0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

ART-PI FDCAN使用方法

冬至子 来源:陈建颖 作者:陈建颖 2023-09-28 16:33 次阅读

1.FDCAN设备添加

如下图所示,使用RT-Thread Setting 添加默认的FDCAN1设备,保存并重新构建到工程;

1.jpg

2.修改波特率配置

检查系统时钟配置,确认can输入时钟为80Mhz,如下图所示:

1.jpg

修改drv_fdcan.c文件,由于本文使用的是500K的波特率,故只改了一小部分。
static const _stm32_fdcan_NTconfig_t st_CanNTconfig[]=
/ baud brp sjw tseg1 tseg2 /
{
{CAN1MBaud, 1,8,63,16},
{CAN800kBaud, 10,8,20,4},
{CAN500kBaud, 2,8,63,16},
{CAN250kBaud, 20,8,35,4},
{CAN125kBaud, 40,8,35,4},
{CAN100kBaud, 40,8,44,5},
{CAN50kBaud, 80,8,44,5},
{CAN20kBaud, 200,8,44,5},
{CAN10kBaud, 400,8,44,5}
};
修改drv_fdcan.c文件下的FDCAN_MODE_INTERNAL_LOOPBACK,改为FDCAN_MODE_EXTERNAL_LOOPBACK;此项改动为防止FDCAN在回环模式下TX没有输出信号
static rt_err_t _inline_can_config(struct rt_can_device *can, struct can_configure *cfg)
{
_stm32_fdcan_t *pdrv_can;
rt_uint32_t tmp_u32Index;
RT_ASSERT(can);
RT_ASSERT(cfg);
pdrv_can = (_stm32_fdcan_t )can->parent.user_data;
RT_ASSERT(pdrv_can);
pdrv_can->fdcanHandle.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_NORMAL;
pdrv_can->fdcanHandle.Init.AutoRetransmission = DISABLE;
pdrv_can->fdcanHandle.Init.TransmitPause = DISABLE;
pdrv_can->fdcanHandle.Init.ProtocolException = DISABLE;
switch (cfg->mode)
{
case RT_CAN_MODE_NORMAL:
pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_NORMAL;
break;
case RT_CAN_MODE_LISEN:
pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_BUS_MONITORING;
break;
case RT_CAN_MODE_LOOPBACK:
pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_EXTERNAL_LOOPBACK;
break;
default:
pdrv_can->fdcanHandle.Init.Mode = FDCAN_MODE_NORMAL;
break;
}
/ config baud rate /
tmp_u32Index = _inline_get_NTbaud_index(cfg->baud_rate);
pdrv_can->fdcanHandle.Init.NominalPrescaler = st_CanNTconfig[tmp_u32Index].u16Nbrp;
pdrv_can->fdcanHandle.Init.NominalSyncJumpWidth = st_CanNTconfig[tmp_u32Index].u8Nsjw;
pdrv_can->fdcanHandle.Init.NominalTimeSeg1 = st_CanNTconfig[tmp_u32Index].u8Ntseg1;
pdrv_can->fdcanHandle.Init.NominalTimeSeg2 = st_CanNTconfig[tmp_u32Index].u8Ntseg2;
if(pdrv_can->fdcanHandle.Instance == FDCAN1)
{
pdrv_can->fdcanHandle.Init.MessageRAMOffset = 0;
}
else
{
pdrv_can->fdcanHandle.Init.MessageRAMOffset = 1280;
}
pdrv_can->fdcanHandle.Init.StdFiltersNbr = 2;
pdrv_can->fdcanHandle.Init.ExtFiltersNbr = 2;
pdrv_can->fdcanHandle.Init.RxFifo0ElmtsNbr = 1;
pdrv_can->fdcanHandle.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
pdrv_can->fdcanHandle.Init.RxBuffersNbr = 0;
pdrv_can->fdcanHandle.Init.TxEventsNbr = 0;
pdrv_can->fdcanHandle.Init.TxBuffersNbr = 3;
pdrv_can->fdcanHandle.Init.TxFifoQueueElmtsNbr = 0;
pdrv_can->fdcanHandle.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
pdrv_can->fdcanHandle.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
if (HAL_FDCAN_Init(&pdrv_can->fdcanHandle) != HAL_OK)
{
return -RT_ERROR;
}
/
default filter config /
HAL_FDCAN_ConfigFilter(&pdrv_can->fdcanHandle , &pdrv_can->FilterConfig);
/ init fdcan tx header /
_inline_can_tx_header_init(pdrv_can);
/
can start */
HAL_FDCAN_Start(&pdrv_can->fdcanHandle);
return RT_EOK;
}

3.添加外设软件包
使用RT-Thread Setting 添加【rtthread设备驱动使用示例】软件包,在搜索框中搜索samples也可以找到,配置如下图所示;

1.jpg

2.添加完成后,查看can_sample.c文件,如下图所示;
1.jpg

3.修改can_sample.c文件,代码如下,主要是将can1设备改为fdcan1,并增加设置can波特率语句。

#include
#include
#define CAN_DEV_NAME "fdcan1" /* CAN 设备名称 /
static struct rt_semaphore rx_sem; /
用于接收消息的信号量 /
static rt_device_t can_dev; /
CAN 设备句柄 /
/
接收数据回调函数 /
static rt_err_t can_rx_call(rt_device_t dev, rt_size_t size)
{
/
CAN 接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */
rt_sem_release(&rx_sem);
return RT_EOK;
}
static void can_rx_thread(void parameter)
{
int i;
rt_err_t res;
struct rt_can_msg rxmsg = {0};
/
设置接收回调函数 /
rt_device_set_rx_indicate(can_dev, can_rx_call);
#ifdef RT_CAN_USING_HDR
struct rt_can_filter_item items[5] =
{
RT_CAN_FILTER_ITEM_INIT(0x100, 0, 0, 0, 0x700, RT_NULL, RT_NULL), /
std,match ID:0x1000x1ff,hdr 为 - 1,设置默认过滤表 /
RT_CAN_FILTER_ITEM_INIT(0x300, 0, 0, 0, 0x700, RT_NULL, RT_NULL), /
std,match ID:0x300
0x3ff,hdr 为 - 1 /
RT_CAN_FILTER_ITEM_INIT(0x211, 0, 0, 0, 0x7ff, RT_NULL, RT_NULL), /
std,match ID:0x211,hdr 为 - 1 /
RT_CAN_FILTER_STD_INIT(0x486, RT_NULL, RT_NULL), /
std,match ID:0x486,hdr 为 - 1 /
{0x555, 0, 0, 0, 0x7ff, 7,} /
std,match ID:0x555,hdr 为 7,指定设置 7 号过滤表 /
};
struct rt_can_filter_config cfg = {5, 1, items}; /
一共有 5 个过滤表 /
/
设置硬件过滤表 /
res = rt_device_control(can_dev, RT_CAN_CMD_SET_FILTER, &cfg);
RT_ASSERT(res == RT_EOK);
#endif
while (1)
{
/
hdr 值为 - 1,表示直接从 uselist 链表读取数据 /
rxmsg.hdr = -1;
/
阻塞等待接收信号量 /
rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
/
从 CAN 读取一帧数据 /
rt_device_read(can_dev, 0, &rxmsg, sizeof(rxmsg));
/
打印数据 ID 及内容 /
rt_kprintf("ID:%x", rxmsg.id);
for (i = 0; i < 8; i++)
{
rt_kprintf("%2x", rxmsg.data[i]);
}
rt_kprintf("n");
}
}
int mycan_sample(int argc, char argv[])
{
struct rt_can_msg msg = {0};
rt_err_t res;
rt_size_t size;
rt_thread_t thread;
char can_name[RT_NAME_MAX];
if (argc == 2)
{
rt_strncpy(can_name, argv[1], RT_NAME_MAX);
}
else
{
rt_strncpy(can_name, CAN_DEV_NAME, RT_NAME_MAX);
}
/
查找 CAN 设备 /
can_dev = rt_device_find(can_name);
if (!can_dev)
{
rt_kprintf("find %s failed!n", can_name);
return RT_ERROR;
}
/
初始化 CAN 接收信号量 /
rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
/
以中断接收及发送方式打开 CAN 设备 /
res = rt_device_open(can_dev, RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_INT_RX);
RT_ASSERT(res == RT_EOK);
/
设置 CAN 通信的波特率为 500kbit/s
/
res = rt_device_control(can_dev, RT_CAN_CMD_SET_BAUD, (void )CAN500kBaud);
RT_ASSERT(res == RT_EOK);
/
创建数据接收线程 /
thread = rt_thread_create("can_rx", can_rx_thread, RT_NULL, 1024, 25, 10);
if (thread != RT_NULL)
{
rt_thread_startup(thread);
}
else
{
rt_kprintf("create can_rx thread failed!n");
}
msg.id = 0x78; /
ID 为 0x78 /
msg.ide = RT_CAN_STDID; /
标准格式 /
msg.rtr = RT_CAN_DTR; /
数据帧 /
msg.len = 8; /
数据长度为 8 /
/
待发送的 8 字节数据 /
msg.data[0] = 0x00;
msg.data[1] = 0x11;
msg.data[2] = 0x22;
msg.data[3] = 0x33;
msg.data[4] = 0x44;
msg.data[5] = 0x55;
msg.data[6] = 0x66;
msg.data[7] = 0x77;
/
发送一帧 CAN 数据 /
size = rt_device_write(can_dev, 0, &msg, sizeof(msg));
if (size == 0)
{
rt_kprintf("can dev write data failed!n");
}
return res;
}
/
导出到 msh 命令列表中 */
MSH_CMD_EXPORT(mycan_sample, can device sample);

4.测试结果

1.jpg

注意:再次使用命令启动该示例会有以下提示:

1.jpg

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • CAN总线
    +关注

    关注

    145

    文章

    1942

    浏览量

    130717
  • STM32
    +关注

    关注

    2270

    文章

    10893

    浏览量

    355660
  • RT-Thread
    +关注

    关注

    31

    文章

    1285

    浏览量

    40065
  • 系统时钟
    +关注

    关注

    1

    文章

    30

    浏览量

    9306
  • HAL库
    +关注

    关注

    1

    文章

    121

    浏览量

    6213
收藏 人收藏

    评论

    相关推荐

    ART-Pi Smart开发板开箱及爱之初次体验

    ART-Pi Smart 开发板初次尝鲜,ART-Pi Smart开箱及初次体验内置应用.
    的头像 发表于 05-03 16:25 5003次阅读
    <b class='flag-5'>ART-Pi</b> Smart开发板开箱及爱之初次体验

    ART-Pi Studio工程下NimBLE软件包的使用

    本文主要介绍 ART-Pi Studio 工程下 NimBLE 软件包的使用
    的头像 发表于 08-26 10:31 1679次阅读

    ART-PI重力感应无线智能小车设计实现

    ART-PI重力感应无线智能小车第一弹-----ART-PI扩展板设计雷德斯 and枕头们,小飞哥又又叒好久没更新文章啦,最近实在是太忙啦,大家久等啦,这次是系列文章,一步步教你如何在ART-PI
    发表于 02-10 06:39

    怎样在ART-Pi H750上移植TouchGFX呢

    目录在ART-Pi H750上移植TouchGFX(一)——使用STM32CUBMX生成TouchGFX工程在ART-Pi H750上移植TouchGFX(二)——制作MDK的外部
    发表于 02-22 06:01

    基于ART-Pi Smart平台的设计方案推荐

    ART-Pi Smart 平台上实现视频播放功能;由于ART-Pi Smart 没有音频模块,所以没有实现音频的解码播放。在上一篇分享中,我们在 ART-Pi Smart 平台上实现了视频解码
    发表于 03-24 16:56

    基于ART-Pi与SX1302的设计资料分享

    1、基于 ART-Pi lora-pkt-sniffer 抓包工具抓取空口 LoRa 数据包 8 个并行的 LoRa BW125KHz 通道 支持 CRC 过滤机制 串口 shell 支持参数读写
    发表于 04-01 16:36

    ART-PI在MDK中使用SDIO设备的方法

    一、ENV使能SDIO1.1.在kconfig增加配置因为ART-PI的SDIO2连接的是wifi,所以这里我们使用SDIO1。1.2.ENV中使能SDIO1.3.使能文件系统1.4.使用SD设备
    发表于 04-11 10:07

    如何才能在art-pi上运行fdcan

    大家好,art-pi板上运行CAN2.0没问题,收发自如,若想运行canfd,是不是需要对drv_fdcan.c做修改?比如一些参数配置等
    发表于 04-21 09:27

    关于ART-PI的基本使用例程简单描述

    ,使用静态IP与PC直连做测试。后续有需要,将ARI-PI通过路由器连接PC,可以随时再打开DHCP。5.保存Setting,编译,成功。2 基本测试1.将ART-PI通电并连接网线2.通过设备管理
    发表于 06-01 15:06

    ART-Pi LoRa开发套件教程相关资料分享

    1、ART-Pi LoRa 开发套件简介  ART-Pi LoRa 开发套件(LSD4RFB-2EVKM0201)是利尔达科技与睿赛德科技联合出品的一套面向物联网开发者的 LoRa产品原型设计工
    发表于 09-30 11:57

    art-pi板上运行canfd是不是需要对drv_fdcan.c做修改?

    大家好,art-pi板上运行CAN2.0没问题,收发自如,若想运行canfd,是不是需要对drv_fdcan.c做修改?比如一些参数配置等。
    发表于 02-08 11:40

    RT-AK及Art-Pi简介

    Github:https://github.com/EdgeAIWithRTT/Project7-Cifar10_Cube_Art-Pi RT-AK 及 Art-Pi 简介 目前该项目为 RT-AK
    的头像 发表于 07-26 18:16 3614次阅读
    RT-AK及<b class='flag-5'>Art-Pi</b>简介

    【STM32H750】玩转ART-Pi(一)——使用STM32CUBMX生成TouchGFX工程

    目录在ART-Pi H750上移植TouchGFX(一)——使用STM32CUBMX生成TouchGFX工程在ART-Pi H750上移植TouchGFX(二)——制作MDK的外部
    发表于 12-28 19:20 10次下载
    【STM32H750】玩转<b class='flag-5'>ART-Pi</b>(一)——使用STM32CUBMX生成TouchGFX工程

    【技术三千问】之《玩转ART-Pi》,看这篇就够了!

    2.在 ART-Pi 平台有没有人成功使用 openocd 可以直接烧写到外部 Quad spi flash 的?[链接]
    发表于 01-25 18:44 2次下载
    【技术三千问】之《玩转<b class='flag-5'>ART-Pi</b>》,看这篇就够了!

    ART-PI重力感应无线智能小车第一弹——ART-PI扩展板设计

    雷德斯 and 枕头们,小飞哥好久没更新文章啦,最近实在是太忙啦,大家久等啦,这次是系列文章,一步步教你如何在ART-PI上实现无线重力感...
    发表于 01-25 19:27 1次下载
    <b class='flag-5'>ART-PI</b>重力感应无线智能小车第一弹——<b class='flag-5'>ART-PI</b>扩展板设计