串口参数及时序
本节展示串口收发的功能,通常使用波特率为9600,8位数据位,即无校验位,停止位长度为1的时序。
USART简介
·USART (Universal Synchronous/Asynchronous Receiver/Transmitter)通用同步/异步收发器
·USART是STM32内部集成的硬件外设,可根据数据寄存器的一个字节数据自动生成数据帧时序,从TX引脚发送出去,也可自动接收RX引脚的数据帧时序,拼接为一个字节数据,存放在数据寄存器里
·自带波特率发生器,最高达4.5Mbits/s
·可配置数据位长度(8/9)、停止位长度(0.5/1/1.5/2)
·可选校验位(无校验/奇校验/偶校验)
·支持同步模式、硬件流控制、DMA、智能卡、IrDA、LIN
·STM32F103C8T6 USART资源:USART1、USART2、USART3(USART1是APB2总线的设备,剩下的是APB1的设备)
配置USART基本结构
初始化模板
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//把PA9配置为复用推挽输出,供USART的TX使用
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);
//初始化PA10引脚
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//可选浮空或上拉输入
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
//初始化USART 9600波特率 无流控 无校验 8位字长 1位停止位 选择发送和接收模式
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate=9600;//波特率
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//硬件流控制
USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;//串口模式
USART_InitStructure.USART_Parity=USART_Parity_No;//校验位选择无校验
USART_InitStructure.USART_StopBits=USART_StopBits_1;//停止位长度
USART_InitStructure.USART_WordLength=USART_WordLength_8b;//字长选择8位
USART_Init(USART1,&USART_InitStructure);
//开启RXNE标志位到NVIC的输出
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
//优先级分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//中断通道
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(USART1,ENABLE);
查看引脚定义表
可见USART1的TX和RX分别对应PA9和PA10引脚,初始化PA9时要配置成复用推挽输出模式。
关于USART的结构体参数USART_Mode,需要接收或发送的哪一个功能就选哪一个,两个都要就用“|”操作或起来。
接收一个数据
方法一:
模板里使用中断触发来接收数据,首先开启RXNE到中断的通道,用USART_ITConfig函数,再配置NVIC优先级分组等参数;关于RXNE标志位
有数据时会触发中断,中断函数从启动文件里找
中断函数示例:
void USART1_IRQHandler(void)
{
if(USART_GetFlagStatus(USART1,USART_IT_RXNE)==SET)
{
//。。。要进行的操作
USART_ClearITPendingBit(USART1,USART_IT_RXNE);//若读出收到的数据,不用手动清零
}
}
读出数据用函数USART_ReceiveData,手册里说读DR硬件会自动清零标志位。
方法二:
在主函数里不断判断RXNE标志位,如果置1了,就说明收到数据了,那再调用ReceiveData,读取DR寄存器就行了。
发送一个数据
发送数据用函数USART_SendData,发送完判断一下TXE标志位即可
关于TXE标志位
为1时标志可以继续发了,和RXNE对应,为1时表示接收到了数据,可以读了,以免继续发数据被覆盖了。
发送数据代码示例
//发送一个数据
void Serial_SendByte(uint8_t Byte)
{
USART_SendData(USART1,Byte);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//TXE发送数据寄存器空标志位,为1即空
//硬件会将标志位清零
}
见手册描述,我们对DR进行读操作,硬件会将标志位清零,所以这里不需要我们像收数据一样手动清除标志位。