这是飞思卡尔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;
}