寻求使用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
回复
| 有奖活动 | |
|---|---|
| 硬核工程师专属补给计划——填盲盒 | |
| “我踩过的那些坑”主题活动——第002期 | |
| 【EEPW电子工程师创研计划】技术变现通道已开启~ | |
| 发原创文章 【每月瓜分千元赏金 凭实力攒钱买好礼~】 | |
| 【EEPW在线】E起听工程师的声音! | |
| 高校联络员开始招募啦!有惊喜!! | |
| 【工程师专属福利】每天30秒,积分轻松拿!EEPW宠粉打卡计划启动! | |
| 送您一块开发板,2025年“我要开发板活动”又开始了! | |
			
			
			
						
			
 我要赚赏金
