历史上的今天
返回首页

历史上的今天

今天是:2024年08月28日(星期三)

正在发生

2019年08月28日 | STM32 HAL库学习(二) 串口收发数据

2019-08-28 来源:eefocus

上一篇实现了LED的点亮和串口轮询发送数据,这章想着实现串口接收数据,不得不说,在开始使用STM32的外设才对HAL库的框架有更准确的理解。之前一直不懂HAL库的优越性在哪,这次对它的msp层有了一定认识。


简单来说,HAL库有一个特点就是对于许多外设的初始化以及功能操作,都提供有一个weak版本的函数,例如串口的HAL_UART_MspInit()函数和HAL_UART_MspDeInit()函数等,这些都可以供用户在需要时在stm32f0xx_hal_msp.c中进行重写实现功能。


用串口初始化来举例子,用Cube配置UART1使能并生成代码后可以看到有三个关键函数:


1、void MX_USART1_UART_Init(void)


这个函数是Cube配置完成后自动帮我们生成的,存在于用户文件usart.c中(如果Cube中有配置选项生成用户.c文件,否则在main函数中)。里面主要是将USART的结构体初始化成USART1以及我们设置好的参数),并且在最后有一个语句:if (HAL_UART_Init(&huart1) != HAL_OK)通过这个来调用HAL_UART_Init函数。


2、HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)


这个函数在HAL库文件stm32f0xx_hal_uart.c中,在上一个函数 MX_USART1_UART_Init(void)中有被调用,这个函数将初始化UART1,使能UART1,而重点是里面有调用一个函数HAL_UART_MspInit(huart)


3、__weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)


这个函数也在HAL库文件stm32f0xx_hal_uart.c中,它是weak修饰的,也就是可以重写。我们发现在Cube生成的用户文件usart.c文件中有对这个函数进行重写,主要实现对UART1的TX、RX引脚的IO口配置,以及开启串口中断等设置。


由此,HAL库的串口外设初始化操作就清晰了,也就是说如果我们使用Cube生成代码,要完成对串口的初始化,就要自行对串口的结构体参数进行配置,并对HAL_UART_MspInit函数进行重写。到这里,也能看书HAL库的优越性,用户只需在msp.c中对要实现的函数进行重写,调用相关函数既可实现。


 


串口初始化完成后,下一步就是实现串口的收发数据,轮询发送很简单,上一篇就实现了。这里主要研究下串口的中断接收,和中断接收有关的函数有下面几个:


1、HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)


函数有是三个参数,分别是串口结构体,要传输的数据指针以及待传输数据的大小,这其实是对中断接收的一个配置函数,指定当接收到Size大小的字节后就产生一次中断进入中断处理。对比以前的库函数的串口接收协议,可以将这里的Size设置为1,也就是每次接收一个字节就产生一次中断,并将数据存储到pData指向的地址中。这就类似于库函数中的每次中断将数据赋值给临时变量res。需要注意的是,这个函数调用一次只适用于一次中断,如果要连续接收数据的话应该在重写函数中调用它。


2、USART1_IRQHandler(void)、HAL_UART_IRQHandler(&huart1)


第一个是在it.c中的通用的硬件中断入口函数,其中在里面调用了HAL_UART_IRQHandler(&huart1),也就进入了UART1的中断处理,HAL_UART_IRQHandler函数在stm32f0xx_hal_uart.c文件中,主要进行中断标志的判定,当判定接收到数据时,调用UART_Receive_IT(huart)函数。


3、HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)


这个函数也在stm32f0xx_hal_uart.c中,这才是真正的处理数据的函数,读取接收寄存器,将数据赋值给结构体huart的pRxBuffer并清除中断标志,而在里面还调用了一个函数HAL_UART_RxCpltCallback(huart);


4、__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)


这个是用户真正可以进行重写实现自己所需功能的函数,在msp.c中将其重写。前面我们设置了参数使得每接收一个字节就产生中断,于是可以重写这个函数,在里面将每次接收到的数据存放在自己定义的UART1RXBuffer中。另外,上面有提到配置中断参数的函数 HAL_UART_Receive_IT()每次调用仅适用于一次中断,如果要实现连续采用中断接收数据,也要这个函数中调用HAL_UART_Receive_IT()。因为这个回调函数是每次中断发生都会调用,也就相当于每次发生中断处理完数据后又将中断打开,从而实现连续中断接收数据。


 


总结下整个逻辑就是:


1、初始化UART1


2、调用HAL_UART_Receive_IT(&huart1,&RxData,1)


3、在msp.c中重写HAL_UART_RxCpltCallback


void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

{

UART1RxBuffer[receive_count++] = RxData;

HAL_UART_Transmit(huart,&RxData,1,10);

HAL_UART_Receive_IT(huart,&RxData,1);

}

 


实验时如何保证HAL库的完整性是一个值得重视的问题。 


推荐阅读

史海拾趣

Good-Ark公司的发展小趣事
声控报警电路应安装在需要监控的区域附近,并确保声音传感器能够充分接收环境声音。同时,应避免将传感器安装在有强风、机械振动等干扰源的地方。
Dow-Key Microwave Corporation公司的发展小趣事

1945年,第二次世界大战结束后不久,Dow-Key Microwave Corporation在美国成立。公司创始人凭借对射频和微波技术的深刻理解和市场需求的敏锐洞察,决定专注于射频微波开关的制造。在初创阶段,公司面临资金短缺、技术挑战和市场接受度不高等问题。然而,创始人及其团队凭借不懈的努力和创新的精神,逐渐克服了这些困难,为公司的发展奠定了坚实的基础。

FerriShield公司的发展小趣事

为了进一步推动技术创新和产品研发,FerriShield积极寻求与高校和研究机构的合作。公司与多所知名大学建立了产学研合作关系,共同开展新材料、新工艺的研究和开发。这些合作不仅提升了FerriShield的技术实力,还为公司培养了一批高素质的研发人才。

Datasensor公司的发展小趣事

1978年,DATALOGIC公司成功研制出欧洲第一台条码扫描器,并将此产品应用于商业领域。这一创新不仅展示了公司在光电技术领域的实力,也为其在工业自动化领域赢得了良好的声誉。条码扫描器的成功推出,为公司带来了可观的收益,也为公司后续的技术研发和市场拓展提供了强有力的支持。

Electech Electronics公司的发展小趣事

在快速发展的同时,Electech Electronics也注重环保和可持续发展。公司积极采用环保材料和绿色生产工艺,降低生产过程中的能耗和排放。此外,Electech Electronics还积极参与环保公益活动,推动电子行业的绿色发展。这些举措不仅体现了公司的社会责任感,也为公司的长期发展奠定了基础。

Dell公司的发展小趣事

随着科技的不断发展,Electech Electronics意识到仅仅依赖电子元器件的代理和销售已经无法满足市场的需求。于是,公司开始投入研发,专注于电子产品的设计和制造。经过数年的努力,Electech Electronics成功开发出一系列具有竞争力的电子产品,如智能控制模块、高精度传感器等。这些产品的推出不仅拓宽了公司的产品线,也提升了公司的市场竞争力。

问答坊 | AI 解惑

显示故障: VISTA下图片自动播放时偏向右侧,不知什么原因?

请教一显示故障: 在VISTA平台下,使用windows自带的图片播放器,自动播放时图像偏向右侧,此现象只有在最大分辨率的情况下会出现,在此特请教一下高手们,指点指点,谢谢!…

查看全部问答>

shen zhen programmer

程序员在深圳群已经超过1500人,里面有很多在大公司上班的成员(包括国家级的研究院),有很多经验丰富的成员(包括参加过上亿元的项目的架构师),有很热爱技术的成员(包括自己写过嵌入式操作系统),希望大家踊跃发言,找到志同道合的朋友,找到对你有帮助的 ...…

查看全部问答>

mobile下声音处理(调用API出错,高手请进)

        MMRESULT  mres;         if (mres = waveOutOpen(&hWaveOut, WAVE_MAPPER, &lpFormat, (DWORD_PTR)sb_callback, (DWORD_PTR)pDeviceMemory, CALLBACK_FUNCTION) !=0)     ...…

查看全部问答>

有什么好的WinCE学习资料,大家推荐以下,谢了!

有什么好的WinCE学习资料,大家推荐以下,谢了!…

查看全部问答>

EE_FPGA V1.0 发现的一个BUG

AM29LV160DB的接法有些问题   BYTE已经被我接地了,那么就是8为数据宽度,只需要引出D0-D7就可以了 而EE_FPGA V1.0中是把D0-D15全部引出的 这点将在下一版中改进,设置为8bit和16bit模式可选  …

查看全部问答>

关于430f149sram得扩展

偶是个430新手,这两天看了些资料,但是一直没有看到关于外扩ram得应用,想弱弱得问一下,430用哪个口扩展外部ram,扩展后,软件是怎么操作得(比如c51使用XBYTE访问得)? 请大虾不要置疑为何扩展ram,只因为系统确实需要这么做才能正常工作,这 ...…

查看全部问答>

请教一个UCOS中断任务的问题

    假设一个任务在执行过程中,被中断,然后保存现场进入中断后,发现更高优先级任务,这时候,执行更高优先级任务,在执行更高优先级任务时候,被中断的任务处在什么状态?在被中断的代码中,没有看到被挂起的代码。还有更高优先 ...…

查看全部问答>

C2000 问题汇总Ver 1.0

C28x Based DeviceQ: What is the difference between the TMS320F28xx and the TMS320C28xx MCUs? A: The \"F\" represents flash, while the \"C\" represents ROM. The Flash devices are reprogrammable and are available through normal dist ...…

查看全部问答>

是不是今年会有压控LC振荡器 类似得题目?

本帖最后由 paulhyde 于 2014-9-15 09:08 编辑 我看看了看03年的元件清单有个高频变容二极管,然后那年题目就有电压控制LC振荡器。是不是今年有可能会有呢?  …

查看全部问答>

易电源试用报告4:总结

这么晚发,实在是抱歉。。。。。 我总结的比较晚,各路大侠都已经说得差不多了,总结的也比我这业余人士强多了。时间也不早了,哈哈,我就只是简单说一下自己的想法吧,说多无益免得贻笑大方。其实在测试之前我还是不太明白这电源模块的优点,边测 ...…

查看全部问答>