1.测试准备工作
1.1. 开发板硬件资源介绍:
1.2. 首先通过国民技术的技术资料网址,用浏览器打开后如下所示:
选择下载了n32l40xxx_v2.1.0.zip资料包后,解压得到官方demo,数据手册,评估板,软件开发套件,应用笔记,测试资料等等。如下图所示:
1.3. 引脚资源分配介绍
本例中can的引脚使用gpiob的引脚8和引脚9配置can的接收和发送引脚。将gpioc的引脚11和引脚10配置为usart3的接收和发送引脚,通过usb转uart模块,晶振等公共资源就不一一介绍。
1.4. 功能模块介绍
本方案从软件上主要分为三部份,can模块,串口通讯模块和日志输出模块。
can模块:主要负责can报文的收发,报文解析。
串口通讯模块:将can模块接收的can报文传输至上位机,将上位机发送的can报文转给can模块发送到can网络中。
日志输出模块:输出系统运行过程中的日志。
1.5. 性能指标
本案例测试中,将测试波特率为500kbps,250kbps,125kbps三个波特率,具体指标为:
错误率:帧错误率:99%
采样率:85%
连续测试时长:72小时
2.环境搭建及创建工程。
2.1.首先到rt-thread官方网站下载rt-thread studio,并安装好,启动rt-thread studio.点击sdk安装按钮,弹出下图所示界面。
2.3.还需要安装pyocd,防止在下载程序时报错
2.4.在文件选择新建,由于不支持rt-thread nano,所以只能选择rt-thread项目。
2.5. 在弹出菜单中,选择项目存放路径,输入项目名,选择基于开发板,并选择本次的测试开发板,点击确定,就创建了基于模板的工程。
2.6.在项目内的rt-thread settings中打开can模块功能,串口1用于日志打印。
3.rtthread的can驱动机制介绍
3.1. rtconfig.h配置文件介绍
在rt-thread setting中,打开usart3和can后,在rtconfig.h配置文件中可以看到定义了bsp_using_can,rt_using_pin,rt_using_serial宏,表示启动了can驱动与设备。
3.2.can drive 驱动介绍,
3.2.1.rt-thread提供i/o设备管理接口来访问can硬件控制,接口如下:
3.2.2.通过init_board_export将can的硬件驱动加载到初始化列表中,通过rt_hw_can_register将can注册到rt-thread的设备列表中。
3.2.3.在调用rt_device_register函数,将设备注册到os的设备列表中。
3.2.4.can波特率配置
3.3.测试代码
#include
#include
#include
#include
/* defined the led3 pin: pb5 /
#define led3_pin get_pin(b, 5)
#define led2_pin get_pin(b, 4)
int main(void)
{
/ set led3 pin mode to output /
rt_pin_mode(led3_pin, pin_mode_output);
rt_pin_mode(led2_pin, pin_mode_output);
thread_candriver_entry(rt_null);
while (1)
{
rt_pin_write(led2_pin, pin_low);
rt_pin_write(led3_pin, pin_high);
rt_thread_mdelay(500);
rt_pin_write(led3_pin, pin_low);
rt_pin_write(led2_pin, pin_high);
rt_thread_mdelay(500);
}
}
#include
/
copyright (c) 2006-2021, rt-thread development team
spdx-license-identifier: apache-2.0
change logs:
date author notes
2023-04-22 chunyang.jiang the first version
/
#include rtdevice.h
#include
#include
#include
#define can_dev_name bxcan / can 设备名称 /
struct rt_semaphore rx_sem; / 用于接收消息的信号量 /
static rt_device_t can_device; / can 设备名称 */
struct rt_can_msg can_msg = {0};
struct rt_can_msg canrx_msg = {0};
static rt_thread_t thread_rec;
static rt_thread_t thread_send;
static void thread_can_send(void *parameter);
static void thread_can_receiver(void *parameter);
static rt_err_t can_receivermessage_call(rt_device_t dev, rt_size_t size)
{
rt_sem_release(&rx_sem);
// rt_kprintf(can receiver message!rn);
return rt_eok;
}
static void thread_can_receiver(void parameter)
{
rt_err_t ret;
int i;
/ 设置接收回调函数 /
rt_device_set_rx_indicate(can_device, can_receivermessage_call);
/
struct rt_can_filter_item items[5] =
{
{0x100, 0, 0, 0, 0x700, rt_null},
{0x300, 0, 0, 0, 0x700, rt_null},
{0x211, 0, 0, 0, 0x7ff, rt_null},
{0x486, 0, 0, 0, 0x7ff, rt_null},
{0x555, 0, 0, 0, 0x7ff, 7}
};
struct rt_can_filter_config cfg = {5,1,items};
ret = rt_device_control(can_device,rt_can_cmd_set_filter,&cfg);
rt_assert(ret == rt_eok);
*/
while(1)
{
canrx_msg.hdr = -1;
rt_sem_take(&rx_sem, rt_waiting_forever);
rt_device_read(can_device, 0, &canrx_msg, sizeof(canrx_msg));
rt_kprintf(id:%x,canrx_msg.id);
for(i=0; i >8);
can_msg.data[2] = (i>>16);
can_msg.data[3] = (i>>24);
can_msg.data[4] = 0x05;
can_msg.data[5] = 0x06;
can_msg.data[6] = 0x07;
can_msg.data[7] = 0x08;
res = rt_device_write(can_device, 0, &can_msg, sizeof(can_msg));
if(res == 0)
{
// rt_kprintf(can send a frame failed!rn);
}
else
{
// rt_kprintf(can send a frame success!rn);
}
can_msg.id = 0x778;
can_msg.ide = rt_can_stdid;
can_msg.rtr = rt_can_dtr;
can_msg.len = 0x08;
can_msg.data[0] = a;
can_msg.data[1] = (a>>8);
can_msg.data[2] = (a>>16);
can_msg.data[3] = (a>>24);
can_msg.data[4] = 0x05;
can_msg.data[5] = 0x06;
can_msg.data[6] = 0x07;
can_msg.data[7] = 0x08;
res = rt_device_write(can_device, 0, &can_msg, sizeof(can_msg));
if(res == 0)
{
// rt_kprintf(can send a frame failed!rn);
}
else
{
// rt_kprintf(can send a frame success!rn);
}
can_msg.id = 0x508;
can_msg.ide = rt_can_stdid;
can_msg.rtr = rt_can_dtr;
can_msg.len = 0x08;
can_msg.data[0] = 8;
can_msg.data[1] = 8;
can_msg.data[2] = 8;
can_msg.data[3] = 8;
can_msg.data[4] = 0x05;
can_msg.data[5] = 0x06;
can_msg.data[6] = 0x07;
can_msg.data[7] = 0x08;
res = rt_device_write(can_device, 0, &can_msg, sizeof(can_msg));
if(res == 0)
{
// rt_kprintf(can send a frame failed!rn);
}
else
{
// rt_kprintf(can send a frame success!rn);
}
rt_thread_mdelay(1);
}
}
int thread_candriver_entry(void *parameter)
{
static char can_name[rt_name_max];
static uint32_t can_name_len = 0;
rt_err_t ret;
can_name_len = sizeof(can_dev_name);
rt_strncpy(can_name, can_dev_name, rt_name_max);
/ 在设备列表中查找设备 /
can_device = rt_device_find(can_name);
if(!can_device)
{
rt_kprintf(find %s failed!rn,can_name);
return rt_error;
}
/ 初始化信号量 /
rt_sem_init(&rx_sem, rx_sem, 0 ,rt_ipc_flag_fifo);
/ 打开设备 /
ret = rt_device_open(can_device, rt_device_flag_int_tx | rt_device_flag_int_rx);
rt_assert(ret == rt_eok);
thread_send = rt_thread_create(thread_send, thread_can_send,rt_null, 1024,25,1);
if(thread_send == null)
{
rt_kprintf(create can send failed!rn);
return rt_error;
}
else
{
rt_thread_startup(thread_send);
}
thread_rec = rt_thread_create(thread_receiver, thread_can_receiver,rt_null, 1024,25,1);
if(thread_send == null)
{
rt_kprintf(create can send failed!rn);
return rt_error;
}
else
{
rt_thread_startup(thread_rec);
}
}
msh_cmd_export(thread_candriver_entry, can device driver sample);
4.测试效果图
测试效果图连接:
在测试时,测试500kbps,250bps,125bps波特率,报文发送时间间隔为10ms,开发板发送3帧,接收一帧(由于测试can只支持1帧发送)
5.测试总结
在测试中发现在没有安装pyocd,无法烧录的问题,同时还发现在发送can数据时,执行res = rt_device_write(can_device, 0, &can_msg, sizeof(can_msg));发送一帧can数据时,通过can测试盒,明显看到有报文发出,但返回状态一直为0,于是跟踪测试后发现在等待can发送后,没有对发送结果进行返回导致,于是修改代码,如下图所示:
另外也发现如果can的tx,rx不接can驱动器时,执行发送数据后,代码会进入死循环。这个问题是驱动机制导致,如果遇到这个问题可以查一下can驱动接接线,驱动器是否工作。
总的说来,本次测试挺顺利的,除了部分bug外,can能够实现10ms多帧发送,并同时处理接收报文。满足日常设计中的can通讯需求。
梳理电容的三大作用
中国到2020年将产生1800万个大数据业机会
施耐德电气,助力核心业务,赋能终端配电智能化未来
同样2499元 小米6被iphone6吊打!国产手机的悲哀
利用AI掌握生物钟,助力精准医疗
N32L40XCL-STB开发板模块评测任务大挑战-测试CAN
恒温电烙铁的工作原理及制作方法
万众期待的代码解释器上线了!
超实用的汽车电路接线10条规律
禾多科技积极推动自动驾驶大规模量产落地
机器人成功帮猪修复受损的食道 医疗技术更进一步
直流工作点是什么意思
深入体验魅蓝5s之后,冲着这几点这款手机买到就是赚到
云原生应用中的“云”指的是什么?
光路科技工业交换机助力智慧交通行业发展,成为行业新兴力量
苹果回应iPhone12消磁:买个价值479元的MagSafe皮革卡包就可以了
呼气阀气密性测试仪的主要组成是怎样的
芯片缺货潮如何解决?如何看待立讯精密遭美国337调查?工信部回应
触控板和手势组合以控制AR
关于HiSpark WiFi IoT OLED移植到鸿蒙