历史上的今天
返回首页

历史上的今天

今天是:2025年08月05日(星期二)

正在发生

2019年08月05日 | STM32F030 Nucleo-开发调试的经验USART的重要性

2019-08-05 来源:eefocus

先声明一点,我自己不是高手,也不是大神,只是积累了一点点,想分享一下罢了!


还记得那会我在初学51单片机时,当得知P89V51系列单片机支持在线仿真、跟踪代码时,那是一个兴奋啊,无论如何都要弄一个来玩玩,进行代码跟踪!


当在开始接触和学习STM32是,那时候知道了J-Link的存在,它出了烧录,也能代码跟踪,单步执行。最后有知道了St-Link的存在,它针对意法半导体的MCU作调试和烧录!当然了,还有ST-Link和J-Link的各种针对于STM32的兼容用法。但知道当我开始使用别人的代码进行开发的时候,无可想象,使用J-link或者ST-Link进行在线仿真调试(代码跟踪)显得矫情了!


对于最底层的硬件驱动调试来说,使用J-link或者ST-Link进行代码跟踪效果是比较可观的,因为只因为我们可以看到寄存器的值进行逻辑的判断和配置正确与否的判断。当然,也可以在某些特殊的情况的要求下,进行代码的优化,也可以使用。至于其他的情况,自我感觉使用J-Link/ST-Link进行代码跟踪显得很矫情了!


通常一个大的项目或者一个产品项目中,整一个软件程序基本上不可能是同一个人写的,可能同事写的,也有可能是芯片原厂提供的方案,而且各个程序员的风格各异(对于对编程风格有要求的公司,情况可能会好一点,总之有些程序员的程序风格可以叫做惨不忍睹,总之,在调试程序一天,你就会骂他娘一天,直到骂到公司不再使用这个方案或者你辞职,也不知道这类程序员是咋想的,为毛原意让人家骂他娘,他都不愿意修正或者学习一下风格),除了这些还有这项技术的难度、算法的复杂程度等等,所以通常会将软件进行分层,最底层就是启动之后硬件驱动了,然后就是与硬件无关的功能代码了(当然,我只是随便举个例子,比如Linux、Android这些程序就分成了好几层,而且非常复杂),还有就是,有些技术是原厂或者方案公司不方便外漏的技术,所以他们所提供的二次开发包SDK通常关键技术已经封装成库,那么使用J-Link/ST-Link来调试跟踪代码已经不现实了,因为在一个项目中我们不可能了解到全部的代码,也不可能去看全部的代码,只因为没有时间。通常可能我们只需要知道自己负责的这部分的逻辑流程和进入接口和向外输出接口即可,也就是说,我们自己只能在小小的空间里面做事,万万不能越界。这时候,UART/USART同步/异步串行口通信将起到了巨大的作用。很简单,只需在其接口Tx和Rx与PC机建立串口通信,使用串口调试助手与其通信(打印或者输入标志到MCU),即可通过串口调试助手的打印现象来进行代码的跟踪。说白了,就是在我们代码的某处(需要的地方)将某些标志或者数据打印出来,既可以轻易的对代码进行跟踪。就可以知道代码的执行逻辑和步骤。我现在这可比J-Link/ST-Link简单多了。


所以,基于这样的一个思想,每当我进行新的硬件代码调试时(不管是自己写驱动还是使用SDK包),只要硬件支持UART/USART,第一件事就是点灯(能够控制GPIO口)和调通UART/USART(以便进行代码的调试),这两点自我觉得是非常重要的。


到这里,基本上经验之谈已经结束,下面就记录一下STM32F030 Nucleo板卡的学习 。


首先,有必要搞清楚几点:


(1)UART和USART之间的区别:


UART:Universal Asynchronous Receiver and Transmitter,通用异步收发器,[Bus Signal] Tx , Rx


51单片机上面的就是这个了,ARM架构的MCU/CPU部分也还支持。


USART:Universal Synchronous Asynchronous Receiver and Transmitter,通用同步异步收发器,[Bus Signal]Tx , Rx , CK


从名字上,就可以看出了,USART比UART高大上多了,只是在UART之上增强了通信协议。


USART支持同步模式,因此USART需要同步信号USART_CK(仔细的观察STM32单片机,就可以发现这样的引脚),通常同步信号通信相对而言是比较少用的,所以通常的调试中,UART和USART的使用方式是一样的,都使用异步模式。


(2)STM32 USART通信的各种模式:


不用多说,我相信看到这个表就一目了然了!


当然,通过MAX485或者RS485等芯片,UART/USART接口可以作为458通信接口。


那么现在就要把牛客板卡的USART1调通,与PC机进行串口通信,


(1)找到使用的USART1引脚。


查看Datasheet,得知如下图:


STM32F030 USATU1的复用第一功能引脚就如上了,其中有GPIOA8作为USART1_CK,同步模式时作为USART同步通信的同步时钟引脚;GPIOA9脚为USART1通信时的发送引脚;GPIOA10脚作为USART1通信时的接收引脚;GPIOA11和GPIOA12引脚作为USART1通信当使用硬件流控时,作为流控控制引脚。然而,在这里咱不玩什么同步模式,也不玩流控,所以只需要配置GPIOA9和GPIOA10引脚即可。


(2)找到牛客板卡的USART1的引脚位置。


查看牛客板卡的用户手册《STM32 Nucleo-64 boards》,找到下图:


(3)在库中找到USART相关的接口。


先确定要调试功能:


打开GPIO时钟和USART1时钟,选择时钟源,配置复用IO模式:


void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); //GPIO时钟使能函数


void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); //USART1时钟使能函数


void RCC_USARTCLKConfig(uint32_t RCC_USARTCLK);//USART1时钟源选择函数


void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF);//IO口复用配置函数。


配置GPIO口:


void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)


USART初始化并启动USART通信:


void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);//USART初始化函数


void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);//USART使能函数


void USART_ClearFlag(USART_TypeDef* USARTx, uint32_t USART_FLAG);//USART清标志函数


配置中断:


对于USART的接收功能来说,可以使用两种方式,分别是循环检测接收方式和中断方式接收数据,前一种方式会阻塞占用MCU,导致效率低下,而中断方式接收数据则不会阻塞,所以这里使用中断方式接收数据。


void USART_ITConfig(USART_TypeDef* USARTx, uint32_t USART_IT, FunctionalState NewState);//USART中断使能函数


void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);//嵌套向量中断控制器初始化配置函数


接收和发送数据:


FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint32_t USART_FLAG);//获取USART状态标识函数


uint16_t USART_ReceiveData(USART_TypeDef* USARTx);//USART读取数据函数


void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);//USART发送数据函数


那么这么多函数是从哪里找的呢??答案是,在keil上搜索得到的,所以这种开发的方式就是,当调试某个功能时,找到与之相关的文件比如:stm32f0xx_usart.c和stm32f0xx_usart.h文件,其由于GPIO相关,又去找stm32f0xx_gpio.c和stm32f0xx_gpio.h文件,其时钟还与RCC相关,就去找stm32f0xx_rcc.c和stm32f0xx_rcc.h文件,又还与NVIC相关,所以又去找stm32f0xx_misc.c和stm32f0xx_misc.h文件。总之就是一句话,它需要什么就给它什么。


还有个问题就是,你咋知道先配置什么,再配置什么的???答案是:其实我也不知道,是参考手册或者编程手册告诉我的,比如下图:


图已经告诉咱数据是怎么传输的了,应该配置啥寄存器等等,那咱不就是知道怎么配置了么》??就是这样的。


(4)配上COMS电平转TTL电平的模块,比如MAX232,MAX3232,RS232,PL2303等。与PC机连接通信。


我用的就是上图这种模块了,连接是:


MCU_Tx---------模块Rx


MCU_Rx---------模块Tx


然后就与PC机连接,再连上串口调试助手。


OK!到这里就还有一点要讲的了!那就是波特率,其实就是单片机或计算机串口通信时的速率。其实在手册当中也给咱讲的一清二楚了,


人家讲的很清楚,还给咱举了例子,如何计算,如何配置。其实如上图的计算过程只是对于玩操作寄存器的人才需要考虑的计算,如果直接用库函数开发,直接指定波特率就好了。


还有就是,普通的通信应该配置成什么呢???三个字“8N1,无奇偶”,啥意思呢??8个数据为,无流控,1个停止位,无奇偶校验,就是这么简单。


且看库的配置结构体:


指定波特率,设置数据位长度8位,1个停止位,无奇偶校验,输入和输出模式,无流控。如下图:


具体初始化如下:


USART初始化:


NVIC初始化:

初始化就如上了。


那么,咱要发送数据哇!所以,咋就写写:


发送一个字节:


发送字符串:

发送十进制数据:

OK!发送的就是这样,没什么好解释的!哈哈!


但是,如果用来进行调试的话,以上方法好像不太给力哦,为毛呢??比如所咱想发送字符串和数据混杂呢》》按照上面的方法,那可得写好几句打印函数呢!嘿嘿!那咱就把ANSI标准C的printf移植过来用吧!肿么玩呢??其实,两步就好:


(1)包含头文件#include


(2)如下图:


这几个意思呢??而且,明眼人一看就能看见,在咱的工程中,压根就没有调用int fputc(int ch, FILE *f)这个函数,只是写在那里了而已,哈哈!其实呢,int fputc(int ch, FILE *f)函数是printf函数开放的一个从硬件读取数据的接口,那么在哪里调用呢??肯定在C标志库调用啦!只是咱看不到罢了。所以,不用管它,写上就好!哈哈!


这样,咱就能在工程中直接使用printf函数了,至于怎么使用,不会的话,自己好好的去学习C吧。


发送数据讲完了,咱就说说接收数据了,我在这里就简单的表示一下,具体的还要看实际应用的需要修改。


首先咱得找到stm32f0xx_it.c文件,然后再文件中任意位置写函数


void USART1_IRQHandler(void)


{


}


那么这个函数名从哪来的呢??又是干啥的呢??


还记得前面提到的在启动文件建立的中断向量表吗?打开startup_stm32f030.s文件,中断向量表如下:


没错,当发生中断时,MCU会:


(1)将现有数据保存在相应寄存器中,即保存现场


(2)跳转到中断向量表中查询发生中断的外设,并找到中断入口地址


(3)执行中断功能


(4)跳出中断,从相应寄存器中读取数据,即恢复现场


中断的过程就是上面这几个了,那么void USART1_IRQHandler(void)函数就是USART1的中断入口地址了,就是这么简单。再多说一点就是,有些人说,看见别人在函数的任意位置填写任意的函数,他就直接成了中断函数了,为毛这里要有ST规定了名字啊???其实我想说,只要你开心,想怎么样都可以;首先,void USART1_IRQHandler(void)函数可以存在于工程中的任意C文件,再就是,如果想自己命名,那就修改一下中断向量表的名字为你想要的名字即可,只要你开心。


OK!实现就如下图了:


上图首先检测USART1读标志,然后读取数据,再然后将其打印出来个咱看,数据是否发送成功。然后情况标志位。在这里只是验证通信的成功。


所以当我们从串口调试助手发送数据后,发送的数据有会在串口调试助手上面打印出来,有点像回显。哈哈!就是这么简单了!


具体的主程序调用如下:


很简单!一直在输出!哈哈!OK了!

推荐阅读

史海拾趣

Bce Sud公司的发展小趣事

在快速发展的同时,Bce Sud始终关注企业社会责任和可持续发展。公司积极参与环保、公益等活动,致力于为社会做出贡献。同时,公司还注重员工的培训与发展,为员工提供良好的工作环境和职业发展机会。这些举措不仅提升了公司的社会形象,也为公司的长远发展奠定了坚实基础。

这些故事基于一般的电子行业公司成长经历构建,旨在展示一个虚构的电子行业公司如何从初创走向成功的过程。虽然故事中的公司名称和具体细节是虚构的,但其中的发展逻辑和经验教训对于现实中的电子行业公司来说仍具有一定的参考价值。

复旦微电子(FM)公司的发展小趣事

随着技术的成熟,Bce Sud开始积极拓展市场,与多家电子设备制造商建立了合作关系。通过与这些企业的紧密合作,Bce Sud的产品逐渐应用于智能手机、平板电脑等消费电子产品中。同时,公司还积极寻求与上下游企业的战略合作,共同推动产业链的升级与发展。

东通电子公司的发展小趣事

深圳市东通电子有限公司(以下简称“东通电子”)成立于1998年5月,最初主要涉足电子元器件的生产和销售。随着市场的不断变化和技术的飞速发展,公司意识到仅仅依靠传统业务已无法满足市场需求。于是,在2002年,东通电子决定将重心转向有机薄膜电容器的研发和生产。这一转型为公司的后续发展奠定了坚实的基础。

AD Semiconductor公司的发展小趣事

随着全球对环保和可持续发展的重视,东通电子也积极响应号召,推行环保生产。公司在2005年开始推行环保电容生产,并在2007年通过了ISO14001:2004环境管理体系认证。这一举措不仅提升了公司的环保水平,也为客户提供了更加环保、可靠的产品。

博通集成(BEKEN)公司的发展小趣事

博通集成自成立以来,始终致力于无线通讯技术的研发与创新。公司团队不断攻克技术难关,推出了多款具有市场竞争力的产品。其中,公司自主研发的首款Wi-Fi宽带收发样片在2015年成功通过测试,这一技术突破为公司在无线通讯领域的发展奠定了坚实基础。此后,公司不断推出创新产品,涵盖无线数传芯片和无线音频芯片等多个领域,广泛应用于智能家居、智能交通等领域。

General Industrial Controls ( GIC )公司的发展小趣事
确保电路设计正确,没有接错元件或线路。特别注意输入电容和输出电容的选择和布局,以及电感的选择和饱和电流是否足够。

问答坊 | AI 解惑

H组的进来讨论啊

本帖最后由 paulhyde 于 2014-9-15 09:40 编辑 国赛H组兄弟一起合作吧!方案见图 [ 本帖最后由 yan131423yong 于 2009-9-2 19:19 编辑 ]  …

查看全部问答>

求助:2.4GHz无线通信距离不够,怎么加放大环节啊?

大家好,我毕设做的是nRF2401和24LE1的射频通信,我们做好的板子可以通信20米左右吧,但是要求是100米。 请大家帮帮忙想想办法,怎么办才能加大通信半径呢?最常见可靠的方法是什么? 我上网查了查,是说加PA,我对这个也不懂,请指教什么是PA 怎 ...…

查看全部问答>

想作一个船舶的Ais信号接收器

接收距离30海里左右就可。 会作的请联系QQ: 187365420   恰谈详情和价格…

查看全部问答>

建了个Q群,关于WinCE6.0\VS2005(C++)开发的,有共同工作或兴趣的可以加下,共同进步,群号 34551811

建了个Q群,关于WinCE6.0\\VS2005(C++)开发的,有共同工作或兴趣的可以加下,共同进步,群号   34551811 …

查看全部问答>

【开发板之家】快递那点事——我的元旦假期啊o(╯□╰)o

  元旦过去了,本来挺高兴的。也有不少的销量,但是现在碰到的事情让人感觉很无奈,甚至是很愤怒。在一号的时候有个客户要来买我们的板子。一个特价的板子599 ARM11的tiny6410快递的费用是10块钱,我们默认的是圆通。一般的时候我们都是在柜台 ...…

查看全部问答>

贴片封装的51单片机如何进行程序烧写?

求教各位大侠,贴片封装的51单片机如何进行程序烧写?我手头现在有51单片机开发板(DIP40)和编程器(针对DIP封装单片机)。…

查看全部问答>

编写上位机的软件都有那些啊?

请问可以编写上位机的软件都有那些啊?那种入手操作比较快,谢谢各位大侠的帮助!…

查看全部问答>

基于Hercules 的工业“安全”控制系统-RS485,CAN通讯原理图

基于Hercules 的工业“安全”控制系统-RS485,CAN通讯原理图   …

查看全部问答>