?? can.c
字號(hào):
/****************************************************************/
/* 項(xiàng)目名稱(chēng) : R8C/23 CAN/LIN Demo Board */
/* : 樣例程序2 */
/* : CAN收發(fā) */
/* 硬件環(huán)境 : R0K521237C000BB */
/* MCU型號(hào) : R5F21237JFP */
/* C編譯器 : NC30WA,版本5.30.r02及以上 */
/* 文件名 : CAN.c */
/* 版本 : 1.0 */
/* 作者 : wangsy */
/* 修訂歷史 : */
/* 修訂者 時(shí)間 版本 說(shuō)明 */
/* wangsy 2006/9/11 1.0 初版發(fā)行 */
/* */
/****************************************************************/
/* Copyright, 2006 RENESAS TECHNOLOGY CORPORATION & */
/* RENESAS SOLUTIONS CORPORATION */
/****************************************************************/
/*------------包含的頭文件--------------*/
#include "..\inc\Comdef_r823.h"
#include "..\inc\CAN.h"
/*-------------變量定義-----------------*/
// CAN 接受幀
can_std_data_def ReceiveData = {0x00U, 0x08, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
// CAN 發(fā)送幀
can_std_data_def TransmitData = {SND_FRM_ID, 0x08, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
uchar8 ucFlag_CAN0_RE = NO; // CAN接收,事件觸發(fā)標(biāo)志
uchar8 re_slot = RCV_SLOT; // 接收信箱
uchar8 tr_slot = SND_SLOT; // 發(fā)送信箱
/*-------------函數(shù)聲明-----------------*/
void config_can0(void); // CAN0初始設(shè)置
void can0_receive(void); // CAN0接收入口函數(shù)
void can0_transmit(void); // CAN0發(fā)送入口函數(shù)
void set_bitrate_can0(void); // CAN0波特率設(shè)置
// 移位(左移)函數(shù) MISRA中不允許移位的位數(shù)為變量
uint16 left_shift(uint16 oprnd_obj, uchar8 left_bit);
// 設(shè)置CAN0標(biāo)準(zhǔn)數(shù)據(jù)幀的發(fā)送
void set_trm_std_dataframe_can0(uchar8 in_slot, can_std_data_def * in_trm_data);
// 設(shè)置CAN0標(biāo)準(zhǔn)數(shù)據(jù)幀的接收
void set_rcv_std_dataframe_can0(uchar8 in_slot, uint16 in_sid);
/*-----------中斷處理函數(shù)---------------*/
void int_can0_receive(void);
/*------------函數(shù)定義------------------*/
/*------------------------------------------------------
名稱(chēng) : config_can0
功能 : CAN0初始設(shè)置
入口 : 無(wú)
出口 : 無(wú)
調(diào)用 : 調(diào)用void set_bitrate_can0(void)
寄存器 : c0ctlr, c0str,c0recic,c0gmr,c0lmar,c0lmbr
------------------------------------------------------*/
void config_can0(void)
{
// canI/O 設(shè)置
pd6_1 = 1;
pd6_2 = 0;
c0ctlr_addr.b.reset = 1; // 進(jìn)入初始化模式
c0ctlr_addr.b.sleep = 0; // 結(jié)束休眠模式
while(c0str_addr.b.state_reset == 0) // 等待處理器進(jìn)入初始化模式
{
}
c0ctlr_addr.b.porten = 1; // CAN端口使能
c0ctlr_addr.b.loopback = 0; // 不采用自環(huán)模式
c0ctlr_addr.b.msgorder = 1; // 消息順序:字節(jié)訪問(wèn)
c0ctlr_addr.b.basiccan = 0; // 不采用Basic CAN模式
c0ctlr_addr.b.buserren = 0; // 禁止總線錯(cuò)誤中斷
c0ctlr_addr.b.tsprescale = 0; // 時(shí)間戳預(yù)分頻器:"period of 1bit time"
set_bitrate_can0(); // 調(diào)用比特率設(shè)置函數(shù)
c0ctlr_addr.b.reset = 0; // 跳出初始化模式
while(c0str_addr.b.state_reset != 0) // 確認(rèn)跳出初始化模式
{
}
c0recic_addr.byte = CAN0_RCV_PRIORITY; // CAN0接收中斷優(yōu)先級(jí)5
//設(shè)置屏蔽寄存器為可以接收所有的ID
c0gmr.ba.sidh = 0x0;
c0gmr.ba.sidl = 0x0;
c0lmar.ba.sidh = 0x0;
c0lmar.ba.sidl= 0x0;
c0lmbr.ba.sidh = 0x0;
c0lmbr.ba.sidl= 0x0;
}
/*------------------------------------------------------
名稱(chēng) : set_bitrate_can0
功能 : CAN0波特率設(shè)置
入口 : 無(wú)
出口 : 無(wú)
調(diào)用 : 無(wú)
寄存器 : prc0,cclkr,c0conr
------------------------------------------------------*/
void set_bitrate_can0(void)
{
// clock = 20MHz
prc0 = 1; // 打開(kāi)保護(hù)寄存器
cclkr &= ~(uchar8)0x00; // 清零 CAN0 時(shí)鐘寄存器
prc0 = 0; // 關(guān)閉保護(hù)寄存器
c0conr_addr.b.brp = CAN0_BRP - 1U; // CAN 時(shí)鐘預(yù)分頻器 = 10 125kbps
// 設(shè)置位時(shí)序
c0conr_addr.b.sam = BT_SAM - 1U; // SS = 1 Tq
c0conr_addr.b.pts = BT_PTS - 1U; // PTS = 1 Tq
c0conr_addr.b.pbs1 = BT_PBS1 - 1U; // PBS1 = 3 Tq
c0conr_addr.b.pbs2 = BT_PBS2 - 1U; // PBS2 = 3 Tq
c0conr_addr.b.sjw = BT_SJW - 1U; // SJW = 1 Tq
}
/*------------------------------------------------------
名稱(chēng) : left_shift
功能 : 移位(左移)函數(shù)
入口 : 要求左移的位數(shù)
出口 : 被移位的變量
調(diào)用 : 無(wú)
寄存器 : 無(wú)
------------------------------------------------------*/
uint16 left_shift(uint16 oprnd_obj, uchar8 left_bit)
{
switch(left_bit)
{
case 0:
break;
case 1:
oprnd_obj = oprnd_obj << 1;
break;
case 2:
oprnd_obj = oprnd_obj << 2;
break;
case 3:
oprnd_obj = oprnd_obj << 3;
break;
case 4:
oprnd_obj = oprnd_obj << 4;
break;
case 5:
oprnd_obj = oprnd_obj << 5;
break;
case 6:
oprnd_obj = oprnd_obj << 6;
break;
case 7:
oprnd_obj = oprnd_obj << 7;
break;
case 8:
oprnd_obj = oprnd_obj << 8;
break;
case 9:
oprnd_obj = oprnd_obj << 9;
break;
case 0x0a:
oprnd_obj = oprnd_obj << 0x0a;
break;
case 0x0b:
oprnd_obj = oprnd_obj << 0x0b;
break;
case 0x0c:
oprnd_obj = oprnd_obj << 0x0c;
break;
case 0x0d:
oprnd_obj = oprnd_obj << 0x0d;
break;
case 0x0e:
oprnd_obj = oprnd_obj << 0x0e;
break;
case 0x0f:
oprnd_obj = oprnd_obj << 0x0f;
break;
default:
break;
}
// 將移位完的操作數(shù)返回
return(oprnd_obj);
}
/*------------------------------------------------------
名稱(chēng) : set_trm_std_dataframe_can0
功能 : 設(shè)置CAN0標(biāo)準(zhǔn)數(shù)據(jù)幀的發(fā)送
入口 : in_slot: 信箱號(hào)
*in_trm_data:發(fā)送數(shù)據(jù)幀的地址
出口 : 無(wú)
調(diào)用 : uint16 left_shift(uint16 oprnd_obj, uchar8 left_bit)
寄存器 : c0mctl,c0icr,c0idr,c0slot
------------------------------------------------------*/
void set_trm_std_dataframe_can0(uchar8 in_slot, can_std_data_def *in_trm_data)
{
uchar8 LoopCounter;
uint16 temp;
// 確認(rèn)可以發(fā)送
while(c0mctl[in_slot].transmit.trmactive == 1)
{
}
// 清零CAN0消息控制寄存器
while(c0mctl[in_slot].byte != 0x00)
{
c0mctl[in_slot].byte = 0x00;
}
// 對(duì)應(yīng)信箱,CAN0中斷控制寄存器禁止
temp = c0icr_addr.word + 0U;
temp &= (~(left_shift((uint16)0x0001, in_slot)));
c0icr_addr.word = (int16)temp;
// 對(duì)應(yīng)信箱,CAN0采用標(biāo)準(zhǔn)ID
temp = c0idr_addr.word + 0U;
temp &= ~(left_shift((uint16)0x0001, in_slot));
c0idr_addr.word = (int16)temp;
c0slot[in_slot].ba.sidh = (uchar8)(((in_trm_data->id)>> 6U) & 0x1FU); // 設(shè)置SID10-6
c0slot[in_slot].ba.sidl = (uchar8)((in_trm_data->id) & 0x3FU); // 設(shè)置SID5-0
c0slot[in_slot].ba.dlc = in_trm_data->dlc; // 設(shè)置DLC
// 將發(fā)送數(shù)據(jù)放入CAN0發(fā)送信箱
for(LoopCounter=0; (LoopCounter<(in_trm_data->dlc))&&(LoopCounter<8); ++LoopCounter)
{
c0slot[in_slot].ba.data[LoopCounter] = in_trm_data->data[LoopCounter];
}
// 啟動(dòng)標(biāo)準(zhǔn)數(shù)據(jù)幀的發(fā)送
c0mctl[in_slot].byte = 0x80;
}
/*------------------------------------------------------
名稱(chēng) : can0_receive
功能 : CAN0接收
入口 : 無(wú)
出口 : 無(wú)
調(diào)用 : void set_rcv_std_dataframe_can0(uchar8 in_slot, uint16 in_sid)
寄存器 : 無(wú)
------------------------------------------------------*/
void can0_receive(void)
{
// 調(diào)用CAN0標(biāo)準(zhǔn)數(shù)據(jù)幀的接收設(shè)置
set_rcv_std_dataframe_can0(re_slot, ReceiveData.id);
}
/*------------------------------------------------------
名稱(chēng) : set_rcv_std_dataframe_can0
功能 : 設(shè)置CAN0標(biāo)準(zhǔn)數(shù)據(jù)幀的接收
入口 : in_slot: 信箱號(hào)
in_sid: 接收SID
出口 : 無(wú)
調(diào)用 : uint16 left_shift(uint16 oprnd_obj, uchar8 left_bit)
寄存器 : c0mctl,c0icr,c0idr,c0slot
------------------------------------------------------*/
void set_rcv_std_dataframe_can0(uchar8 in_slot, uint16 in_sid)
{
uint16 temp;
// 清零CAN0消息控制寄存器
while(c0mctl[in_slot].byte != 0x00)
{
c0mctl[in_slot].byte = 0x00;
}
// 對(duì)應(yīng)信箱,CAN0中斷控制寄存器允許
temp = c0icr_addr.word + 0U;
temp |= left_shift((uint16)0x0001, in_slot);
c0icr_addr.word = (int16)temp;
// 對(duì)應(yīng)信箱,CAN0采用標(biāo)準(zhǔn)ID
temp = c0idr_addr.word + 0U;
temp &= ~(left_shift((uint16)0x0001, in_slot));
c0idr_addr.word = (int16)temp;
c0slot[in_slot].ba.sidh = (uchar8)((in_sid>> 6U) & 0x1FU); // 設(shè)置 SID10-6
c0slot[in_slot].ba.sidl = (uchar8)(in_sid & 0x3FU); // 設(shè)置 SID5-0
// 啟動(dòng)CAN0標(biāo)準(zhǔn)數(shù)據(jù)幀的接收
c0mctl[in_slot].byte = 0x40;
}
/*------------------------------------------------------
名稱(chēng) : can0_transmit
功能 : CAN0發(fā)送
入口 : 無(wú)
出口 : 無(wú)
調(diào)用 : void set_trm_std_dataframe_can0(uchar8 in_slot, can_std_data_def * in_trm_data)
寄存器 : 無(wú)
------------------------------------------------------*/
void can0_transmit(void)
{
set_trm_std_dataframe_can0(tr_slot, &TransmitData);
}
/*------------------------------------------------------
名稱(chēng) : int_can0_receive
功能 : 中斷處理函數(shù):CAN0接收
入口 : 無(wú)
出口 : 無(wú)
調(diào)用 : 無(wú)
寄存器 : c0mctl,c0slot
------------------------------------------------------*/
#pragma INTERRUPT int_can0_receive
void int_can0_receive(void)
{
uchar8 lp_dlc;
// 當(dāng)發(fā)生中斷時(shí),將CAN0接收事件觸發(fā)標(biāo)志置為YES
ucFlag_CAN0_RE = YES;
// 確認(rèn)新的數(shù)據(jù)來(lái)到
while(c0mctl [re_slot].receive.newdata != 1)
{
}
// 等待直到消息有效
while(c0mctl[re_slot].receive.invaldata == 1)
{
}
// 清零
c0mctl[re_slot].receive.newdata = 0;
// 檢查過(guò)載錯(cuò)誤
if(c0mctl[re_slot].receive.msglost == 1)
{
c0mctl[re_slot].receive.msglost = 0;
// 當(dāng)發(fā)生過(guò)載錯(cuò)誤時(shí)的用戶(hù)處理程序(略)
}
else
{
}
// 讀出消息
ReceiveData.id = ((uint16)c0slot[re_slot].ba.sidh << 6) + c0slot[re_slot].ba.sidl;
ReceiveData.dlc = c0slot[re_slot].ba.dlc;
for(lp_dlc=0; lp_dlc<c0slot[re_slot].ba.dlc; ++lp_dlc)
{
ReceiveData.data[lp_dlc] = c0slot[re_slot].ba.data[lp_dlc];
}
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -