历史上的今天

今天是:2024年09月04日(星期三)

正在发生

2019年09月04日 | stm32串口通信调试总结

发布者:zeta16 来源: eefocus关键字:stm32  串口通信  调试总结 手机看文章 扫描二维码
随时随地手机看文章

本文分为两部分,即”以USART1为例的串口初始化”和“调试中遇到的问题”


以USART1为例的串口初始化

本程序调用了stm32自带的固件库,工程中具体的文件见下图: 

这里写图片描述

一.GPIO及USART1初始化结构体变量定义


GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;


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

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

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


TX,RX分别对应PA9,PA10

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


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);


三.TX,RX配置 

GPIO端口模式的配置包括


确定需要配置的引脚

确定端口速度

确定端口工作模式

初始化该引脚

    //USART1 Tx(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);

    //USART1 Rx(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);


四.串口参数初始化 

以下为默认的参数:


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);//初始化USART1

USART_Cmd(USART1, ENABLE); //USART1使能


至此,串口相关的配置已全部完成,接下来可以写串口程序了。


五.串口程序 

这里以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);//等待数据发送完


关于两次等待的说明: 

RXNE和TC都是寄存器USART_SR中的位。当寄存器收到消息后,RXNE会置1,此时读取消息可令其清零。当数据发送完成后,TC会置1,此时读取状态可令其清零。


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


字符串内容如下:


#define SENDBUF_LEN 23

unsigned char order[SENDBUF_LEN]="0 1 06 1111/1 1 05 2121";


发送程序如下:


for(i=0;i{   

    USART1->SR;//防止首字符丢失

    USART_SendData(USART1,order[i]);

    while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);

}


关于USART1->SR作用的解释: 

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


调试中遇到的问题

无论PC发什么,stm32都没有回应。调试过程:我把初始化的程序与网上众多程序员写的初始化程序做了比较,没有发现不一样的地方。接着我就怀疑USART_SendData(USART1,order)这句代码中的order的数据类型有问题。这个函数的定义如下:

void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)

{

  /* Check the parameters */

  assert_param(IS_USART_ALL_PERIPH(USARTx));

  assert_param(IS_USART_DATA(Data)); 


  /* Transmit Data */

  USARTx->DR = (Data & (uint16_t)0x01FF);

}


可知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,发现了问题——那就是之前提到的首字符丢失问题。

关键字:stm32  串口通信  调试总结 引用地址: stm32串口通信调试总结

上一篇:RTC--根据年月日计算[星期]的函数
下一篇:STM32 PA6引脚输出低电平不正常的问题

推荐阅读

近日,ADI公布了截止2018年8月份的三季度财报,财报显示公司三季度GAAP准则下的销售额为15.7亿美元,环比增长4%,同比增长10%。ADI公司CEO Vincent Roche在三季度分析师电话会议上表示,工业4.0正在推动工业自动化的创新和投资的发展。对于许多行业而言,数字工厂将带来更高的供应链效率,更高的质量,更大的灵活性和更安全的工作场所,这些都有助于提高...
为了满足消费者希望以智能手机取代车钥匙的需求,汽车行业正在经历着重大变革。随着“手机即钥匙”技术的普及,你不再需要传统的密钥卡,使用手机即可操作“被动门禁/被动启动”(PEPS)系统。低功耗Bluetooth®技术的领先优势在于它是一种可以广泛应用于智能手机的多功能技术。图1:车内的低功耗蓝牙PEPS架构,卫星模块的数量可能会随系统要求变化。 图...
早在2018年4月,由工信部、公安部、交通部三部门联合印发的《智能网联汽车道路测试管理规范(试行)》(以下简称《管理规范》)正式对外发布。《管理规范》对智能网联汽车上路测试的主体、测试驾驶人及测试车辆、测试申请及审核、测试管理、交通违法和事故处理等进行了明确规定。由此开始,全国不少城市在《管理规范》的统一指导下纷纷制定了地方版的管理...
当打工人被繁杂的工作压垮,在日复一日的重复性工作后逐渐躺平;企业也在业务流程复杂性和员工生产力中困顿不堪,企业是时候思考如何实现业务流程端到端的自动化,以及组织和员工的协作关系。有远见的企业正在使用自动化与人工智能来增强核心优势,并与员工和客户建立智能高效的协作关系。 根据 IBM 商业价值研究院的一项研究显示,到 2022年,人工...

史海拾趣

问答坊 | AI 解惑

您是否也曾有过想在论坛中发问,却不知如何开口的困惑?

本人计算机专业本科,去年毕业,现在在一家生产(确切的定义应该是“研发”,因为地质仪器需求量比较少,我们更多的精力投放在手头的科研项目上)地质勘探仪器的公司工作,公司的总工曾是文革后中科院电子所第一届研究生,我就在他的手下学习。大学 ...…

查看全部问答∨

模拟的今年找工作是啥情况啊

模拟的今年找工作是啥情况啊…

查看全部问答∨

转:看看开关电源厂家是如何骗人的

把主机拆开除灰尘,想想顺便也把电源也除除灰,拆开一看,感觉哪个PFC有点不对,顺便拆开看看,由于这台电脑是第一次配的,是一款杂牌电源,当时那JS说230块机箱电源随便选,觉得有问题,不过当时没经验,也就没管那么多~ 凡来坛里的一看就知道, ...…

查看全部问答∨

在控制面板中添加硬件错误!

我在“控制面板\\添加硬件"中按照向导安装到最后,点击完成的哪个界面 出现如下提示信息: 安装设备时出现了一个错误 名称已用作服务或服务显示名 各位大哥指点一下,可能是那里错误!说出解决的方法,越详细越好,哈哈 先谢谢各位捧场的大 ...…

查看全部问答∨

STM32F103RC的USB与PC连不通

STM32F103RC的USB与PC连不通芯片可以认到,D+加了1.5k上拉,D+,D-匹配电阻22ohm,程序用的是最新STM32_USB-FS-Device_Lib_V3.3.0 晶振用的是6M的,程序里面时钟配置都改了,usb时钟是48M 急求高人帮助啊~~…

查看全部问答∨

MSP-EXP430FR5739实验板套件团购

因为本来对MSP430暂时还是在数据上面的了解,并没有真正的深入学习过!所以希望申请个实验板学习!   再次感谢论坛提供这么好的机会!…

查看全部问答∨

Quartus 并转串

代码如下:   always @(negedge clk or negedge rst_n)   begin     if(!rst_n)       begin         address      <=  1 ...…

查看全部问答∨

Beaglebone学习之5-外围电路设计完成(含原理图和PCB)

最近公司事情太忙,迟到这么久的设计终于完成了,不然真的辜负EEWORLD和大家的信任了(板子和奖金都到手了),今天已经把板子发出去做,周末应该就能回来了,到时再分享硬件调试和软件开发细节 另外板子做了10块,有兴趣的我可以赠送几块出来,还有 ...…

查看全部问答∨

使用Ultra Librarian转换成altium designer的文件出问题

我在TI的28335DSP网页下载了bxl的封装文件,然后使用Ultra Librarian转换成altium designer的文件出问题,由于28335DSP原理图库是分部分的,但转换后只能出来第一部分,怎么解决这个问题啊?谢谢。…

查看全部问答∨

请问大侠们,IAR怎么样在一个工程中建立多个文件

怎样在IAR中建立一个project含有多个file? 不同file之间的变量信息通过什么传输?全局变量为什么不行? (像下图一样,一个工程中包含多个文件)…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved