一.準(zhǔn)備
基于RT-Thread Studio
1.1安裝BSP包
注意GNU工具鏈版本
1.2 芯片資料
1.3FSP
1.4代碼倉庫
1.5創(chuàng)建工程
菜單欄
文件->新建->RT-Thread項目
設(shè)置如下
接上串口P205 P206
115200-8-N-1
TP5設(shè)置了一個測試點,可以測試Vref的VDD/2的電壓,輔助確認(rèn)芯片是否正常。
R76 R77構(gòu)成了120歐終端電阻,C67起到濾波作用,這個電容不能大,否則影響高速時信號邊沿,導(dǎo)致邊沿變遲緩可能導(dǎo)致采樣錯誤。
RS用于Slope-Control控制輸入,默認(rèn)接GND即High-Speed模式。
三.CAN模塊介紹
參考《Renesas RA6M3 Group User’s Manual: Hardware》的《37. Controller Area Network (CAN) Module》
3.1特征
支持ISO11898-1 標(biāo)準(zhǔn)和擴展幀
支持最高1 Mbps
32個消息郵箱:每一個都可以獨立配置為接收或發(fā)送;或者24個配置為接受或發(fā)送,剩余的8個配置為4級收發(fā)FIFO。
支持?jǐn)?shù)據(jù)幀和遠程幀接收,可配置只接收標(biāo)準(zhǔn)幀或者擴展幀或者混合幀,可配置單次接收模式,可配置溢出時數(shù)據(jù)是保存還是丟棄,每個郵箱可單獨配置接收完成中斷使能。
4個郵箱共用一個,一共8個接收過濾器,每個郵箱可單獨使能過濾。
支持?jǐn)?shù)據(jù)幀和遠程幀發(fā)送,可配置只發(fā)送標(biāo)準(zhǔn)幀或者擴展幀或者混合幀,可配置單次發(fā)送模式,廣播功能,優(yōu)先級可由ID或者郵箱序號決定,支持發(fā)送中止且有中止完成標(biāo)志,每個郵箱可單獨配置接發(fā)送成中斷使能。
從總線斷開狀態(tài)恢復(fù)的模式轉(zhuǎn)換可選擇為:1.符合ISO11898-1規(guī)范2.總線斷開進入時自動進入CAN停止模式3.總線斷開完成時自動進入CAN停止模式4.通過軟件進入CAN停止模式5.通過軟件轉(zhuǎn)換到錯誤活動狀態(tài)。
?監(jiān)控CAN總線錯誤,包括填充錯誤、格式錯誤、ACK錯誤、15位CRC錯誤、位錯誤和ACK分隔符錯誤。檢測到錯誤狀態(tài)的轉(zhuǎn)換,包括錯誤警告、被動錯誤、總線關(guān)閉進入和總線關(guān)閉恢復(fù)。支持讀取錯誤計數(shù)器。
使用16位計數(shù)器的時間戳功能,可選擇1位、2位、4位和8位時間周期的參考時鐘
支持五種中斷源:接收完成、發(fā)送完成、接收FIFO、發(fā)送FIFO和錯誤中斷。
停止CAN時鐘以降低功耗。
三個軟件支持單元:接收過濾器;郵箱搜索支持,包括接收郵箱搜索、發(fā)送郵箱搜索和郵件丟失搜索;通道搜索支持。
時鐘源來自PCLKB 或 CANMCLK
可用于評估的三種測試模式:僅聽模式;自檢模式0(外部環(huán)回);自檢模式1(內(nèi)部環(huán)回)。
可以設(shè)置模塊停止?fàn)顟B(tài)以降低功耗.
3.2框圖
3.3操作模式
CAN模塊的操作模式包括:CAN復(fù)位模式,CAN停止模式,CAN操作模式,CAN睡眠模式。狀態(tài)切換如下圖:
3.4時序設(shè)置
時序設(shè)置很重要
時鐘源
CAN模塊有一個CAN時鐘發(fā)生器,可通過BCR寄存器中的CCLKS和BRP[9:0]位進行設(shè)置。圖顯示了CAN時鐘發(fā)生器的框圖
CCLKS選擇時鐘源來自與PCLKB還是EXTAL
BPR設(shè)置時鐘分頻最后得到fCANCLK
3.5時序設(shè)置
3.6中斷
四.CAN驅(qū)動介紹
4.1添加CAN驅(qū)動
按如下設(shè)置并保存,也可以使用env設(shè)置
添加的代碼位置如下
4.2使能硬件CAN
右鍵點擊工程,打開env環(huán)境
4.3測試代碼
CANboardSConscript下添加
if GetDepend(['RT_USING_CAN']):
src += Glob('ports/can_test.c')
刷新scons配置
添加的測試代碼如下
該代碼使用can0,創(chuàng)建接收線程接收can數(shù)據(jù),接收到后打印信息,同時導(dǎo)出命令can_sample,執(zhí)行一次命令發(fā)送一幀CAN數(shù)據(jù)。
五.回環(huán)測試
rt_device_open后添加一行,設(shè)置為回環(huán)模式
rt_device_control(can_dev,RT_CAN_CMD_SET_MODE,RT_CAN_MODE_LOOPBACK);
編譯運行,help可以看到對應(yīng)的命令can_sample
六.問題
can_sample can0
只能執(zhí)行一次
static rt_device_t can_dev = NULL;
設(shè)置只有未初始化才初始化
if(can_dev == NULL)
{
if (argc == 2)
{
rt_strncpy(can_name, argv[1], RT_NAME_MAX);
}
else
{
rt_strncpy(can_name, CAN_DEV_NAME, RT_NAME_MAX);
}
can_dev = rt_device_find(can_name);
if (!can_dev)
{
rt_kprintf("find %s failed!n", can_name);
return RT_ERROR;
}
rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
res = rt_device_open(can_dev, RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_INT_RX);
RT_ASSERT(res == RT_EOK);
rt_device_control(can_dev,RT_CAN_CMD_SET_MODE,RT_CAN_MODE_LOOPBACK);
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");
}
}
這樣就可以反復(fù)進行can_sample測試
七.CAN驅(qū)動分析
7.1測試代碼
boardportscan_test.c
見前面的測試
7.2硬件抽象層
librariesHAL_Driversdrv_can.c drv_can.h
導(dǎo)出了初始化函數(shù),啟動時自動根據(jù)鏈接腳本放置的位置調(diào)用該函數(shù)
INIT_BOARD_EXPORT(rt_hw_can_init);
通過接口
result = rt_hw_can_register(&can_obj[i].can_dev, can_obj[i].config->name, can_obj[i].can_dev.ops, RT_NULL);
注冊幾個關(guān)鍵的數(shù)據(jù)結(jié)構(gòu)
重點是如下結(jié)構(gòu)體,即操作底層硬件的接口,驅(qū)動層即通過注冊的該opt結(jié)構(gòu)進行底層硬件操作
const struct rt_can_ops ra_can_ops =
{
.configure = ra_can_configure,
.control = ra_can_control,
.sendmsg = ra_can_sendmsg,
.recvmsg = ra_can_recvmsg
};
librariesHAL_Driversconfigra2l1can_config.h中的
#if defined(BSP_USING_CAN0)
#ifndef CAN0_CONFIG
#define CAN0_CONFIG
{
.name = "can0",
.num_of_mailboxs = CAN_NO_OF_MAILBOXES_g_can0,
.p_api_ctrl = &g_can0_ctrl,
.p_cfg = &g_can0_cfg,
}
#endif /* CAN0_CONFIG /
#endif / BSP_USING_CAN0 */
則定義的芯片相關(guān)的操作數(shù)據(jù)結(jié)構(gòu)和設(shè)備名字。
7.3組件層
rt-threadcomponentsdriverscancan.c
導(dǎo)出了命令
MSH_CMD_EXPORT_ALIAS(cmd_canstat, canstat, stat can device status);
rt_hw_can_register注冊以下接口,即組件設(shè)備的驅(qū)動API
device- >init = rt_can_init;
device- >open = rt_can_open;
device- >close = rt_can_close;
device- >read = rt_can_read;
device- >write = rt_can_write;
device->control = rt_can_control;
7.4設(shè)備層
更通用的設(shè)備層通過設(shè)備名找到設(shè)備句柄
rt_device_find
設(shè)備打開等操作時rt_device_open通過設(shè)備句柄調(diào)用組件層的API,
rt_can_open等,而組件層調(diào)用硬件抽象層的接口,硬件抽象層再調(diào)用IC的固件庫實現(xiàn)硬件操作。
八.總結(jié)
得益于RT_Thread比較好的設(shè)備驅(qū)動框架,設(shè)備驅(qū)動的擴展非常方便,直接配置IC固件庫,實現(xiàn)硬件抽象層即可,組件層和設(shè)備層驅(qū)動都是通用的。
-
收發(fā)器
+關(guān)注
關(guān)注
10文章
3424瀏覽量
105961 -
PCB板
+關(guān)注
關(guān)注
27文章
1447瀏覽量
51610 -
CAN模塊
+關(guān)注
關(guān)注
0文章
24瀏覽量
8747 -
GNU
+關(guān)注
關(guān)注
0文章
143瀏覽量
17492 -
RT-Thread
+關(guān)注
關(guān)注
31文章
1285瀏覽量
40082 -
RA6M3
+關(guān)注
關(guān)注
0文章
52瀏覽量
110
發(fā)布評論請先 登錄
相關(guān)推薦
評論