0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

ART-PI FDCAN使用方法

冬至子 ? 來源:陳建穎 ? 作者:陳建穎 ? 2023-09-28 16:33 ? 次閱讀

1.FDCAN設備添加

如下圖所示,使用RT-Thread Setting 添加默認的FDCAN1設備,保存并重新構建到工程;

1.jpg

2.修改波特率配置

檢查系統(tǒng)時鐘配置,確認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在回環(huán)模式下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設備驅(qū)動使用示例】軟件包,在搜索框中搜索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 設備句柄 /
/
接收數(shù)據(jù)回調(diào)函數(shù) /
static rt_err_t can_rx_call(rt_device_t dev, rt_size_t size)
{
/
CAN 接收到數(shù)據(jù)后產(chǎn)生中斷,調(diào)用此回調(diào)函數(shù),然后發(fā)送接收信號量 */
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};
/
設置接收回調(diào)函數(shù) /
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 鏈表讀取數(shù)據(jù) /
rxmsg.hdr = -1;
/
阻塞等待接收信號量 /
rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
/
從 CAN 讀取一幀數(shù)據(jù) /
rt_device_read(can_dev, 0, &rxmsg, sizeof(rxmsg));
/
打印數(shù)據(jù) ID 及內(nèi)容 /
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);
/
以中斷接收及發(fā)送方式打開 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);
/
創(chuàng)建數(shù)據(jù)接收線程 /
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; /
數(shù)據(jù)幀 /
msg.len = 8; /
數(shù)據(jù)長度為 8 /
/
待發(fā)送的 8 字節(jié)數(shù)據(jù) /
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;
/
發(fā)送一幀 CAN 數(shù)據(jù) /
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

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • CAN總線
    +關注

    關注

    145

    文章

    1898

    瀏覽量

    130337
  • STM32
    +關注

    關注

    2258

    文章

    10828

    瀏覽量

    352509
  • RT-Thread
    +關注

    關注

    31

    文章

    1239

    瀏覽量

    39442
  • 系統(tǒng)時鐘

    關注

    1

    文章

    30

    瀏覽量

    9247
  • HAL庫
    +關注

    關注

    1

    文章

    114

    瀏覽量

    6034
收藏 人收藏

    評論

    相關推薦

    ART-Pi Smart開發(fā)板開箱及愛之初次體驗

    ART-Pi Smart 開發(fā)板初次嘗鮮,ART-Pi Smart開箱及初次體驗內(nèi)置應用.
    的頭像 發(fā)表于 05-03 16:25 ?4802次閱讀
    <b class='flag-5'>ART-Pi</b> Smart開發(fā)板開箱及愛之初次體驗

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

    本文主要介紹 ART-Pi Studio 工程下 NimBLE 軟件包的使用
    的頭像 發(fā)表于 08-26 10:31 ?1568次閱讀

    ART-PI重力感應無線智能小車設計實現(xiàn)

    ART-PI重力感應無線智能小車第一彈-----ART-PI擴展板設計雷德斯 and枕頭們,小飛哥又又叒好久沒更新文章啦,最近實在是太忙啦,大家久等啦,這次是系列文章,一步步教你如何在ART-PI
    發(fā)表于 02-10 06:39

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

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

    基于ART-Pi Smart平臺的設計方案推薦

    ART-Pi Smart 平臺上實現(xiàn)視頻播放功能;由于ART-Pi Smart 沒有音頻模塊,所以沒有實現(xiàn)音頻的解碼播放。在上一篇分享中,我們在 ART-Pi Smart 平臺上實現(xiàn)了視頻解碼
    發(fā)表于 03-24 16:56

    基于ART-Pi與SX1302的設計資料分享

    1、基于 ART-Pi lora-pkt-sniffer 抓包工具抓取空口 LoRa 數(shù)據(jù)包 8 個并行的 LoRa BW125KHz 通道 支持 CRC 過濾機制 串口 shell 支持參數(shù)讀寫
    發(fā)表于 04-01 16:36

    ART-PI在MDK中使用SDIO設備的方法

    一、ENV使能SDIO1.1.在kconfig增加配置因為ART-PI的SDIO2連接的是wifi,所以這里我們使用SDIO1。1.2.ENV中使能SDIO1.3.使能文件系統(tǒng)1.4.使用SD設備
    發(fā)表于 04-11 10:07

    如何才能在art-pi上運行fdcan?

    大家好,art-pi板上運行CAN2.0沒問題,收發(fā)自如,若想運行canfd,是不是需要對drv_fdcan.c做修改?比如一些參數(shù)配置等
    發(fā)表于 04-21 09:27

    關于ART-PI的基本使用例程簡單描述

    ,使用靜態(tài)IP與PC直連做測試。后續(xù)有需要,將ARI-PI通過路由器連接PC,可以隨時再打開DHCP。5.保存Setting,編譯,成功。2 基本測試1.將ART-PI通電并連接網(wǎng)線2.通過設備管理
    發(fā)表于 06-01 15:06

    ART-PI嵌入式人形檢測設計資料實現(xiàn)

    1、ART-PI嵌入式人形檢測設計實現(xiàn)硬件平臺 ART-Pi, 50M FLOPS。我的模型(刪減后的模型)最終部署在板子上是推理時間是56ms,不包括數(shù)據(jù)處理時間。$ pip
    發(fā)表于 08-25 15:33

    ART-Pi LoRa開發(fā)套件教程相關資料分享

    1、ART-Pi LoRa 開發(fā)套件簡介  ART-Pi LoRa 開發(fā)套件(LSD4RFB-2EVKM0201)是利爾達科技與睿賽德科技聯(lián)合出品的一套面向物聯(lián)網(wǎng)開發(fā)者的 LoRa產(chǎn)品原型設計工
    發(fā)表于 09-30 11:57

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

    大家好,art-pi板上運行CAN2.0沒問題,收發(fā)自如,若想運行canfd,是不是需要對drv_fdcan.c做修改?比如一些參數(shù)配置等。
    發(fā)表于 02-08 11:40

    【STM32H750】玩轉(zhuǎn)ART-Pi(一)——使用STM32CUBMX生成TouchGFX工程

    目錄在ART-Pi H750上移植TouchGFX(一)——使用STM32CUBMX生成TouchGFX工程在ART-Pi H750上移植TouchGFX(二)——制作MDK的外部
    發(fā)表于 12-28 19:20 ?10次下載
    【STM32H750】玩轉(zhuǎn)<b class='flag-5'>ART-Pi</b>(一)——使用STM32CUBMX生成TouchGFX工程

    【技術三千問】之《玩轉(zhuǎn)ART-Pi》,看這篇就夠了!

    2.在 ART-Pi 平臺有沒有人成功使用 openocd 可以直接燒寫到外部 Quad spi flash 的?[鏈接]
    發(fā)表于 01-25 18:44 ?2次下載
    【技術三千問】之《玩轉(zhuǎn)<b class='flag-5'>ART-Pi</b>》,看這篇就夠了!

    ART-PI重力感應無線智能小車第一彈——ART-PI擴展板設計

    雷德斯 and 枕頭們,小飛哥好久沒更新文章啦,最近實在是太忙啦,大家久等啦,這次是系列文章,一步步教你如何在ART-PI上實現(xiàn)無線重力感...
    發(fā)表于 01-25 19:27 ?1次下載
    <b class='flag-5'>ART-PI</b>重力感應無線智能小車第一彈——<b class='flag-5'>ART-PI</b>擴展板設計