您的位置 首页 编程

串口通讯原理和控制程序

以USART1为例的串口初始化本程序调用了STM32自带的固件库,工程中具体的文件见下图:一.GPIO及USART1初始化结构体变量定义GPIO_InitTypeDefGPIO_Ini

  以USART1为例的串口初始化

  本程序调用了STM32自带的固件库,工程中详细的文件见下图:

  一.GPIO及USART1初始化结构体变量界说

  GPIO_InitTypeDefGPIO_InitStructure;USART_InitTypeDefUSART_InitStructure;12

  二.串口时钟及GPIO端口时钟使能

  USART1是挂在APB2总线上的外设。

  TX,RX别离是PA9,PA10端口的复用。

  要运用到端口复用,就要使能端口的时钟,并使能相应外设的时钟。这儿可运用|一起使能这两个时钟。

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA"RCC_APB2Periph_USART1,ENABLE);1

  三.TX,RX装备

  GPIO端口形式的装备包含

  确认需求装备的引脚

  确认端口速度

  确认端口作业形式

  初始化该引脚

  //USART1Tx(PA.09)GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出GPIO_Init(GPIOA,&GPIO_InitStructure);//USART1Rx(PA.10)GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA,&GPIO_InitStructure);12345678910

  四.串口参数初始化

  以下为默许的参数:

  USART_InitStructure.USART_BaudRate=9600;//波特率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_Tx|USART_Mode_Rx;//收发形式USART_Init(USART1,&USART_InitStructure);//初始化USART1USART_Cmd(USART1,ENABLE);//USART1使能12345678

  至此,串口相关的装备已悉数完结,接下来能够写串口程序了。

  五.串口程序

  这儿以STM32与PC通讯为例。

  例1.PC向STM32发送一个字符,STM32再将该字符发回去。

  while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)!=SET);//等候PC的音讯order=USART_ReceiveData(USART1);//读取收到的音讯USART_SendData(USART1,order);//发送音讯while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等候数据发送完1234

  关于两次等候的阐明:

  RXNE和TC都是寄存器USART_SR中的位。当寄存器收到音讯后,RXNE会置1,此刻读取音讯可令其清零。当数据发送完结后,TC会置1,此刻读取状况可令其清零。

  例2.STM32向PC发一个字符串

  字符串内容如下:

  #defineSENDBUF_LEN23unsignedcharorder[SENDBUF_LEN]="01061111/11052121";123

  发送程序如下:

  for(i=0;iSR;//避免首字符丢掉USART_SendData(USART1,order[i]);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);}123456

  关于USART1->SR效果的解说:

  STM32在复位时TC位被置1,因而while句子中的内容直接建立,while句子直接跳出,榜首个字符还没发送完,寄存器就发送了第二个字符,导致榜首个字符被掩盖。处理办法是在发送前先将TC为清零,办法是读USART->SR。由此可知,在发字符串时,一定要先读一次USART->SR,而例1中发一个字符时就不必要了,因为不会有第二个字符来掩盖榜首个字符。

  调试中遇到的问题

  不管PC发什么,STM32都没有回应。调试进程:我把初始化的程序与网上很多程序员写的初始化程序做了比较,没有发现不一样的当地。接着我就置疑USART_SendData(USART1,order)这句代码中的order的数据类型有问题。这个函数的界说如下:

  voidUSART_SendData(USART_TypeDef*USARTx,uint16_tData){/*Checktheparameters*/assert_param(IS_USART_ALL_PERIPH(USARTx));assert_param(IS_USART_DATA(Data));/*TransmitData*/USARTx->DR=(Data&(uint16_t)0x01FF);}123456789

  可知Data的数据类型是uint16_t,我就试着把order的数据类型别离改成了char,uint8_t,uint16_t,但问题仍无法处理(实践上,这个数据类型是没有任何影响的)。

  值得一提的是,之前咱们设置USART1的参数时,一次发送的数据长度设置的是8位USART_InitStructure.USART_WordLength = USART_WordLength_8b;,那么为什么这儿写的却是16位的无符号整型呢?看这句话USARTx->DR = (Data & (uint16_t)0x01FF);,可知理论上发送的内容应该是Data的低9位。但是,因为之前设置了数据长度为8位,故实践发送的内容只要低8位。那么为什么Data会&0x01ff呢?其实这剩余的一位是用于奇偶校验的,当需求装备奇偶校验时,需求将数据长度设置为9位即USART_InitStructure.USART_WordLength = USART_WordLength_9b;,记住,STM32的数据位是包含奇偶校验位的,而PC上调试助手上的数据位仍需设置为8位,这样互发数据才不会出问题。

  回到之前的问题上来——更改完发现仍处理不了问题后,我在程序中加了一个LED闪耀程序,即接纳数据之前LED亮,发送完数据后LED灭,成果发现LED始终是亮的。后改成LED先灭后亮,发现LED始终是灭的。故猜测程序卡死在了这两句程序之间,接着置疑到函数delay_ms()上,接着发现这个由淘宝卖家供给的delay_ms()函数需求先初始化才干运用。(这个延时函数不是简略的for循环延时,比较复杂和精准,初始化函数为delay_init();)因为没有初始化,导致程序死在这条句子上。

  2. STM32发回来的内容与PC发送的内容不一致。调试进程:用示波器观测数据,发现收发的数据都是正确的,但电平宽度不一致,由此得知两者的波特率不一致,进一步核算得知是STM32的串口波特率不对。后发现程序默许的外部高速时钟是8MHz,而我的板子上的晶振是11.0592MHz,故波特率核算错误。处理办法是更改头文件stm32f10x.h中的HSE_VAULE,见下图

  需求阐明的是,博主更改这儿后仍不能接遭到正确音讯,其时我设置的波特率是1200,后来改成9600就正常了。博主没有去深化了解寄存器,只能猜测STM32应该不支持过低的波特率吧。

  3.当STM32向c51发送字符串时,c51接纳不到正确的数据。我用示波器看了下PC向c51发送的波形,又看了下STM32向c51发送的波形,发送数据所用时刻差不多,所以波特率应该是对的,波形因为太长,每个脉冲太窄,欠好调查,看起来也差不多。最终我让STM32把之前发的数据发给PC,发现了问题——那就是之前说到的首字符丢掉问题。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/biancheng/136181.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部