我是靠谱客的博主 机智热狗,最近开发中收集的这篇文章主要介绍一文弄通STM32F103基于simulink自动代码生成CAN/USART/GPIO/TIM(stm32cubemx+stm32target+matlab2018b)写在前面1、stm32cubemx的配置2、搭建simulink模型3、生成代码及编译4、实际测试效果写在最后,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一文弄通STM32F103基于simulink自动代码生成CAN/USART/GPIO/TIM(stm32cubemx+stm32target+matlab2018b)

  • 写在前面
  • 1、stm32cubemx的配置
    • 1.1选择芯片型号
    • 1.2配置时钟
    • 1.3 配置时钟树
    • 1.4 配置下载模式
    • 1.5 TIM中断配置
    • 1.6 通讯配置
      • CAN配置
      • USART配置
    • 1.7 GPIO配置
    • 1.8 工程配置
  • 2、搭建simulink模型
    • 2.1目标文件系统的配置
    • 2.2搭建芯片配置
    • 2.3应用层模块的搭建
      • 2.3.1使用TIM1和GPIO实现1s闪灯
      • 2.3.2使用TIM6和CAN send实现500ms发送一条can报文
      • 2.3.3使用CAN FIFO,CAN receive和USART实现指定can报文接收及串口转发数据
        • 过滤器配置
        • can接收模型
        • 接收子系统及USART模型
  • 3、生成代码及编译
  • 4、实际测试效果
  • 写在最后

写在前面

之前用过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发送的)
STM32F103RCT+TJA1050+USBCAN盒做can通讯
程序下载使用STLINK,同时也方便调试。(正常量产一般选择CAN bootloader来更新程序,这个我已经实现了,后面有机会再发文章)
调试串口需要一个USB转TTL的设备。如果是无线通讯,需要两个无线透传的模块。本次用的就是两个无线透传的模块。
本文用到的模块包括:
GPIO输出(用来点亮LED灯)
TIM定时中断(定周期触发)
USART(串口发送数据)
CAN(发送,接收,过滤

1、stm32cubemx的配置

1.1选择芯片型号

打开stm32cubemx,新建工程,搜索STM32F103RC,选择STM32F103RCTx(这个根据自己手里的芯片选择,我的是F103的,所以选这个)
在这里插入图片描述

1.2配置时钟

选择外部时钟High Speed Clock(HSE),在RCC中配置为Crystal
在这里插入图片描述

1.3 配置时钟树

本次使用的开发版晶振为8M,经过PLL超频后系统时钟为72M
CAN使用的时钟是APB1,我们配置为36M,后面会用到
在这里插入图片描述

1.4 配置下载模式

本次使用STLINK调试下载程序,选择SW模式。
在这里插入图片描述

1.5 TIM中断配置

这个根据应用程序来,本次使用了两个TIM中断,使用TIM1和TIM6。这里配置了后面还可以再增加或减少。
TIM1配置为输出比较模式,设置上升沿触发
在这里插入图片描述
激活TIM6
在这里插入图片描述

1.6 通讯配置

CAN配置

使能CAN,引脚选择PB8.PB9(这个看自己板子,有的可能是PA11,PA12),预分频系数Prescaler选择9,TQ1选5个tq,TQ2选2个tq,得到波特率为500K(1/2000us)
计算公式如下:
36000000(APB1的时钟)/(9(分频系数)/(5(TQ1)+2(TQ2)+1(同步段时间1tq))=500k
在这里插入图片描述
对于重同步来说,同步跳转宽度(SJW,reSynchronization Jump Width)设置的太小则重新同步的调整速度慢,若太大,则影响传输速率。若想了解更多can同步知识,请自行查阅。
在这里插入图片描述
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(异步),波特率选择115200。
在这里插入图片描述

1.7 GPIO配置

配置PD2和PA8为GPIO输出,在右边的引脚图上左键可以配置。
GPIO Output level:默认输出电平为低电平。
根据开发板原理图可知,输出低电平时灯亮
在这里插入图片描述

1.8 工程配置

设置工程名,工程路径,选择编译器为MDK-ARM V5
在这里插入图片描述
以上,配置STM32cubemx的工作就完成了,Ctrl+s保存工程。(和后面建的simulink模型放在一个文件夹下)不需要在cube中生成代码,生成代码在simulink中,由simulink调用cube。

2、搭建simulink模型

新建一个simulink模型,保存在和cube工程相同的文件夹下。

2.1目标文件系统的配置

点击模型左上方的小齿轮,进入模型配置界面
选择离散型,定步长时间为0.001s,这个时间为模型运行一次的时间,最好设置为0.001实测设置为0.01会报错。
在这里插入图片描述
Code Generation中目标系统文件选择stm32.tlc。关于目标系统tlc文件,可以参考我的另外几个博客。
从零开始simulink自定义代码生成----自定义目标系统配置(1)

在这里插入图片描述
选择完后下面会多出来一个选项,勾选
在这里插入图片描述
点Updata install path,会自动找到安装cube的目录
配置好上述设置后,点ok保存设置,至此目标系统配置完成。

2.2搭建芯片配置

打开simulink模块库,选择stm32下的mcu config模块,拖到模型中

在这里插入图片描述

双击打开mcu config,选择之前配置好的cube工程
在这里插入图片描述
导入芯片配置后,之前在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配置图如下:
在这里插入图片描述
配置好后,点ok,模块右侧会出现一个输出,该输出为function call,我们选择一个function子系统来执行回调函数
在这里插入图片描述
在function子系统中增加两个GPIO write模块,一个配置为PA8.一个配置为PD2
在这里插入图片描述
在这里插入图片描述
模型中增加了一个delay模块和一个取反模块,实现两个灯的来回亮灭。不是很复杂的逻辑。

2.3.2使用TIM6和CAN send实现500ms发送一条can报文

TIM6的配置和上面的TIM1差不多。只是将频率改为了2HZ(对应0.5s)
在这里插入图片描述
function子系统中建立模型如下,模拟一条报文的发送,选择的是simulink自带的can pack模块,第一个信号递增输出,最大值为7(位数为3),其他两个信号为常数输出。该模块输出时必须要有一个变化的值或变量输出,否则会报错,原因未知。如果是要全部输出常值,可以在function外部输入进来
在这里插入图片描述
在这里插入图片描述
关于发送can报文,本文没有使用中断。
在生成代码调试过程遇到一个非常奇怪的问题,HAL函数在添加报文(addmessage)以后,会卡在CAN_IsTxMessagePending函数中,一直没有解决,屏蔽这个while就好了,网上看其他can发送的函数里,基本没有用过这个IsTxMessagePending函数,暂时在tlc文件中将其屏蔽了,生成代码的时候也会是屏蔽的状态。如果有同学遇到了知道什么原因可以告知我一下。
关于tlc文件的作用,可以参考我的其他博客
从零开始simulink自定义代码生成----自定义硬件驱动库文件(1)

can_send模块对应的tlc文件在STM32-MAT的安装目录下,我的是在C:MATLABSTM32-MATSTM32blksmextlc_c,找到Can_send.tlc文件,记事本打开,对其进行修改。在while函数前加//,注释掉这个生成的代码。
在这里插入图片描述
注释掉这个代码后,生成的代码可以正常发送can数据。
使用usbcan接收数据,这个之前的博客也说过的。

2.3.3使用CAN FIFO,CAN receive和USART实现指定can报文接收及串口转发数据

在模型中添加如下模块
在这里插入图片描述

过滤器配置

can接收时,即使不需要过滤,也需要添加一个过滤器(选择mask模式,32位,MASK ID HIGH LOW,ID HIGH LOW都填0,过滤器选择FIFO0,其他默认就好)
关于can 过滤器,有两种模式,一种mask模式(掩码模式),一种list模式(列表模式),有两种位选择,一种32位,一种16位。组合起来有四种模式
在这里插入图片描述

对于列表模式,很好理解,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的配置如下:
在这里插入图片描述
注意:此处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信号
在这里插入图片描述
if模块配置,两者不为0可以进入Subsystem
在这里插入图片描述

接收子系统及USART模型

将收到的can数据通过USART1串口发送出来,设置发送的字节为2,RcvUsartBuf转化在官方的demo中的usart模块中有。将两个不同的can中的数据进行组合,放入buf中
在这里插入图片描述

在这里插入图片描述
至此模型的搭建,也已经完成了。
注意:在can接收的模型中,又发现一个问题,标准帧可以接收到数据,正常转发,而扩展帧中的数据接收不到。通过STlink调试发现,生成的代码中unpack模块判断扩展帧是为1,而接收的ID信息在赋值时,STM32定义的扩展帧表示为4.
可能当时做这个STM32硬件驱动库的人就没考虑到用unpack解析?感觉STM32做的库确实不太给力啊
同样的解决方案,找到can_read_data.tlc,修改为下图所示
在这里插入图片描述

3、生成代码及编译

模型搭建完成后,ctrl+b生成代码,用KEIL5打开工程,编译后通过STLINK将程序烧写到开发板中。
编译过程中可能会遇到缺少头文件和源文件,
can_message.h,在mat-target安装目录下的addSrcR2018binc 目录下,拷贝到生成的工程头文件夹下
getBuffPtr.h,在mat-target安装目录下的addSrcinc目录下,拷贝到生成的工程头文件夹下
getBuffPtr.c,在mat-target安装目录下的addSrcsrc目录下,拷贝到生成的工程源文件夹下
还有一种方法,在simulink配置Model Configuration Parameters(小齿轮))中配置
选择对应文件夹下的文件即可,编译的时候会包含选择的文件
在这里插入图片描述

4、实际测试效果

can 500ms发送一帧数据
在这里插入图片描述
灯来回闪(只拍了两张图)
在这里插入图片描述
在这里插入图片描述
can接收数据及串口转发
发送0x51,串口可以转发数据
在这里插入图片描述
在这里插入图片描述
更换数据发送
在这里插入图片描述
在这里插入图片描述
发送0x52,can无法接受到数据,串口不转发(串口后面没有7的数据)
在这里插入图片描述
在这里插入图片描述
发送0x18ff31f0,串口可以转发数据(转发数据为2)
在这里插入图片描述
在这里插入图片描述
此处之前一个can转发的数据8还是在继续发送,保持了上一次的值,本文没有处理。

写在最后

后面还有can中断收发还没有试,串口接收,输入电平采集,其他can过滤方式后面有空再测试~
STM32的硬件驱动库还有很多不完善的地方,后面有空再多多研究~~

欢迎大家点赞转发分享~~有问题可以与我联系:WX/QQ:953590472
STM32cube工程及模型及生成的代码

最后

以上就是机智热狗为你收集整理的一文弄通STM32F103基于simulink自动代码生成CAN/USART/GPIO/TIM(stm32cubemx+stm32target+matlab2018b)写在前面1、stm32cubemx的配置2、搭建simulink模型3、生成代码及编译4、实际测试效果写在最后的全部内容,希望文章能够帮你解决一文弄通STM32F103基于simulink自动代码生成CAN/USART/GPIO/TIM(stm32cubemx+stm32target+matlab2018b)写在前面1、stm32cubemx的配置2、搭建simulink模型3、生成代码及编译4、实际测试效果写在最后所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部