这篇文章主要为大家展示了“STM32串口的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“STM32串口的示例分析”这篇文章吧。
USART是通用异步收发传输器(UniversalAsynchronousReceiver/Transmitter),通常称作UART,是一种异步收发传输器,是设备间进行异步通信的关键模块。UART负责处理数据总线和串行口之间的串/并、并/串转换,并规定了帧格式;通信双方只要采用相同的帧格式和波特率,就能在未共享时钟信号的情况下,仅用两根信号线(Rx和Tx)就可以完成通信过程,因此也称为异步串行通信。
全双工异步通信。
小数波特率发生器系统,提供精确的波特率。
可配置的16倍过采样或8倍过采样,因而为速度容差与时钟容差的灵活配置提供了可能。
可编程的数据字长度(8位或者9位);
可配置的停止位(支持1或者2位停止位);
可配置的使用DMA多缓冲器通信。
单独的发送器和接收器使能位。
检测标志:① 接受缓冲器 ②发送缓冲器空 ③传输结束标志
多个带标志的中断源。触发中断。
其他:校验控制,四个错误检测标志。
通信结构
1.数据包
串口通讯的数据包由发送设备通过自身的TXD接口传输到接收设备得RXD接口,在协议层中规定了数据包的内容,具体包括起始位、主体数据(8位或9位)、校验位以及停止位,通讯的双方必须将数据包的格式约定一致才能正常收发数据。
2.波特率
由于异步通信中没有时钟信号,所以接收双方要约定好波特率,即每秒传输的码元个数,以便对信号进行解码,常见的波特率有4800、9600、115200等。STM32中波特率的设置通过串口初始化结构体来实现。
3.起始和停止信号
数据包的首尾分别是起始位和停止位,数据包的起始信号由一个逻辑0的数据位表示,停止位信号可由0.5、1、1.5、2个逻辑1的数据位表示,双方需约定一致。STM32中起始和停止信号的设置也是通过串口初始化结构体来实现。
4.有效数据
有效数据规定了主题数据的长度,一般为8或9位,其在STM32中也是通过串口初始化结构体来实现的。
5.数据校验
在有效数据之后,有一个可选的数据校验位。由于数据通信相对更容易受到外部干扰导致传输数据出现偏差,可以在传输过程加上校验位来解决这个问题。校验方法有奇校验(odd)、偶校验(even)、0 校验(space)、1 校验(mark)以及无(noparity)。这些也都可以在串口初始化结构体中实现的。
如果时钟时84M
USARTDIV = 84000000/(115200*16) = 45.572
那么得到:
DIV_Fraction = 16*0.572 = 0x09;
DIV_Mantissa = 45 = 0x2D;
根据STM32F207数据手册,STM32F207一共6个串口
配置中断优先级。
/* Enable the USARTx Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);
打开串口与相应的GPIO引脚,配置好相应串口信息与GPIO引脚的工作模式。
/* Enable GPIO clock */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); /* Enable UART1 clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); /* Connect PXx to USARTx_Tx*/ GPIO_PinAFConfig(GPIOA, 9, GPIO_AF_USART1); /* Connect PXx to USARTx_Rx*/ GPIO_PinAFConfig(GPIOA, 10, GPIO_AF_USART1); /* Configure USART Tx as alternate function */ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure USART Rx as alternate function */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_Init(GPIOA, &GPIO_InitStructure);
配置USART1。
USART_InitStructure.USART_BaudRate = 115200;//配置波特率 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 configuration */ USART_Init(USART1, &USART_InitStructure);// 完成串口的初始化配置
使能中断配置。
USART_ITConfig(USART1, USART_IT_TC, ENABLE); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE)
我们配置了发送传输完成中断和接收数据寄存器非空中断。我们可以配置很多类型中断,在ST提供的标准库函数中看到。
/** * @brief Enables or disables the specified USART interrupts. * @param USARTx: where x can be 1, 2, 3, 4, 5 or 6 to select the USART or * UART peripheral. * @param USART_IT: specifies the USART interrupt sources to be enabled or disabled. * This parameter can be one of the following values: * @arg USART_IT_CTS: CTS change interrupt * @arg USART_IT_LBD: LIN Break detection interrupt * @arg USART_IT_TXE: Transmit Data Register empty interrupt * @arg USART_IT_TC: Transmission complete interrupt * @arg USART_IT_RXNE: Receive Data register not empty interrupt * @arg USART_IT_IDLE: Idle line detection interrupt * @arg USART_IT_PE: Parity Error interrupt * @arg USART_IT_ERR: Error interrupt(Frame error, noise error, overrun error) * @param NewState: new state of the specified USARTx interrupts. * This parameter can be: ENABLE or DISABLE. * @retval None */
最后使能串口。
/* Enable USART */ USART_Cmd(USART1, ENABLE);
main主函数,功能是LCD显示串口接收的10个字符(如果不是ascii码则不显示),串口倒序返回接收到的10个字节。
int main(void) { /*省略初始化部分代码*/ while (1) { if(LCD_refresh_flg){ LCD_refresh_flg = 0; LCD_ShowString(0,16,receive_data); receive_num--; USART_SendData(USART1, receive_data[receive_num--]); send_flg = 1; } } }
因为使能了中断,我们还需要编写中断函数。
void USART1_IRQHandler(void) { if(USART_GetFlagStatus(USART1, USART_FLAG_TC)) { if(send_flg == 1){ if(receive_num==0){ USART_SendData(USART1, receive_data[receive_num]); send_flg = 0; receive_flg = 1; }else{ USART_SendData(USART1, receive_data[receive_num--]); } } USART_ClearFlag(USART1, USART_FLAG_TC); } if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE)) { if((receive_flg)&&(send_flg == 0)){ receive_data[receive_num++] = USART_ReceiveData(USART1); if(receive_num==10){ receive_flg = 0; LCD_refresh_flg = 1; } } USART_ClearFlag(USART1, USART_FLAG_RXNE); } }
下载验证
LCD显示屏可以显示接收的10个字符,且PC以100ms为间隔发送数据,发送977包收到977包回复,测试demo就够健壮,没有出现丢包。
以上是“STM32串口的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。