MC9S12XEP100 CAN通信配置
CAN0配置
结构体
typedef struct
{
UINT32 ID;
UINT8 DtLen;
UINT8 IDE;
UINT8 data[8];
} CanMsg_t;
CanMsg_t Rx0Msg,Rx4Msg;
初始化
void Init_Can0(void)
{
if(CAN0CTL0_INITRQ==0) // 查询是否进入初始化状态
CAN0CTL0_INITRQ =1;// 进入初始化状态
while (CAN0CTL1_INITAK==0); //等待进入初始化状态
CAN0BTR0_SJW = 0;//设置同步
CAN0BTR0_BRP = 3;//设置波特率3-250k,根据时钟按需配置
CAN0BTR1 = 0x1c; //设置时段1和时段2的Tq个数 ,总线频率为500k
// 关闭滤波器
CAN0IDMR0 = 0xFF;
CAN0IDMR1 = 0xFF;
CAN0IDMR2 = 0xFF;
CAN0IDMR3 = 0xFF;
CAN0IDMR4 = 0xFF;
CAN0IDMR5 = 0xFF;
CAN0IDMR6 = 0xFF;
CAN0IDMR7 = 0xFF;
CAN0CTL1 = 0xC0; //使能MSCAN模块,设置为一般运行模式、使用总线时钟源
CAN0CTL0 = 0x00; //返回一般模式运行
while(CAN0CTL1_INITAK); //等待回到一般运行模式
while(CAN0CTL0_SYNCH==0);//等待总线时钟同步
CAN0RIER_RXFIE = 1; //开接收中断
}
发送
unsigned char Can0SendMsg(CanMsg_t msg)
{
unsigned char send_buf, sp;
// 检查数据长度
if(msg.DtLen > 8)
return(FALSE);
// 检查总线时钟
if(CAN0CTL0_SYNCH==0)
return(FALSE);
send_buf = 0;
do
{
// 寻找空闲的缓冲器
CAN0TBSEL=CAN0TFLG;
send_buf=CAN0TBSEL;
}
while(!send_buf);
// 写入标识符
if(msg.IDE==0)
{
CAN0TXIDR0 = (unsigned char)(msg.ID>>3);
CAN0TXIDR1 = (unsigned char)(msg.ID<<5);
}
else
{
CAN0TXIDR0 = (unsigned char)(msg.ID>>21);
CAN0TXIDR1 = (unsigned char)(((msg.ID>>15)&0x07)|((msg.ID>>13)&0xE0)|0x18);
CAN0TXIDR2 = (unsigned char)(msg.ID>>7);
CAN0TXIDR3 = (unsigned char)(msg.ID<<1);
}
// 写入数据
for(sp = 0; sp < msg.DtLen; sp++)
*((&CAN0TXDSR0)+sp) = msg.data[sp];
// 写入数据长度
CAN0TXDLR = msg.DtLen;
// 清 TXx 标志 (缓冲器准备发送)
CAN0TFLG = send_buf;
return(TRUE);
}
接收
unsigned char Can0GetMsg(CanMsg_t *msg)
{
unsigned char sp0;
// 检测接收标志
if(CAN0RFLG_RXF==0){
return(FALSE);
}
// 检测 CAN协议报文模式 (一般/扩展) 标识符
if(!CAN0RXIDR1_IDE) //IDE = 0:标准ID ;1:扩展ID
msg->ID = ((((unsigned char)CAN0RXIDR0)<<8) + ((unsigned char)CAN0RXIDR1)) >> 5;
else
msg->ID = (unsigned long)((unsigned long)CAN0RXIDR0<<21)|(unsigned long)((((CAN0RXIDR1>>5)<<3)| ((unsigned long)(CAN0RXIDR1&0b00000111)))<<15)| (unsigned long)(CAN0RXIDR2<<7)|(CAN0RXIDR3>>1);
// 读取数据长度
msg->DtLen = CAN0RXDLR;
// 读取数据
for(sp0 = 0; sp0 < msg->DtLen; sp0++)
msg->data[sp0] = *((&CAN0RXDSR0)+sp0);
// 清 RXF 标志位 (缓冲器准备接收)
CAN0RFLG = 0x01;
return(TRUE);
}
中断
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt 38U Can0Rx(void)
{
if(Can0GetMsg(&Rx0Msg))
{
if(Rx0Msg.ID == 0x0000000)
{
}
}
}
#pragma CODE_SEG DEFAULT
CAN4
void Init_Can4(void)
{
MODRR_MODRR2 = 1;
MODRR_MODRR3 = 0;
if(CAN4CTL0_INITRQ==0) // 查询是否进入初始化状态
CAN4CTL0_INITRQ =1;// 进入初始化状态
while (CAN4CTL1_INITAK==0); //等待进入初始化状态
CAN4BTR0_SJW = 0;//设置同步
CAN4BTR0_BRP = 3;//设置波特率
CAN4BTR1 = 0x1c; //设置时段1和时段2的Tq个数 ,总线频率为0x5c->250kb/s ,0x25->500k
// 关闭滤波器
CAN4IDMR0 = 0xFF;
CAN4IDMR1 = 0xFF;
CAN4IDMR2 = 0xFF;
CAN4IDMR3 = 0xFF;
CAN4IDMR4 = 0xFF;
CAN4IDMR5 = 0xFF;
CAN4IDMR6 = 0xFF;
CAN4IDMR7 = 0xFF;
CAN4CTL1 = 0xC0; //使能MSCAN模块,设置为一般运行模式、使用总线时钟源
CAN4CTL0 = 0x00; //返回一般模式运行
while(CAN4CTL1_INITAK); //等待回到一般运行模式
while(CAN4CTL0_SYNCH==0);//等待总线时钟同步
CAN4RIER_RXFIE = 1; //开接收中断
}
发送接收
与CAN0类似
中断
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt 54U Can4Rx(void)// CAN_receive
{
if(Can4GetMsg(&Rx4Msg))
{
if(Rx4Msg.ID == 0x0000000000)
{
}
}
}
#pragma CODE_SEG DEFAULT