飞思卡尔MC9S12X:CAN发送配置

飞思卡尔MC9S12X:CAN初始化配置
飞思卡尔MC9S12X:CAN发送配置
飞思卡尔MC9S12X:CAN接收配置
飞思卡尔MC9S12X:CAN驱动函数在主函数中的应用


一、MSCAN发送流程

  1. 检查数据长度:超过8个就不发送了。
  2. 检查总线时钟:使用外部晶振时钟,此段可以省略。
  3. 寻找空闲缓冲器
  4. 写入标识符:此处用到CANIDR寄存器。
  5. 判断帧类型远程帧 /数据帧):此处用到CANIDR寄存器。
  6. 写入数据:此处用到CANDSR寄存器。
  7. 写入数据长度:此处用到CANDLR寄存器。
  8. 写入优先级:此处用到CANTBPR寄存器。
  9. 清除发送标志位 :此处用到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_Send(struct can_msg msg)
{
    
    
 unsigned char send_buf, sp;
  
  // 检查数据长度
  if(msg.len > 8)
    return(FALSE);

  // 检查总线时钟
  if(CAN0CTL0_SYNCH==0)
    return(FALSE);

  send_buf = 0;
  do
  {
    
    
    // 寻找空闲的缓冲器
    CAN0TBSEL=CAN0TFLG;
    send_buf=CAN0TBSEL;
  }
  while(!send_buf); 
  
  // 写入标识符
  CAN0TXIDR0 = (unsigned char)(msg.id>>3);
  CAN0TXIDR1 = (unsigned char)(msg.id<<5);
  
  // RTR: 1为远程帧,0为数据帧
  if(msg.RTR)
    CAN0TXIDR1 |= 0x10;
    
  // 写入数据
  for(sp = 0; sp < msg.len; sp++)
    *((&CAN0TXDSR0)+sp) = msg.data[sp];
    
  // 写入数据长度
  CAN0TXDLR = msg.len; 
  
  // 写入优先级
  CAN0TXTBPR = msg.prty;
  
  // 清 TXx 标志 (缓冲器准备发送)
  CAN0TFLG = send_buf;
  
  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_Send(struct can_msg msg)
{
    
    
 unsigned char send_buf, sp;
  
  // 检查数据长度
  if(msg.len > 8)
    return(FALSE);

  // 检查总线时钟
  if(CAN0CTL0_SYNCH==0)
    return(FALSE);

  send_buf = 0;
  do
  {
    
    
    // 寻找空闲的缓冲器
    CAN0TBSEL=CAN0TFLG;
    send_buf=CAN0TBSEL;
  }
  while(!send_buf); 
  
  // 写入标识符
  CAN0TXIDR0 = (unsigned char)(msg.ID>>21);
  CAN0TXIDR1 = (unsigned char)(msg.ID>>13)&0xE0;
  CAN0TXIDR1 |=0x18; 						//写替代远程请求位SRR和扩展帧标志位IDE
  CAN0TXIDR1 |=(unsigned char)(msg.ID>>15)&0x07;
  CAN0TXIDR2 = (unsigned char)(msg.ID>>7);
  CAN0TXIDR3 = (unsigned char)(msg.ID<<1);
    
  // RTR: 1为远程帧,0为数据帧
  if(msg.RTR)
    CAN0TXIDR3 |= 0x01;
    
  // 写入数据
  for(sp = 0; sp < msg.len; sp++)
    *((&CAN0TXDSR0)+sp) = msg.data[sp];
    
  // 写入数据长度
  CAN0TXDLR = msg.len; 
  
  // 写入优先级
  CAN0TXTBPR = msg.prty;
  
  // 清 TXx 标志 (缓冲器准备发送)
  CAN0TFLG = send_buf;
  
  return(TRUE);
}

点击下载,关于MSCAN寄存器的详细中文介绍

猜你喜欢

转载自blog.csdn.net/MQ0522/article/details/112763104