一、前言
本博文的目的是是直接我弄好的BSP,直接往STM32工程里加入代码就能简单并快速地完成CANopen协议的移植。
刚开始研究“如何在STM32上实现CANopen协议”时注意到广州硬石科技的教程。这个教程我建议同学们一定要学习一下,移植Canfestival的流程我记得是没问题的。如下图所示: 硬石教程给Canfestival设计的定时器的代码在实现上有问题,说白了就是“定时不准。 先不说硬石实现方法复杂(使用定时器的比较中断实现定时器中断),而且从我测试报文的时间间隔看来是有误差的(尤其在几个ms的时候)。所以,移植可以从硬石教程上学习,但是定时器的实现最好使用我这篇博文的方法。其实,我也是参考别人的文章,并走了不少弯路后才总结出来的。经过us级的定时器事件证明我的方法是可行的。
我使用的硬件: 工程代码: 链接:https://pan.baidu.com/s/1ysuNG82IyljWxVn48Dl8OA 提取码:dhfi
二、移植前的准备
- 移植CANopen协议之前,需要准备一个已经完成CAN底层驱动的工程。我是基于之前分享的工程上进行CANopen协议的移植的,所以需要下载该工程的代码:
STM32H743+CubeMX-双路FDCAN同时工作的终极方案(裸机) - 下载我的提供的代码。里面含我编写的BSP与Canfestival的源码与对象字典的文件,如下图所示:
这些文件的共享地址: 链接:https://pan.baidu.com/s/10c05VtPURW4YWGYWKX1pcA 提取码:1uwt
三、移植
3.0、移植的目的
在开发板的FDCAN1接口上实现CANopen从站。当然,我编写的这个bsp已经预留了FDCAN2也能实现CANopen从站或者主站。一般情况下,开发板只需一个FDCAN口实现CANopen。
3.1、工程的实际硬盘上添加文件夹
3.2、往bsp文件夹放入bsp代码
3.3、往canfestival里放入源代码
3.4、往obj_dir里放入代码
3.5、在工程上添加文件canfestival,obj_dir,bsp三个文件夹
3.6、在工程里添加各个文件的代码
特别注意一下的是,文件夹canfestival/Inc/STM32里的头文件也必须添加,如下图所示:
3.7、添加include的路径
在Keil的工程上添加完工程后,需要继续添加include Paths,不然会出现找不到”啥啥头文件“的情况。
四、定时器
4.1、TIM17
选择TIM17的原因是canfestival只需要一个简单的定时器,会产生定时器溢出中断即可,所以没必要占用其他高级定时器。 配置240-1分频的原因是TIM17挂载在APB2时钟总线上,APB2的时钟频率是240M,所以需要将此定时器进行1/240分频,让定时器的工作频率为1M。 接着,生成并编译代码。出现4个Error(s),5个Warning(s),但先不用管它。
五、代码
5.1、bsp_canopen_timer.h
在bsp_canopen_timer.h里告诉canfestival,我给它提供了TIM17定时器。 接着,编译代码后发现0 Error(s)里,还有5个Warning(s)。 其内容如下,在sdo.c文件里,我是不管这个警告的,在实践中也没有发现SDO有问题,可能是编译器原因吧。反正,不用管这5个警告,不会影响canfestival的使用。 再重新编译一次,就会出现0 Error(s),0 Warning(s).
5.2、main.c
函数HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)是HAL库的定时器中断回调函数,在main.c里调用。 TIM17是提供给Canfestival的,所以在TIM17的中断回调里调用TIMx_DispatchFromISR()。
5.3、bsp_fdcan.c
首先包含两个头文件: 因为只在FDCAN1接口上实现CANopen协议,所以在FDCAN的RX FIFO0的中断回调函数HAL_FDCAN_RxFifo0Callback()调用canfestival的接收函数canDispatch()。
5.4、回到main.c
接着,编译代码:
5.5、重定向printf
我的bsp代码里面有很多printf,所以一定要实现printf,否则单片机系统会跑飞。实现printf有很多种方法。我使用Keil自带的EventRecorder实现printf。 还是回到main.c 编译代码,下载代码到开发板子上。
六、调试
6.1、Debug(printf)Viewer
在这里调试窗口,可以看到printf的信息。
6.1、CAN分析仪调试
至此,FDCAN1已经运行CANopen协议了!!!!
七、细节补充
7.1、将CANopen从站的Node_ID改为0x05
一般情况,CANopen从站的Node_ID不能设为0x01,0x01最好留给CANopen主站使用。 修改代码,编译与下载代码后,从CAN分析仪观察报文。
|