stm32f103串口接收函数_STM32MP157

stm32f103串口接收函数_STM32MP157一文弄通STM32F103基于simulink自动代码生成CAN/USART/GPIO/TIM(stm32cubemx+stm32target+matlab2018b)写在前面之前用过stm32发送can数据,用stm32与simulink联合开发只搞了一个tim中断和led

一文弄通STM32F103基于simulink自动代码生成CAN/USART/GPIO/TIM(stm32cubemx+stm32target+matlab2018b)   写在前面   之前用过stm32发送can数据,用stm32与simulink联合开发只搞了一个tim中断和led闪灯,也没有记录,弄完就忘了,最近又有时间来做下代码生成,不需要手写一行代码实现控制逻辑。本文用来记录下过程及遇到的一些问题。方便以后自己查看的同时,希望对后面遇到相关问题的同学有所帮助~~~本文用到的matlab版本为2018b,stm32cubemx版本为5.3.0,stm32mat_target版本为5.6.0,编译器版本为KEIL5,后面的开发都基于上述四个版本的软件,如果版本不匹配可能会遇到各种问题(如生成的代码中不包含主逻辑函数的调用等),软件的下载在官网即可,网上也有很多下载链接,本文不再给出。安装cube还需要安装java,网上有详细教程。本文用到的开发版为STM32F103RCT开发板,两个LED输出(PD2,PA8),USART1串口,CAN0发送与接收(PB8,PB9)。由于开发板没有带TJA1050can收发芯片,所以还需要一个TJA1050模块(我之前的一篇文章有讲过,关于stm32can发送的)   程序下载使用STLINK,同时也方便调试。(正常量产一般选择CAN bootloader来更新程序,这个我已经实现了,后面有机会再发文章)调试串口需要一个USB转TTL的设备。如果是无线通讯,需要两个无线透传的模块。本次用的就是两个无线透传的模块。本文用到的模块包括:GPIO输出(用来点亮LED灯)TIM定时中断(定周期触发)USART(串口发送数据)CAN(发送,接收,过滤)   1、stm32cubemx的配置   1.1选择芯片型号   打开stm32cubemx,新建工程,搜索STM32F103RC,选择STM32F103RCTx(这个根据自己手里的芯片选择,我的是F103的,所以选这个)
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   1.2配置时钟   选择外部时钟High Speed Clock(HSE),在RCC中配置为Crystal
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   1.3 配置时钟树   本次使用的开发版晶振为8M,经过PLL超频后系统时钟为72MCAN使用的时钟是APB1,我们配置为36M,后面会用到
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   1.4 配置下载模式   本次使用STLINK调试下载程序,选择SW模式。
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   1.5 TIM中断配置   这个根据应用程序来,本次使用了两个TIM中断,使用TIM1和TIM6。这里配置了后面还可以再增加或减少。TIM1配置为输出比较模式,设置上升沿触发
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   激活TIM6
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   1.6 通讯配置   CAN配置   使能CAN,引脚选择PB8.PB9(这个看自己板子,有的可能是PA11,PA12),预分频系数Prescaler选择9,TQ1选5个tq,TQ2选2个tq,得到波特率为500K(1/2000us)计算公式如下:(APB1的时钟)/(9(分频系数))/(5(TQ1)+2(TQ2)+1(同步段时间1tq))=500k
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   对于重同步来说,同步跳转宽度(SJW,reSynchronization Jump Width)设置的太小则重新同步的调整速度慢,若太大,则影响传输速率。若想了解更多can同步知识,请自行查阅。
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   Time Triggered Communication 选择disable选择非时间触发通讯模式Automatic Bus-Off Management 选择disable(可以enable)表示Bus Off后无法自恢复Automatic Wake-Up Mode 选择disable(可以enable)表示不开启自动唤醒No-Automatic Retransmission 选择disable(可以enable)表示允许报文自动重传Receive Fifo Locked Mode 接收FIFO锁定模式,选择disable,表示报文不锁定,新的覆盖旧的Transmit Fifo Priority 发送FIFO优先级选择disable,表示优先级由报文标识符决定Operating Mode ,选择正常模式(如果调试配置参数,可以选择环回模式)Normal CAN硬件工作在正常模式silent CAN硬件工作在静默模式LoopBack 环回模式Silent_LoopBack 静默环回模式   本文的can通讯暂未使用到中断模式。后面有时间再测试。   USART配置   使能USART1,选择Asynchronous(异步),波特率选择。
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   1.7 GPIO配置   配置PD2和PA8为GPIO输出,在右边的引脚图上左键可以配置。GPIO Output level:默认输出电平为低电平。根据开发板原理图可知,输出低电平时灯亮
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   1.8 工程配置   设置工程名,工程路径,选择编译器为MDK-ARM V5
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   以上,配置STM32cubemx的工作就完成了,Ctrl+s保存工程。(和后面建的simulink模型放在一个文件夹下)不需要在cube中生成代码,生成代码在simulink中,由simulink调用cube。   2、搭建simulink模型   新建一个simulink模型,保存在和cube工程相同的文件夹下。   2.1目标文件系统的配置   模型左上方的小齿轮,进入模型配置界面选择离散型,定步长时间为0.001s,这个时间为模型运行一次的时间,最好设置为0.001,实测设置为0.01会报错。
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   Code Generation中目标系统文件选择stm32.tlc。关于目标系统tlc文件,可以参考我的另外几个博客。
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   选择完后下面会多出来一个选项,勾选
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   点Updata install path,会自动找到安装cube的目录配置好上述设置后,点ok保存设置,至此目标系统配置完成。   2.2搭建芯片配置   打开simulink模块库,选择stm32下的mcu config模块,拖到模型中   
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   双击打开mcu config,选择之前配置好的cube工程
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   导入芯片配置后,之前在cube里配置的模块就可以在simulink中使用了,如果没有配置的模块将会是灰色,无法选择   2.3应用层模块的搭建   2.3.1使用TIM1和GPIO实现1s闪灯   从simulink模块库中,托一个TIM模块到模型中,双击点开TIM模块进行配置。APB为之前时钟树设置的频率,无法在该模块中修改。选择Timer通道为TIM1分频系数选7199,(7199+1=7200),将TIM1时钟降为10000HZ(这里默认是999,这样的话,如果周期变成1s,计数ARR就会溢出)选择输出频率为1HZ(对应周期为1s),ARR值自动变为10000(表示的是计数到10000后触发中断)选择UP中断   注意: ARR值最大为65535,超过后会导致溢出,定时中断出现错误。该模块并没有考虑值大于65535的情况,如果是大于65535的数仍然是可以生成代码的。同时输出的频率必须为整数,不能为小数。小数也可以生成代码,但生成的代码是错误的,这个STM32硬件驱动库没有考虑。上面两点都是本人实测出来的,TIM1配置图如下:
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   配置好后,点ok,模块右侧会出现一个输出,该输出为function call,我们选择一个function子系统来执行回调函数
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   在function子系统中增加两个GPIO write模块,一个配置为PA8.一个配置为PD2
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   模型中增加了一个delay模块和一个取反模块,实现两个灯的来回亮灭。不是很复杂的逻辑。   2.3.2使用TIM6和CAN send实现500ms发送一条can报文   TIM6的配置和上面的TIM1差不多。只是将频率改为了2HZ(对应0.5s)
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   function子系统中建立模型如下,模拟一条报文的发送,选择的是simulink自带的can pack模块,第一个信号递增输出,最大值为7(位数为3),其他两个信号为常数输出。该模块输出时必须要有一个变化的值或变量输出,否则会报错,原因未知。如果是要全部输出常值,可以在function外部输入进来
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   关于发送can报文,本文没有使用中断。在生成代码调试过程遇到一个非常奇怪的问题,HAL函数在添加报文(addmessage)以后,会卡在CAN_IsTxMessagePending函数中,一直没有解决,屏蔽这个while就好了,网上看其他can发送的函数里,基本没有用过这个IsTxMessagePending函数,暂时在tlc文件中将其屏蔽了,生成代码的时候也会是屏蔽的状态。如果有同学遇到了知道什么原因可以告知我一下。关于tlc文件的作用,可以参考我的其他博客can_send模块对应的tlc文件在STM32-MAT的安装目录下,我的是在C:\MATLAB\STM32-MAT\STM32\blks\mex\tlc_c,找到Can_send.tlc文件,记事本打开,对其进行修改。在while函数前加//,注释掉这个生成的代码。
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   注释掉这个代码后,生成的代码可以正常发送can数据。使用usbcan接收数据,这个之前的博客也说过的。   2.3.3使用CAN FIFO,CAN receive和USART实现指定can报文接收及串口转发数据   在模型中添加如下模块
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   过滤器配置   can接收时,即使不需要过滤,也需要添加一个过滤器(选择mask模式,32位,MASK ID HIGH LOW,ID HIGH LOW都填0,过滤器选择FIFO0,其他默认就好)关于can 过滤器,有两种模式,一种mask模式(掩码模式),一种list模式(列表模式),有两种位选择,一种32位,一种16位。组合起来有四种模式
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   对于列表模式,很好理解,32位宽的列表模式,可以精确筛选两个ID(扩展帧和标准帧都可以),对于16位宽的列表模式,可以精确筛选4个标准帧ID,如果将IDE位置1,则可以筛选ID的高11位数据,无法精确筛选扩展帧ID。对于掩码模式,可以这样理解,有一个屏蔽码和验证码,屏蔽码用来指定需要确定的位,验证码用来指定确定的位的值,两者一起用来过滤部分ID。关于验证码和屏蔽码,网上也有很多教程说明,此处不再说明。32位的掩码模式,FilterIdHigh与FilterIdLow合在一起表示CAN_FxR1寄存器,用来存放验证码,而FilterMaskIdHigh与FilterMaskIdLow合在一起表示CAN_FxR2寄存器,用来存放屏蔽码在16位宽的掩码模式下,CAN_FxR1的低16位是作为验证码,对应的16位屏蔽码为CAN_FxR1的高16位,同样的,CAN_FxR2的低16位是作为验证码,对应与CAN_FxR2的高16位为屏蔽码本次使用的是32位宽的列表模式来指定确定的一个标准帧ID和一个扩展帧ID,其他过滤方式后面有空再测试。can过滤器FIFO的配置如下:
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   注意:此处Filter Mask ID High Filter Mask ID Low Filter ID High Filter ID Low四位值填的是十进制数。在生成代码的过程中会转化为16进制。在32位列表模式下,Filter Mask ID High Filter Mask ID Low的组合和Filter ID High Filter ID Low两者实现的功能是一样的。定义需要过滤的标准帧ID为0x51,扩展帧ID为0x18ff31f0。定义将标准帧ID的过滤放在Filter Mask ID High 和Filter Mask ID Low中由上图的32位列表模式排列图可知,标准帧格式占的是高位,要想过滤确定一个标准帧0x51,需要把ID左移5位,然后转化为十进制,填入Filter Mask ID High,计算值为2592,Filter Mask ID Low需要把IDE置为标准帧(值为0),数据帧RTR(值为0),所以计算值为0。要想过滤一个扩展帧0x18ff31f0,需要把先ID左移3位,再把ID右移16位,和0xffff做与运算,再转换为十进制,得到Filter ID High的值51193 ((ExtId<<3)>>16)&0xffff;Filter ID Low需要把先ID左移3位,和0xffff做与运算,再将IED为置为扩展帧(值为4这个地方后面会有用),数据帧RTR(值为0),再转换为十进制36740 (ExtId<<3)&0xffff|CAN_ID_EXT对于STM32F103只有一个can,filter slave start bank没有作用,若是两路can,尽量设置为14。filter bank默认即可。   can接收模型   按官方给的demo,最好在CAN_get_state=ready(1)且read_data=ready(1)后再解析数据read_data配置输出为can massage信号
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   if模块配置,两者不为0可以进入Subsystem
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   接收子系统及USART模型   将收到的can数据通过USART1串口发送出来,设置发送的字节为2,RcvUsartBuf转化在官方的demo中的usart模块中有。将两个不同的can中的数据进行组合,放入buf中
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   至此模型的搭建,也已经完成了。注意:在can接收的模型中,又发现一个问题,标准帧可以接收到数据,正常转发,而扩展帧中的数据接收不到。通过STlink调试发现,生成的代码中unpack模块判断扩展帧是为1,而接收的ID信息在赋值时,STM32定义的扩展帧表示为4.可能当时做这个STM32硬件驱动库的人就没考虑到用unpack解析?感觉STM32做的库确实不太给力啊同样的解决方案,找到can_read_data.tlc,修改为下图所示
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   3、生成代码及编译   模型搭建完成后,ctrl+b生成代码,用KEIL5打开工程,编译后通过STLINK将程序烧写到开发板中。编译过程中可能会遇到缺少头文件和源文件,can_message.h,在mat-target安装目录下的\addSrc\R2018b\inc 目录下,拷贝到生成的工程头文件夹下getBuffPtr.h,在mat-target安装目录下的\addSrc\inc目录下,拷贝到生成的工程头文件夹下getBuffPtr.c,在mat-target安装目录下的\addSrc\src目录下,拷贝到生成的工程源文件夹下还有一种方法,在simulink配置Model Configuration Parameters(小齿轮))中配置选择对应文件夹下的文件即可,编译的时候会包含选择的文件
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   4、实际测试效果   can 500ms发送一帧数据
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   灯来回闪(只拍了两张图)
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   can接收数据及串口转发发送0x51,串口可以转发数据
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   更换数据发送
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   发送0x52,can无法接受到数据,串口不转发(串口后面没有7的数据)
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   发送0x18ff31f0,串口可以转发数据(转发数据为2)
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   
stm32f103串口接收函数_STM32MP157
stm32f103串口接收函数_STM32MP157   此处之前一个can转发的数据8还是在继续发送,保持了上一次的值,本文没有处理。后面还有can中断收发还没有试,串口接收,输入电平采集,其他can过滤方式后面有空再测试~欢迎大家点赞转发分析~~有问题可以与我联系:WX/sigusoft:

2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/33894.html

(0)
上一篇 2024年 9月 10日 下午4:06
下一篇 2024年 9月 10日 下午4:10

相关推荐

关注微信