完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
前言
最近导师要求接触到了hlw8032芯片,这是一款可以测量用电设备的电流、电压与功率等的芯片,具体参数大家可以自行百度,网上有很多HLW8032的使用例程,有基于51的与基于stm32f103的,由于项目需要用到stm32f413的nucleo的开发板,抽空移植了一下,过程中还是有很多的收获,特此分享。 程序移植 由于是单片机与8032是串口通信,为了验证我用了两路串口,一路通信,一路打印输出结果。打开f413的官网例程,找到uart-comit例程,用于串口的中断接收。 然后就是修改例程里面的内容啦,先修改串口的初始化吧,我用了串口2和串口3,在main.h里,修改对应的引脚。 然后修改串口的结构体相关参数。 这里就遇到了第一个坑,也是我卡最长时间的原因,因为在给的stm32f103的例程里,与8032的通信串口使用的是8位字长,没有奇偶校验位,而且最关键的是可以正常运行!所以我移植过来的时候也没有仔细查看,然后debug的时候一直卡在frame error,没办法,读了一遍手册才发现坑爹的地方,手册里是9位数据位和一位偶校验位,而网上能搜的例程都是不严谨的!在F1系列上的板子可以运行,但是在F4上不能运行,切记还是要自己读手册呀~ 然后就是修改HAL_UART_MspInit函数,添加第二个串口的对应数据。这里简单,大家自行修改就行。 接下来就对于我来说是一个难点了吧,串口中断接收这里(大家可以参考原子哥的F429的视频,讲的就是HAL库,悔恨自己做完才看到呀~)还是要看手册!可以查到8032发给单片机是24个16进制数解析一次,代表一次完整的数据帧。HAL_UART_Receive_IT(&UartHandle,(uint8_t *)getBuffer,24); 所以我们设置接收到24个数进入一次回调函数,也就是HAL_UART_RxCpltCallback。 if((getBuffer[0] == 0x55) && (getBuffer[1] == 0x5A)) { CmdAnalysis(getBuffer,24); BSP_LED_Off(LED_RED); } 如上图程序,判断接收到的帧是否符合数据要求的格式,数据格式自己看手册哈!CmdAnalysis函数是例程里的数据解析函数,这个复制过来就好。 到现在我们移植的函数是不是大部分就完成了呢?其实是这样的,不过千万不要忽略一个点,这是我遇到的第二个坑,就是单片机在接收数据的时候,如果在上电是的时候接收时数据帧的中间部分,换一句话说如果是从数据帧中间开始接收的话就会出错,卡死直接进入error handler里面,所以我们必须优化让它能自动优化掉这个问题,我当时在思考的时候看到8032是隔50ms给单片机发一次数据,我在想判断第一次后接收到的24个数据如果开始不是0X55和0X5A的话,就舍弃掉这一帧数据,然后接收下一帧,这种想法仍然是错的,因为下一帧接收时仍然是和上一帧是错误的,也是从中间开始接收的,所以在接收完一帧之后必须延时一点时间,舍弃掉从中间帧到结尾帧的部分(这一段有点不好表达,大家多想想),使得下一次接收是从起始帧(0X55,0X5A)开始,然后接下来后面的数据就完全正确了,所以上面的50ms就起到作用了,我们差不多延时个10~20ms左右就可以舍弃掉中间帧到结尾帧的部分,而又不影响下次接收,是不是很完美呢? 于是乎我写了个HAL_Delay(10)加在回调函数中,发现还是卡死了,debug发现是卡死在延时里了,我才意识到这个回调函数竟然在中断里!本着快进快出的原则,中断里还是不要加延时了(因为我测试加delay就会卡死),怎么办呢?我想到的是加一个定时器中断,产生10ms中断调用一次这个函数,可是想想好麻烦,本来HAL库就不熟,后来还是老师指点了一下,加一个软件延时不就行了,这时候我才茅塞顿开。软件延时里将接收到的错误数据清0,还可以延时一点时间完美解决这个问题。附上这里的代码: if((getBuffer[0] == 0x55) && (getBuffer[1] == 0x5A)) { CmdAnalysis(getBuffer,24); BSP_LED_Off(LED_RED); } else {for(1=0;1<24;i++){getBuffer=0;}for(j=0;i<9990000;j++){k++;}} 我感觉这个方法挺笨的,不过暂时解决了问题,而且修复的很快。如果大佬们有更好的方法,欢迎指出~ 然后就是主函数里不停的循环读数了,打印出来,记得在中断服务函数里加一行代码HAL_UART_Receive_IT(&UartHandle, (uint8_t *)getBuffer,24);因为接收一次后会关闭中断,加了之后就可以一直循环接收了。 void USARTx_IRQHandler(void){ HAL_UART_IRQHandler(&UartHandle); HAL_UART_Receive_IT(&UartHandle, (uint8_t *)getBuffer,24);} 到这里基本上本次实验就完成了,我自己跑了完美运行~完整例程后续我会上传。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1641 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1562 浏览 1 评论
988 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
691 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1608 浏览 2 评论
1869浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
655浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
525浏览 3评论
540浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
512浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-25 23:08 , Processed in 0.851376 second(s), Total 79, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号