飞思卡尔MC9S12X:CAN初始化配置
飞思卡尔MC9S12X:CAN发送配置
飞思卡尔MC9S12X:CAN接收配置
飞思卡尔MC9S12X:CAN驱动函数在主函数中的应用
一、MSCAN接收流程
- 检测接收标志:此处用到CANRFLG寄存器。
- 检测帧模式(标准帧/扩展帧):此处用到CANIDR寄存器。
- 读标识符:此处用到CANIDR寄存器。
- 判断帧格式(远程帧/数据帧):此处用到CANIDR寄存器。
- 读取数据长度:此处用到CANDLR寄存器。
- 读取数据:此处用到CANDSR寄存器。
- 清除接收标志位:此处用到CANTFLG寄存器。
二、MSCAN接收寄存器介绍
CANIDR寄存器有两种型式:标准帧型式和扩展帧型式。
标准帧型式:
扩展帧型式:
三、CAN接收配置具体程序实现
1.标准帧程序
具体代码如下:
struct can_msg //报文的结构体
{
unsigned int id; //帧ID
unsigned char RTR; // RTR: 1为远程帧,0为数据帧
unsigned char data[8]; //帧数据
unsigned char len; //数据长度
unsigned char prty; //优先级
};
/*************************************************************/
/* CAN0接收 */
/*************************************************************/
int MSCAN0_Receive(struct can_msg *msg)
{
unsigned char sp2;
// 检测接收标志
if(!(CAN0RFLG_RXF))
return(FALSE);
// 检测 CAN协议报文模式 (一般/扩展) 标识符
if(CAN0RXIDR1_IDE) //0为标准格式,1为扩展格式
// IDE = Recessive (Extended Mode)
return(FALSE);
// 读标识符
msg.id = (unsigned int)(CAN0RXIDR0<<3) |
(unsigned char)(CAN0RXIDR1>>5);
if(CAN0RXIDR1&0x10)
msg.RTR = TRUE;
else
msg.RTR = FALSE;
// 读取数据长度
msg.len = CAN0RXDLR;
// 读取数据
for(sp2 = 0; sp2 < msg.len; sp2++)
msg.data[sp2] = *((&CAN0RXDSR0)+sp2);
// 清 RXF 标志位 (缓冲器准备接收)
CAN0RFLG = 0x01;
return(TRUE);
}
2.扩展帧程序
具体代码如下:
struct can_msg //报文的结构体
{
unsigned long ID; //帧ID
unsigned char RTR; // RTR: 1为远程帧,0为数据帧
unsigned char data[8]; //帧数据
unsigned char len; //数据长度
unsigned char prty; //优先级
};
/*************************************************************/
/* CAN0接收 */
/*************************************************************/
int MSCAN0_Receive(struct can_msg *msg)
{
unsigned char sp2;
// 检测接收标志
if(!(CAN0RFLG_RXF))
return(FALSE);
// 检测 CAN协议报文模式 (一般/扩展) 标识符
if(!CAN0RXIDR1_IDE) //0为标准格式,1为扩展格式
// IDE = Recessive (Extended Mode)
return(FALSE);
// 读标识符
msg.ID = ((unsigned long)(CAN1RXIDR0&0xff))<<21;
msg.ID = can1_msg_get.ID & ((unsigned long)0xff<<21);
msg.ID = can1_msg_get.ID | (((unsigned long)(CAN1RXIDR1&0xe0))<<13);
msg.ID = can1_msg_get.ID | (((unsigned long)(CAN1RXIDR1&0x07))<<15);
msg.ID = can1_msg_get.ID | (((unsigned long)(CAN1RXIDR2&0xff))<<7);
msg.ID = can1_msg_get.ID | (((unsigned long)(CAN1RXIDR3&0xfe))>>1);
if(CAN0RXIDR3&0x01)
msg.RTR = TRUE;
else
msg.RTR = FALSE;
// 读取数据长度
msg.len = CAN0RXDLR;
// 读取数据
for(sp2 = 0; sp2 < msg.len; sp2++)
msg.data[sp2] = *((&CAN0RXDSR0)+sp2);
// 清 RXF 标志位 (缓冲器准备接收)
CAN0RFLG = 0x01;
return(TRUE);
}