寻求使用M16C29族的朋友
现在我使用RSKM16C/29开发板做个CAN通信的测试程序,由这个板子发送CAN数据,通过中断自收,但是总是进不了中断,我反复查看和CAN模块相关的寄存器配置,觉得也没有什么问题,有没有高手或者瑞萨工程师给指点一下,谢谢!小弟在线等!
基本的配置源程序如下:
/*
**********************************************************************
函数声明 :void can_initial(void)
功能 :对CAN0控制器模块进行初始化配置
函数调用 :config_can0()
: set_rec_std_dataframe_can0
输入参数 :无
输出参数 :无
**********************************************************************
*/
void can_initial(void)
{
config_can0(); //配置 CAN 模块
c0recic = CAN0_LVL; //CAN 模块接收结束中断
set_rec_std_dataframe_can0(14); //Set can slot14
trm_data[0].id = 0x10;
trm_data[0].dlc = 1;
trm_data[0].data[0] = 1;
trm_data[1].id = 0x11;
trm_data[1].dlc = 1;
trm_data[1].data[0] = 2;
}
/*
**********************************************************************
函数声明 :void set_rec_std_dataframe_can0(UINT16 in_slot)
功能 :对CAN0控制器模块接收槽进行配置
函数调用 :无
输入参数 :in_slot,接收槽的号;
输出参数 :无
**********************************************************************
*/
void set_rec_std_dataframe_can0(UINT16 in_slot)
{
while(c0mctl[in_slot].byte != 0x00){ /* 确认CAN0消息控制寄存器 */
c0mctl[in_slot].byte = 0x00; /* 清零CAN0消息控制寄存器 */
}
c0icr |= (0x0001<<in_slot); /* 设定CAN0的中断控制寄存器 */
c0idr &= ~(0x0001<<in_slot); /* 设定CAN0的扩展ID寄存器 */
c0mctl[in_slot].byte = 0x40; /* 设定数据桢的接收模式 */
}
/*
**********************************************************************
函数声明 :void set_bitrate_can0(void)
功能 :设置波特率
函数调用 :无
输入参数 :无
输出参数 :无
**********************************************************************
*/
void set_bitrate_can0(void)
{
prc0 = 1; /* CAN 时钟选择寄存器写入允许 */
cclkr = 0x01; /* CAN0 clock = f1/2 */
prc0 = 0; /* CAN 时钟选择寄存器写入禁止 */
/* 500kbps 10Tq */
brp_c0conr = 0; /* fcan(10MHz) */
sam_c0conr = 0; /* 一次采样 */
pts_c0conr = 2; // PTS = 3Tq
pbs1_c0conr = 2; // PBS1 = 3 Tq
pbs2_c0conr = 2; // PBS2 = 3 Tq
sjw_c0conr = 0; // SJW = 1 Tq
}
/*
**********************************************************************
函数声明 :void config_can0()
功能 :设置CAN控制器寄存器
函数调用 :set_bitrate_can0()
:set_mask_can0()
输入参数 :无
输出参数 :无
**********************************************************************
*/
void config_can0(void)
{
reset_c0ctlr = 1; /* 进入复位初始化模式 */
sleep_c0ctlr = 0; /* 解除 CAN 睡眠模式 */
while(! state_reset_c0str){} /* 确认复位状态 */
porten_c0ctlr = 1; /* CAN 端口允许 */
loopback_c0ctlr = 1; /* 回送模式有效 */
msgorder_c0ctlr = 1; /* 字节存取 */
basiccan_c0ctlr = 1; /* BasicCAN 模式有效 */
buserren_c0ctlr = 0; /* 禁止总线错误中断 */
tsprescale_c0ctlr = 0;
set_bitrate_can0(); /* 设置波特率 */
set_mask_can0(); /* 设置屏蔽寄存器 */
reset_c0ctlr = 0; /* 进入工作模式 */
while(state_reset_c0str){} /* 确认工作模式 */
}
/*
**********************************************************************
函数声明 :void set_mask_can0(void)
功能 :设置CAN控制器的屏蔽控制寄存器
函数调用 :无
输入参数 :无
输出参数 :无
**********************************************************************
*/
void set_mask_can0(void)
{
/* MASK_14 = 0x00 */
c0lmar.ba.sidh = (MASK_14>>6) & 0x1f; //SID10-6
c0lmar.ba.sidl = MASK_14 & 0x3f; //SID5-0
}
/*
**********************************************************************
函数声明 :void get_message_can0
(UINT16 in_slot, can_std_data_def *in_rec_data)
功能 :取CAN数据桢
函数调用 :无
输入参数 :in_slot,接收槽号
:in_rec_data,接收数据指针
输出参数 :无
**********************************************************************
*/
void get_message_can0( UINT16 in_slot, can_std_data_def *in_rec_data)
{
UINT8 lp_dlc;
while(1)
{
while(c0mctl[in_slot].receive.invaldata){} /* 查看接收是否结束*/
c0mctl[in_slot].receive.newdata = 0;/* 清零接收结束标志 */
if(c0mctl[in_slot].receive.msglost)
{ /* 查看是否过载错误 */
c0mctl[in_slot].receive.msglost = 0;
error_fnc(CAN_RCV_BUFF_ERROR);
break;
}
/* 读出接收到的消息 */
in_rec_data->id = ((UINT16)c0slot[in_slot].ba.sidh<<6)
+ c0slot[in_slot].ba.sidl;
in_rec_data->dlc = c0slot[in_slot].ba.dlc;
for(lp_dlc=0; lp_dlc<c0slot[in_slot].ba.dlc; ++lp_dlc)
{
in_rec_data->data[lp_dlc] = c0slot[in_slot].ba.data[lp_dlc];
}
/* 查看在读出接收消息的过程中是否又接收到了新的消息 */
if(! c0mctl[in_slot].receive.newdata)
{
break;
}
}
}
/*
**********************************************************************
函数声明 :void trm_can_data
(UINT16 in_slot, can_std_data_def *in_trm_data)
功能 :设置CAN槽的发送
函数调用 :无
输入参数 :in_slot,槽号
:in_trm_data,发送数据指针
输出参数 :无
**********************************************************************
*/
void trm_can_data( UINT16 in_slot, can_std_data_def *in_trm_data)
{
UINT8 lp_dlc;
while(c0mctl[in_slot].transmit.trmactive){}
while(c0mctl[in_slot].byte != 0x00){
c0mctl[in_slot].byte = 0x00;
}
/* transmission */
c0icr &= ~(0x0001 << in_slot);
c0idr &= ~(0x0001 << in_slot);
//------------- set dataframe ----------------
c0slot[in_slot].ba.sidh = ((in_trm_data->id)>>6) & 0x1f;
//SID10-6
c0slot[in_slot].ba.sidl = (in_trm_data->id) & 0x3f;
//SID5-0
c0slot[in_slot].ba.dlc = in_trm_data->dlc; //DLC
for(lp_dlc = 0;lp_dlc<(in_trm_data->dlc) && (lp_dlc<8) ; lp_dlc++){
c0slot[in_slot].ba.data[lp_dlc] = in_trm_data->data[lp_dlc];
//Data
}
//-------------------------------------------------
c0mctl[in_slot].byte = 0x80;
}
通过中断接收的,接收中断函数,我是通过修改文件intprg.c中的can接收中断服务函数,源程序如下:
#pragma interrupt _can0_receive(vect=2)
void _can0_receive(void)
{
if(c0mctl[14].receive.newdata == 1){
get_message_can0(14, &rec_data[0]); //Read receive data
if((rec_data[i].id = trm_data[i].id)&&(rec_data[i].dlc = trm_data[i].dlc)&&(rec_data[i].data[0] = trm_data[i].data[0]))
{
LED0Flash(5, 5000); //LED0闪烁
SET_LED0(); //熄灭LED0
}
else
{
LED2Flash(5, 5000);
SET_LED2();
}
}
}
http://cn.renesas.com/fmwk.jsp?cnt=can_app_child.htm&fp=/product_catalog/child_folder/&title=CAN %E5%BA%94%E7%94%A8%E8%AF%B4%E6%98%8E
回复
有奖活动 | |
---|---|
【有奖活动——B站互动赢积分】活动开启啦! | |
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |