串口最速入门!全网最精简最直接的串口通信教程!

        串口在嵌入式开发时有很多重要,常见的有:数据传输、开发测试、模块数据传递.......,本文将以数据传输和开发测试作为背景进行最精简的介绍,从串口的本质、参数、实现、现象等方面进行讲解。

串口通信

        全双工,通过两根线接收或发送数据,一位一位传输,常见的标准有Uart、RS232(高低电平判定标准不同)。发送的所有数据本质上都是二进制,常用十六进制标识,对应的字母和字符按照不同的编码规则映射,发送发和接收方需要统一编码规则,eg:UTF-8、GB等。
    本质是一种通信协议,可以当作约定俗称的一套规则,只不过制定他的人很权威,所以学习的时候不要畏惧。

Uart

        串口通信的一种,异步通信,不需要统一的共享时钟,但通信需保证通信参数相同

参数

    波特率:一秒钟传输的码元个数,在通常情况下,一个码元代表一位也就是一个电平
    校验位:无检验、奇偶检验
    起始位:默认为高电平,产生一个低电位表示开始传输、一般为一位
    停止位:产生一个高电平,通常为一位
    数据位:传输的数据位的长度,通常为8位,每一个类型位都是独立
    数据帧:封装以上比特位为一个数据帧

步骤

    1.初始化时钟--GPIO、Uart
    2.配置GPIO
    3.配置Uart
    4.使串口中断使能
    5.配置NVIC,有中断必须配置
    6.开启Uart
注意:只需接收二端按照约定好的进行设置,通过调用库函数,只需关心数据位

代码实现:

        初始化是必须的,在接收数据的实现有区别,可以使用轮询和中断二种方式,本文采用的时中断,使用中断的话需要对串口中断和NVIC进行配置,且对串口中断的服务函数进行修改(函数名是固定的,在对应的文件里面找)。

1.初始化

void Serial_Init(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);	//开启USART1的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);					//将PA9引脚初始化为复用推挽输出
	
	/*USART初始化*/
	USART_InitTypeDef USART_InitStructure;					//定义结构体变量
	USART_InitStructure.USART_BaudRate = 9600;				//波特率
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;	//硬件流控制,不需要
	USART_InitStructure.USART_Mode = USART_Mode_Tx;			//模式,选择为发送模式
	USART_InitStructure.USART_Parity = USART_Parity_No;		//奇偶校验,不需要
	USART_InitStructure.USART_StopBits = USART_StopBits_1;	//停止位,选择1位
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;		//字长,选择8位
	USART_Init(USART1, &USART_InitStructure);				//将结构体变量交给USART_Init,配置USART1
	
	/*USART使能*/
	USART_Cmd(USART1, ENABLE);								//使能USART1,串口开始运行
}

2.发送

void Serial_SendByte(uint8_t Byte)
{
	USART_SendData(USART1, Byte);		//将字节数据写入数据寄存器,写入后USART自动生成时序波形
	while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);	//等待发送完成
	/*下次写入数据寄存器会自动清除发送完成标志位,故此循环后,无需清除标志位*/
}

3.接收

void USART1_IRQHandler(void)
{
	if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)		//判断是否是USART1的接收事件触发的中断
	{
		Serial_RxData = USART_ReceiveData(USART1);				//读取数据寄存器,存放在接收的数据变量
		Serial_RxFlag = 1;										//置接收标志位变量为1
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);			//清除USART1的RXNE标志位
																//读取数据寄存器会自动清除此标志位
																//如果已经读取了数据寄存器,也可以不执行此代码
	}
}

注意:

        需要注意的主要是二个寄存器和对应的二个标志位

USART_FLAG_TXE:((Transmit Data Register Empty))

        如果被置位,那么表示发送寄存器为空,即发送完毕,所以没有发送完毕就一直是RESET,while循环等待发送完毕。

USART_IT_RXNE

        表示 接收寄存器非空,如果被置为SET,即有数据,进行对应接收数据的处理。

                (可以从名字对它们的作用进行理解)

有关框图:

实现案例:

        可以编写接收和发送的简单代码,使用串口工具进行调试,观察是否能够正确接收和发送,基本的发送和接收字节能够实现之后,所有的都是基于这个的基础上进行,只不过逻辑和实现手段要复杂一些。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值