hhdsgw 2022-01-04 16:37 采纳率: 0%
浏览 51
已结题

单片机 CAN通讯 帮我看看这段代码是什么意思

这是飞思卡尔S12系列单片机的CAN模块程序,CAN.c 和CAN.h文件。 想请教下 程序是怎么接收CAN报文并读出来的啊?里面有些参数我不明白放那的意义是什么

CAN.h文件

#ifndef  CAN0_H
#define  CAN0_H


#define Command             1
#define SRecord             0

typedef unsigned char byte;
typedef unsigned int word;
typedef unsigned long dword;
typedef unsigned long dlong[2];
#pragma MESSAGE DISABLE C1106 /* WARNING C1106: Non-standard bitfield type */


typedef struct 
{
  UINT8 Extended;

  UINT8 Length;

  UINT32 ID;

  UINT8 TXTBPR;

  UINT8 DATA[8];
} CAN0_DATATYPE;

typedef union {
    byte Byte;
    struct {
      byte data0         :1;                                        
      byte data1         :1;                                       
      byte data2         :1;                                       
      byte data3         :1;
      byte data4         :1;                                        
      byte data5         :1;                                       
      byte data6         :1;                                        
      byte data7         :1;                                       
    } Bits;                                
} Str_Can_Send_State;

extern Str_Can_Send_State   State[8];
#define Bootloader_version_number                 State[0].Byte
#define Have_Program_SRec_numbers                 State[1].Byte
#define Reserve2                                  State[2].Byte
#define Reserve3                                  State[3].Byte
#define Reserve4                                  State[4].Byte
#define Reserve5                                  State[5].Byte
#define Program_state                             State[6].Byte
  #define Program_Successfully                    State[6].Bits.data0
  #define SRecord_CheckSum_error                  State[6].Bits.data1
  #define SRecord_Invalid_address                 State[6].Bits.data2
  #define Program_reset_vector_error              State[6].Bits.data3
  #define SRec_Range_error                        State[6].Bits.data4
  #define Reserve11                               State[6].Bits.data5
  #define Reserve12                               State[6].Bits.data6
  #define Reserve13                               State[6].Bits.data7
#define EraseFlash_state                          State[7].Byte
  #define Get_Ready_to_erase_block0               State[7].Bits.data0
  #define Get_Ready_to_erase_block1N              State[7].Bits.data1
  #define Get_Ready_to_erase_block1S              State[7].Bits.data2
  #define Get_Ready_to_erase_block2               State[7].Bits.data3
  #define Get_Ready_to_erase_block3               State[7].Bits.data4
  #define Erase_Successfully                      State[7].Bits.data5
  #define Reserve20                               State[7].Bits.data6
  #define Reserve21                               State[7].Bits.data7
                                              



 
#pragma CODE_SEG RAM_CODE
extern interrupt void MSCAN0_Receive_ISR(void);
extern interrupt void MSCAN0_Transmit_ISR(void);
#pragma CODE_SEG DEFAULT

extern void CAN_initialize(void);                   
extern void initRxBufferMSCAN0(CAN0_DATATYPE *cf, UINT32 id,UINT8 idxBuffer); 
extern UINT8 readMsgMSCAN0(CAN0_DATATYPE *cf, UINT8 idxBuffer);   
extern UINT8 sendMsgMSCAN0(CAN0_DATATYPE *cf);
                                                
extern void CAN0_call_for_srecord_PACK(UINT8 Call_for_n_message);
extern void CAN0_Send_Operation_results_PACK(void); 

extern CAN0_DATATYPE        CAN0_Call_for_SRecord;
extern CAN0_DATATYPE        CAN0_Send_Operation_results;
extern CAN0_DATATYPE        Intermediate;



#endif                      


CAN.c文件

`

#include <string.h>
#include "Types.h"
#include "Regdef.h"   
#include "CAN0.h"

#define EnterCS()                      {__asm tpa; __asm staa regCCR; __asm sei;}
#define ExitCS()                       {__asm ldaa regCCR; __asm tap;}

                           

#define READ_CAN0_EXT_ID()             (*((unsigned long *)((&CAN0RXIDR0))))
#define WRITE_CAN0_EXT_ID(id)          (*((unsigned long *)((&CAN0TXIDR0)))= id)  


#define MSCAN0_TX_SIZE                 20
static CAN0_DATATYPE  msgTX0[MSCAN0_TX_SIZE];/* transmit buffer */
static UINT8 wIdxTX0;                /* write index */
static UINT8 rIdxTX0;                /* read index */
 UINT8 countTX0;               /* number of element in the buffer */ 

                    
#define CAN0_RX_Srcord_ID         0x00180000 //接收S-Record记录ID
#define CAN0_RX_Command_ID        0x00180002 //接收主机发来命令ID
#define Call_for_SRecord_ID       0x00180004
#define CAN0_Bootloader_State_ID  0x0018000C //Bootloader的状态
  CAN0_DATATYPE        CAN0_Call_for_SRecord;              //申明结构体变量
  CAN0_DATATYPE        CAN0_Send_Operation_results;        //申明结构体变量
  Str_Can_Send_State     State[8];   

                      
  
  #define MSCAN0_RX_SIZE                 2
  CAN0_DATATYPE        Intermediate;
  CAN0_DATATYPE        msgRX0[MSCAN0_RX_SIZE];  
  UINT8 isNewDataRX0[MSCAN0_RX_SIZE];   
                                          

void initializeMSCAN0(void)
{ 

Bootloader_version_number=0;
Have_Program_SRec_numbers=0;
Program_Successfully=0;
SRecord_CheckSum_error=0;
SRecord_Invalid_address=0;
Get_Ready_to_erase_block0=0;
Get_Ready_to_erase_block1N=0;
Get_Ready_to_erase_block1S=0;
Get_Ready_to_erase_block2=0;
Get_Ready_to_erase_block3=0;
Erase_Successfully=0;
SRec_Range_error=0;
Program_reset_vector_error=0;
  wIdxTX0=rIdxTX0=countTX0=0;
  CAN0CTL0|= 0x01;               //请求进入初始化模式  
  while ((CAN0CTL1&0x01)==0) ;   //初始化模式确认  
 
 //总线频率为250kb/s
// CAN0BTR0_SJW = 0;            //设置同步
// CAN0BTR0_BRP = 7;            //设置波特率  
// CAN0BTR1 = 0x1c;       //设置时段1和时段2的Tq个数 ,总线频率为250kb/s

  CAN0CTL1=0x81;      //使能MSCAN模块,使用外部晶振16MHZ 作为时钟源
  CAN0BTR0 = 3;       //预分频值4 ,1个Tq时钟周期          
  CAN0BTR1=156;       // TSEG2=1,2Tq时钟周期 13个Tq时钟周期
   //波特率250kbps              
 
  CAN0IDAC&=239;                 
  CAN0IDAC&=223;      
  
  CAN0IDAR0 =0X00;    
  CAN0IDAR1 =0X18;       
  CAN0IDAR2 =0X00;          
  CAN0IDAR3 =0X00; //CAN0_RX_Srcord_ID  0x00180000        
  
  CAN0IDAR4 =0X00;  
  CAN0IDAR5 =0X18;  
  CAN0IDAR6 =0X00;                
  CAN0IDAR7 =0X02; //CAN0_RX_Command_ID 0x00180002
                                                
  //Config CAN1IDMR0-7                 
  CAN0IDMR0 = 0X00;     
  CAN0IDMR1 = 0X00;   
  CAN0IDMR2 = 0X00;   
  CAN0IDMR3 = 0X00;                                                        
                                                                      
  CAN0IDMR4 = 0x00;
  CAN0IDMR5 = 0X00;
  CAN0IDMR6 = 0x00;
  CAN0IDMR7 = 0x00;
  CAN0CTL0 &=254;   
  while ((CAN0CTL1&CAN0CTL1_INITAK_MASK)==1) ;   
  while ((CAN0CTL0&CAN0CTL0_SYNCH_MASK)==0) ;
  CAN0RIER = 1;       //打开接收中断,中断的开发在退出初始化的模式下进行
  CAN0TIER = 0;       //关闭发送中断
}
void CAN_initialize(void) 
{
  initRxBufferMSCAN0(&Intermediate, CAN0_RX_Srcord_ID, SRecord);
  initRxBufferMSCAN0(&Intermediate, CAN0_RX_Command_ID,Command);
  initializeMSCAN0();
}                              

void initRxBufferMSCAN0(CAN0_DATATYPE *cf, UINT32 id,UINT8 idxBuffer)
{
    cf->ID = id;
    msgRX0[idxBuffer] = *cf;
    isNewDataRX0[idxBuffer] = 0;
}
                                                 
UINT8 readMsgMSCAN0(CAN0_DATATYPE *cf, UINT8 idxBuffer)
{
  UINT8 i, status = 0;
  //EnterCS();
  if (isNewDataRX0[idxBuffer] == 1) 
  {
    isNewDataRX0[idxBuffer] = 0;
    status = 1;
    cf->Length = msgRX0[idxBuffer].Length;
    for (i=0; i<cf->Length; i++) 
    {
      cf->DATA[i] = msgRX0[idxBuffer].DATA[i];
    }
  } 
  //ExitCS();
  return (status);
}

#pragma CODE_SEG RAM_CODE
interrupt void MSCAN0_Receive_ISR(void)
{
  UINT32 id;
  UINT8 dlr, i;                               
  INT8 idxBuffer;                                   
  id = READ_CAN0_EXT_ID();        //读id ??
  dlr = CAN0RXDLR&0x0F;           //读长度
  for (idxBuffer = (MSCAN0_RX_SIZE-1); idxBuffer>=0; idxBuffer--) 
  {
    if (id==msgRX0[idxBuffer].ID) 
    {       
      msgRX0[idxBuffer].Length = dlr;
      for (i=0; i<dlr; i++) 
      {
        msgRX0[idxBuffer].DATA[i] = *(CAN0RXDSR_ARR + i);
      }  
      isNewDataRX0[idxBuffer] = 1;
      break;
    }
  } 
  /* 清除接收缓冲区满标志*/
  CAN0RFLG|=CAN0RFLG_RXF_MASK;
}
#pragma CODE_SEG DEFAULT   
 
void loadMsgMSCAN0(CAN0_DATATYPE *cf)
{
  UINT8 nb;
  UINT32 id;
  CAN0TBSEL = CAN0TFLG;/* 自动寻找空的发送缓冲区*/
  id = cf->ID;
  WRITE_CAN0_EXT_ID(id);
  CAN0TXDLR = cf->Length;
  for (nb=0; nb<cf->Length; nb++)  /* 写入数据*/ 
  {
    *(CAN0TXDSR_ARR + nb) = cf->DATA[nb];
  }
  CAN0TFLG = CAN0TBSEL;    /* 清除标志位开始发送 */
  CAN0TIER |= CAN0TBSEL;   /* 使能发送缓冲区空中断 */
}
     
UINT8 sendMsgMSCAN0(CAN0_DATATYPE *cf)
{  
  UINT8 status = 0;    
  if (CAN0TFLG && (countTX0 == 0))/*如果自定义缓冲区空并且发送缓冲区空*/ 
  {
    loadMsgMSCAN0(cf);
  } 
  else 
  {                             /* add the message to the ring buffer */
    if (countTX0 != MSCAN0_TX_SIZE) 
    {  /* if the transmit buffer is not full */
      msgTX0[wIdxTX0] = *cf;           /* write the current element to be send */
      countTX0++;                      /* increment the number of elements to be transmitted */
      if (++wIdxTX0 == MSCAN0_TX_SIZE) 
      {/* increment and wrap around the buffer write index */
        wIdxTX0 = 0;
      }
    } 
    else 
    {                 
      status = 1;
    }
  }    
  return (status);             
}                                            
//CAN0发送缓冲区空中断
#pragma CODE_SEG RAM_CODE
interrupt void MSCAN0_Transmit_ISR(void)
{
  if (countTX0 != 0) 
  {                 /* if transmit buffer not empty */
    loadMsgMSCAN0(&msgTX0[rIdxTX0]);   /* write the data in the register */
    countTX0--;                        /* decrement the number of elements to be transmitted */
    if (++rIdxTX0 == MSCAN0_TX_SIZE) 
    { /* increment and wrap around the buffer read index */
      rIdxTX0 = 0;
    }
  } else           
  {
    CAN0TIER = 0;
  }                              
}                                 
#pragma CODE_SEG DEFAULT    
                              
void CAN0_call_for_srecord_PACK(UINT8 Call_for_n_message)
{

  CAN0_Call_for_SRecord.ID = Call_for_SRecord_ID;    // Call_for_SRecord_ID     0x00180004
  CAN0_Call_for_SRecord.Extended = 1;                  
  CAN0_Call_for_SRecord.Length = 1;
  CAN0_Call_for_SRecord.TXTBPR = 0;
  CAN0_Call_for_SRecord.DATA[0] =Call_for_n_message;
}                              

void CAN0_Send_Operation_results_PACK(void)
{

  CAN0_Send_Operation_results.ID = CAN0_Bootloader_State_ID;
  CAN0_Send_Operation_results.Extended = 1;
  CAN0_Send_Operation_results.Length = 8;
  CAN0_Send_Operation_results.TXTBPR = 0;
  CAN0_Send_Operation_results.DATA[0] =Bootloader_version_number;
  CAN0_Send_Operation_results.DATA[1] =Have_Program_SRec_numbers;
  CAN0_Send_Operation_results.DATA[2] =State[2].Byte;
  CAN0_Send_Operation_results.DATA[3] =State[3].Byte;
  CAN0_Send_Operation_results.DATA[4] =State[4].Byte;
  CAN0_Send_Operation_results.DATA[5] =State[5].Byte;
  CAN0_Send_Operation_results.DATA[6] =Program_state;
  CAN0_Send_Operation_results.DATA[7] =EraseFlash_state;
}   



  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 系统已结题 1月12日
    • 创建了问题 1月4日

    悬赏问题

    • ¥15 from seleniumwire import webdriver 在抓取http://链接的时候会自动转https://这个怎么解决
    • ¥15 hive直连数据库模式插入mysql表数据失败(相关搜索:数据库)
    • ¥30 不会,学习,有偿解答
    • ¥15 SQL查询语句报错(检查)
    • ¥15 此表中公式应该怎么写
    • ¥15 求HI-TECH PICC 9.50 PL3安装包
    • ¥15 下载ctorch报错,求解
    • ¥15 如何入门学习c语言,单片机
    • ¥15 idea 编辑语言的选择
    • ¥15 Windows下部署Asmjit