当前位置:首页 > 芯闻号 > 充电吧
[导读]先声明一点,我自己不是高手,也不是大神,只是积累了一点点,想分享一下罢了!还记得那会我在初学51单片机时,当得知P89V51系列单片机支持在线仿真、跟踪代码时,那是一个兴奋啊,无论如何都要弄一个来玩玩

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

还记得那会我在初学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了!

这些只是个人调试和理解,如若有误,请谅解!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

单片机是一种嵌入式系统,它是一块集成电路芯片,内部包含了处理器、存储器和输入输出接口等功能。

关键字: 单片机 编写程序 嵌入式

在现代电子技术的快速发展中,单片机以其高度的集成性、稳定性和可靠性,在工业自动化、智能家居、医疗设备、航空航天等诸多领域得到了广泛应用。S32单片机,作为其中的佼佼者,其引脚功能丰富多样,是实现与外部设备通信、控制、数据...

关键字: s32单片机引脚 单片机

在微控制器领域,MSP430与STM32无疑是两颗璀璨的明星。它们各自凭借其独特的技术特点和广泛的应用领域,在市场上占据了重要的位置。本文将深入解析MSP430与STM32之间的区别,探讨它们在不同应用场景下的优势和局限...

关键字: MSP430 STM32 单片机

该系列产品有助于嵌入式设计人员在更广泛的系统中轻松实现USB功能

关键字: 单片机 嵌入式设计 USB

单片机编程语言是程序员与微控制器进行交流的桥梁,它们构成了单片机系统的软件开发基石,决定着如何有效、高效地控制和管理单片机的各项资源。随着微控制器技术的不断发展,针对不同应用场景的需求,形成了丰富多样的编程语言体系。本文...

关键字: 单片机 微控制器

单片机,全称为“单片微型计算机”或“微控制器”(Microcontroller Unit,简称MCU),是一种高度集成化的电子器件,它是现代科技领域的关键组件,尤其在自动化控制、物联网、消费电子、汽车电子、工业控制等领域...

关键字: 单片机 MCU

STM32是由意法半导体公司(STMicroelectronics)推出的基于ARM Cortex-M内核的32位微控制器系列,以其高性能、低功耗、丰富的外设接口和强大的生态系统深受广大嵌入式开发者喜爱。本文将详细介绍S...

关键字: STM32 单片机

在当前的科技浪潮中,单片机作为嵌入式系统的重要组成部分,正以其强大的功能和广泛的应用领域受到越来越多行业的青睐。在众多单片机中,W79E2051以其卓越的性能和稳定的工作特性,成为市场上的明星产品。本文将深入探讨W79E...

关键字: 单片机 w79e2051单片机

单片机,又称为微控制器或微处理器,是现代电子设备中的核心部件之一。它集成了中央处理器、存储器、输入输出接口等电路,通过外部信号引脚与外部设备进行通信,实现对设备的控制和管理。本文将详细介绍单片机的外部信号引脚名称及其功能...

关键字: 单片机 微控制器 中央处理器

随着科技的飞速发展,单片机和嵌入式系统在现代电子设备中的应用越来越广泛。它们不仅提高了设备的智能化水平,还推动了各行各业的创新与发展。在单片机和嵌入式系统的开发中,编程语言的选择至关重要。本文将深入探讨单片机和嵌入式系统...

关键字: 单片机 嵌入式系统 电子设备
关闭
关闭