MC9S12XEP100 CAN通信配置

MC9S12XEP100 CAN通信配置

CAN0配置

Snipaste_2021-09-17_16-31-42.jpg

结构体

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
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值