Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
drv_can.c_CAN设备驱动
CAN调试过程曲折不断,记录调试过程的问题和解决方法。
发布于 2024-10-08 14:04:36 浏览:209
订阅该版
[tocm] ## 编译问题 使用了5.1.0创建工程。CAN编译总是不成功。后来发现5.1.0的drv_can.h/.c与can.c/h不是最新的。 ```c [rt-thread/bsp/stm32/libraries/HAL_Drivers/drivers/drv_can.h at v5.1.0 · RT-Thread/rt-thread · GitHub](https://github.com/RT-Thread/rt-thread/blob/v5.1.0/bsp/stm32/libraries/HAL_Drivers/drivers/drv_can.h) ``` 到这下载最新的相应文件替换 ## 接收问题 使用了示例代码如下,发现能触发事件但是收不到数据,后来研究发现开了硬件过滤,关了就好了。 ```c #include "rtthread.h" #include "rtdevice.h" /* can接收事件标志 */ #define CAN_RX_EVENT (1 << 0) static rt_device_t can_device = RT_NULL; static struct rt_event can_event; static rt_err_t can_rx_ind(rt_device_t device, rt_size_t len) { rt_event_send(&can_event, CAN_RX_EVENT); return RT_EOK; } /* CAN初始化 */ static rt_err_t can_open() { can_device = rt_device_find("can1"); if (RT_NULL == can_device) { rt_kprintf("can1 device not found!\n"); return -RT_ERROR; } // rt_device_control(can_device, RT_CAN_CMD_SET_BAUD, (void *)CAN500kBaud); /* 初始化事件对象 */ rt_event_init(&can_event, "can_rx_event", RT_IPC_FLAG_FIFO); /* 设置回调函数发送事件 */ rt_device_set_rx_indicate(can_device, can_rx_ind); return rt_device_open(can_device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX); /* 设置 CAN 通信的波特率为 500kbit/s*/ } void print_can_msg(struct rt_can_msg *data) { rt_kprintf("\n"); if (RT_CAN_STDID == data->ide) { rt_kprintf("STDID=%03X ", data->id); } else if (RT_CAN_EXTID == data->ide) { rt_kprintf("EXTID=%08X ", data->id); } rt_kprintf("HDR=%02X ", data->hdr); if (RT_CAN_DTR == data->rtr) { rt_kprintf("TYPE=DATA LEN=%02X ", data->len); for (int i = 0; i < data->len; ++i) { rt_kprintf("%02X ", data->data[i]); } } else if (RT_CAN_RTR == data->rtr) { rt_kprintf("TYPE=RMOT LEN=%02X ", data->len); } } rt_err_t can_write(struct rt_can_msg *data, rt_size_t len) { return rt_device_write(can_device, 0, data, len); } rt_err_t can_read(struct rt_can_msg *data, rt_size_t len) { rt_err_t ret = 0; rt_uint32_t e; while (1) { ret = rt_event_recv(&can_event, CAN_RX_EVENT, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &e); if (RT_EOK != ret){ } else { rt_device_read(can_device, 0, data, len); print_can_msg(data); // rt_thread_mdelay(1); } } } #define CAN_ID 0x12 rt_size_t can_sendmsg(const rt_uint8_t *data, const rt_uint32_t len) { struct rt_can_msg msg = {0}; msg.id = CAN_ID; msg.ide = RT_CAN_STDID; msg.rtr = 0; msg.len = len; rt_memcpy(msg.data, data, len); return rt_device_write(can_device, 0, &msg, sizeof(msg)); } int can_write_test(int argc, char **argv) { can_sendmsg(argv[1], 8); } /********线程入口***************/ void can1_entry(void *param) { struct rt_can_msg msg = { .id = 1, .ide = RT_CAN_STDID, .rtr = RT_CAN_DTR, .len = 8, .data = {0, 1, 2, 3, 4, 5, 6, 7} }; can_write(&msg, sizeof(struct rt_can_msg)); msg.rtr = RT_CAN_RTR; can_write(&msg, sizeof(struct rt_can_msg)); msg.ide = RT_CAN_EXTID; msg.rtr = RT_CAN_DTR; can_write(&msg, sizeof(struct rt_can_msg)); msg.rtr = RT_CAN_RTR; can_write(&msg, sizeof(struct rt_can_msg)); // while(1) { // msg.id = 0xff; // msg.rtr = RT_CAN_STDID; // can_write(&msg, sizeof(struct rt_can_msg)); can_read(&msg, sizeof(struct rt_can_msg)); rt_thread_mdelay(100); } } /*线程创建函数*/ int can1_test(void) { rt_thread_t can1_tid; if (RT_EOK != can_open()) return -RT_ERROR;/*创建线程控制块指针来接收线程创建函数的返回值,目的是通过返回值判断线程是否创建ok*/ can1_tid = rt_thread_create("can1_test", /*线程名称,系统打印线程时会显示这个线程的名字*/ can1_entry, /*线程入口函数,入口函数函数名*/ RT_NULL, /*入口参数*/ 1024, /*设置内存堆栈大小*/ 2, /*设置优先级*/ 10); /*时间片参数,时间片是在有多个相同优先级线程时,这个线程每次被执行多少个时间片*/ /* 如果获得线程控制块,启动这个线程 */ if (can1_tid != RT_NULL) rt_thread_startup(can1_tid); return RT_EOK; } INIT_APP_EXPORT(can1_test); /* 导出到 msh 命令列表中 */ MSH_CMD_EXPORT(can_write_test, test can write); ``` ### 波特率问题 发现只能使用1M波特率,修改波特率后无法通信,drv_can.c中波特率配置如下 ```c {CAN1MBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_4TQ | 3)}, {CAN800kBaud, (CAN_SJW_2TQ | CAN_BS1_8TQ | CAN_BS2_5TQ | 4)}, {CAN500kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 6)}, {CAN250kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 12)}, {CAN125kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 24)}, {CAN100kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 30)}, {CAN50kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 60)}, {CAN20kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 150)}, {CAN10kBaud, (CAN_SJW_2TQ | CAN_BS1_9TQ | CAN_BS2_5TQ | 300)} ``` 把这个配置丢到STM32CUBE里面发现除了1M的波特率其他的根本对不上号,时钟频率42没问题。 反推后发现CAN_BS2_5TQ应该配置成CAN_BS2_4TQ ![Snipaste_2024-10-08_14-02-19.png](https://oss-club.rt-thread.org/uploads/20241008/65fa68bd6dc638609a23adff1d4a0053.png) 修改后正常 特此记录~诸位避坑
1
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
AJS琥珀清年
这家伙很懒,什么也没写!
文章
2
回答
0
被采纳
0
关注TA
发私信
相关文章
1
STUDIO找不到drv_can.c
2
请教如何注册can设备?
3
tm4c129x can驱动程序
4
因为can 的原因,差点让我放弃了RT-Thread 这是一个问题.
5
如何使用开启CAN驱动?
6
RTthread 使用CAN通讯硬件端口怎么配置的?
7
基于F107RC芯片CAN驱动
8
GD32 能否通过设备驱动的方式操作CAN,有没有drv_can.c
9
rtthread是否有GD32F303对应的drv_can驱动
10
执行can_sample后程序卡在_can_sendmsg中
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
at_device
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
13
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
7
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
3
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部