最近需要使用CAN,之前并没有接触过CAN方面的知识,由于项目中使用了RTX,所以打算直接使用RL_CAN实现,不过实现过程中出现些问题
由于是测试,所以直接建立了以下三个任务进行测试:
sendCANTask:用于发送消息,由于之前运行时串口助手中显示的数据有误,因此,直接将发送消息固定为6~~
receCANTask:用于接收消息
dispTask: 用于打印发送消息及接收到的消息,验证CAN实现是否有误
CAN的工作模式采用的是环回静默模式,所以并没有外接CAN驱动,,, (弱弱的问一句:是不是必须要接CAN驱动?不接就无法开启CAN?)
问题描述:在串口助手中显示的发送数据及接收数据都是 -- 0 ,这是它们的初始值,,,
设置断点进行调试后,发现senCANTask任务卡在了CAN_start(1) ,因此造成了senCANTask无法进入
循环以及receCANTask没接收到数据,,所以显示的数据就是它们的初始值了~~
个人猜想:是否是因为我没接CAN驱动造成的?可是环回静默模式用不上它吧~~
使用过RL_CAN的大侠们给小弟点指导吧!
程序主要代码:
- U32 Tx_val = 0, Rx_val = 0; /* Global variables used for display */
- /**
- * @brief CAN发送消息任务.
- * @param None.
- * @note 周期性的发送data[0]中的数据.
- * @retval None
- */
- __task void sendCANTask (void) {
- /* Initialize message = { ID, {data[0] .. data[7]}, LEN, CHANNEL, FORMAT, TYPE } */
- CAN_msg msg_send = { 33, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- 1, 2, STANDARD_FORMAT, DATA_FRAME };
- CAN_init (1, 500000); /* CAN controller 1 init, 500 kbit/s */
- CAN_rx_object (1, 2, 33, DATA_TYPE | STANDARD_TYPE); /* Enable reception */
- /* of message on controller 1, channel */
- /* is not used for STM32 (can be set to*/
- /* whatever value), data frame with */
- /* standard id 33 */
- /* The activation of test mode in line below is used for enabling
- self-testing mode when CAN controller receives the message it sends so
- program functionality can be tested without another CAN device */
- /* COMMENT THE LINE BELOW TO ENABLE DEVICE TO PARTICIPATE IN CAN NETWORK */
- CAN_hw_testmode(1, CAN_BTR_SILM | CAN_BTR_LBKM); /* Loopback and */
- /* Silent Mode (self-test)*/
- CAN_start (1); /* Start controller 1 */
- int i = 0;
- for (;;) {
- msg_send.data[0] = 6; /* Data[0] field = analog value from */
- /* potentiometer */
- printf("before sendData\n");
- CAN_send (1, &msg_send, 0x0F00); /* Send msg_send on controller 1 */
- Tx_val = msg_send.data[0];
- printf("after sendData\n");
- os_dly_wait (100); /* Wait 1 second */
- }
- }
- /**
- * @brief CAN接收消息任务.
- * @param None.
- * @note None.
- * @retval None
- */
- __task void receCANTask (void) {
- CAN_msg msg_rece;
- for (;;) {
- /* When message arrives store received value to global variable Rx_val */
- if (CAN_receive (1, &msg_rece, 0x00FF) == CAN_OK) {
- Rx_val = msg_rece.data[0];
- printf("receive success\n");
- }
- }
- }
- __task void dispTask (void) {
- for (;;) {
-
- printf("sendData: %d, receData: %d\n\n",Tx_val, Rx_val);
- os_dly_wait(1000);
- }
- }
- /**
- * @brief 初始化任务.
- * @param None.
- * @note 用于创建任务,当任务都创建完成时,其使命达成自行销毁.
- * @retval None
- */
- __task void initTask (void) {
- t_sendCAN = os_tsk_create(sendCANTask,1);
- t_receCAN = os_tsk_create(receCANTask,1);
- t_disp = os_tsk_create(dispTask,1);
- os_tsk_delete_self();
- }
复制代码 串口助手显示数据:
|
仿真模式下程序运行正常,,硬件下调试则失败~~
好吧 研究了大半天~~ 又是修改时钟频率又是重新编译的、、
最后发现出错的原因还是有点郁闷,,,
keil既然提供了demo,需要修改的文件为什么不在文档中指出,图1中的文档为什么没指出
问题出处:keil提供的STM32F103的RL_CAN示例程序是基于STM32F103RB的,
而我当前板子上使用的是STM32F103C8,两者CAN使用的引脚不同,
一个是PB8、PB9,一个是PA11、PA12,因此需要修改驱动文件。
解决方法:进入CAN_STM32F103.c文件,找到CAN_hw_setup (U32 ctrl)函数,
将其中对PB8,9的配置部分注释掉,将其下边的PA11,12的配置指令
取消注释,然后重新编译后就好了,如图2所示:
顺带贴上最终串口助手显示信息,CAN显示的是通道1的设置温度--》80,如图3
图1:
图2:
图3:
评分
查看全部评分