目录
- STMF4串口通信使用
- USART的使用流程
- 注意
STMF4串口通信使用
前提回顾:
串口通信概念介绍1
STM32串口通信概念介绍2
针对特定stm32F4板子的串口接线
折叠文本
USART指的是通用同步异步收发器,是STM32中的串行通信设备,STM32F407ZET6一共提供了6个串行接口供用户使用,其中4个为USART,2个为UART。UART指的是通用异步收发器,其实就是在USART的基础上裁掉了同步通信的功能,只保留了异步通信。 可以看到STM32中的USART采用工业标准中常用的NRZ编码进行通信,NRZ码指的是不归零码(Non-Return-Zero),指的是每次传输1bit数据后电平不归零,其实还有一种RZ码,指的是归零码(Return-Zero),指的是每次传输1bit数据后需要电平归零。平时大家一般都是使用串口的异步通信功能,区分同步还是异步其实很简单,就是看是否在通信是对外提供时钟输出。
USART的使用流程
-
打开KEIL5工程,然后把ST公司提供的标准外设库的关于USART的源文件添加到工程中
-
参考并分析ST公司提供的代码例程以及提供的关于USART源文件的开头注释,进行理解
点击查看代码
void USART1_Config(u32 baud)
{USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;//打开了GPIO端口时钟 PA9和PA10RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//打开USART1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//选择GPIO引脚的复用功能GPIO_PinAFConfig(GPIOA, GPIO_PinSource9 , GPIO_AF_USART1);GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);//配置GPIO引脚 注意:复用模式GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;GPIO_Init(GPIOA, &GPIO_InitStructure);//配置串口参数+对串口初始化USART_InitStructure.USART_BaudRate = baud; //波特率USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位USART_InitStructure.USART_Parity = USART_Parity_No; //无校验USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无流控USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式USART_Init(USART1, &USART_InitStructure);//配置NVIC参数 + 对NVIC初始化NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);//选择USART1的中断源,接收到数据则触发中断USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//打开串口USART_Cmd(USART1, ENABLE);
}//利用串口发送一个字符串
void USART1_SendString(const char *str)
{while(*str){while( USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET );USART_SendData(USART1,*str++);}
}//前台程序就是中断服务程序,该程序是不需要手动调用的,当中断触发之后CPU会自动跳转过来执行该函数
void USART1_IRQHandler(void)
{uint8_t data;//判断中断是否发生if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET){ //从USART1中接收一个字节data = USART_ReceiveData(USART1); //一次只能接收一个字节 //把接收到的数据转发出去USART_SendData(USART1,data);}
}int main()
{//1.硬件的初始化USART1_Config(9600);while(1){//把接收到的数据转发出去USART_SendData(USART1,'h');delay_ms(500);}
}
注意
- 如果打算串口发送字符串,由于字符串属于字符序列,所以按照顺序发送字符,由于串口外设的发送数据寄存器是8bit的,所以每次只能发送1个字符,并且只有等上一次字符发送完成,才可以发送下一个字符。
- 可以通过检测串口外设的发送数据寄存器是否为空,来判断待发送的字节是否发送完成,所以需要检测状态标志。
- 配置GPIO引脚 注意:复用模式
- 接收数据用上中断,要用上NVIC->NVIC、EXIT学习
参考李明轩老师第9天的笔记