📄 can.c
字号:
#include <mc9s12c32.h> /* derivative information */
#include "can.h"
#include "io.h"
#include "pwm.h"
#include "sci.h"
#include "timer.h"
#include "event.h"
#pragma CODE_SEG DEFAULT
// ===================================================================
// Method : CAN_Init(void)
// Description : CAN Initialization
// Parameters : None
// Time segment 1: 6
// Time segment 2: 7
// RSJ: 1
// Returns: None
// ===================================================================
void CAN_Init(void)
{
CANCTL0 = 0x01; // Set the control register
CANCTL1 = 0x80; // Set the control register
CANIDAC_IDAM = 0x00; // Set the acceptance mode
*(dword *)&CANIDAR0 = 0xFFFFFFFF; // Set the acceptance code
*(dword *)&CANIDAR4 = 0xFFFFFFFF; // Set the acceptance code
*(dword *)&CANIDMR0 = 0xFFFFFFFF; // Set the acceptance mask
*(dword *)&CANIDMR4 = 0xFFFFFFFF; // Set the acceptance mask
CANBTR0 = 0x40; // Set the device timing register
CANBTR1 = 0x32; // Set the device timing register
CANCTL1_CLKSRC = 0x00; // Select the clock source from crystal
CANCTL0_INITRQ = 0x00; // Start device
while(CANCTL1_INITAK); // Wait for device initialization acknowledge
while(!CANCTL0_SYNCH); // Wait for synchronization
CANRFLG |= 0xFE; // Reset error flags
CANRIER = 0xFF; // Enable interrupts
}
// ===================================================================
// Method : CAN_SendFrame(byte BufferNum,dword MessageID,byte FrameType,byte Length,byte *Data)
// Description : Send a frame.
// Parameters :
// MessageID - Identification of the message
// FrameType - Type of frame
// DATA_FRAME - data frame 0
// REMOTE_FRAME - remote frame 1
// Length - Length of the frame in bytes (0..8)
// * Data - Pointer to data
// Returns : None
// ===================================================================
void CAN_SendFrame(byte BufferNum,dword MessageID,byte FrameType,byte Length,byte *Data)
{
byte i; /* Temorary variables */
byte bufmask=((word)1 << BufferNum); /* Buffer mask */
CANTBSEL = bufmask;
if (MessageID <= 0x7FF) /* Is it the standard frame? */
*(dword *)&CANTXIDR0 = (MessageID << 21); /* Sets the message as "standard" */
else
*(dword *)&CANTXIDR0 = ( ((MessageID << 1) & 0x0007FFFF) | ((MessageID << 3) & 0xFFE00000) ) | 0x00080000; /* Set the message as "extended" */
if (FrameType == DATA_FRAME)
{ /* Is it a data frame? */
for(i=0; i<Length; i++)
*((byte *)&CANTXDSR0 + i) = Data[i]; /* Store data to the transmit register */
if (MessageID <= 0x7FF) /* Is it the standard frame? */
CANTXIDR1 &= 0xEF; /* If yes then set the standard message type as "data frame" */
else
CANTXIDR3 &= 0xFE; /* If no then set the extended message type as "data frame" */
}
else
{ /* Remote frame */
if (MessageID <= 0x7FF) /* Is it the standard frame? */
CANTXIDR1 |= 0x10; /* If yes then set the standard message type as "remote frame" */
else
CANTXIDR3 |= 0x01; /* If yes then set the extended message type as "remote frame" */
}
CANTXDLR = Length; /* Set the length of the message */
CANTXTBPR = 0x00; /* Set the priority (high) */
CANTFLG = bufmask; /* Start transmission */
}
// ===================================================================
// Method : CAN_ReadFrame(dword *MessageID,byte *FrameType,byte *FrameFormat,byte *Length,byte *Data)
// Description : Read a frame.
// Parameters :
// * MessageID - Pointer to the message indentification
// * FrameType - Pointer to a frame type
// DATA_FRAME - data frame
// REMOTE_FRAME - remote frame
// * FrameFormat - Pointer to a frame format
// STANDARD_FORMAT - standard frame 11-bits
// EXTENDED_FORMAT - extended frame 29-bits
// * Length - Pointer to length of the frame
// * Data - The buffer for received data
// Returns : None
// ===================================================================
void CAN_ReadFrame(dword *MessageID,byte *FrameType,byte *FrameFormat,byte *Length,byte *Data)
{
byte i; /* Temporary variable */
dword ID; /* Temporary variable */
ID = *(dword *)&CANRXIDR0; /* Read the identification of the received message */
if ((CANRXIDR1 & 0x08))
{ /* Is the received message "extended frame" */
ID = ( ((ID >> 0x01) & 0x0003FFFF) | ((ID >> 0x03) & 0xFFFC0000) ); /* Result the identification */
*FrameType = (CANRXIDR3 & 0x01)? REMOTE_FRAME : DATA_FRAME; /* Result the frame type */
}
else
{ /* Message is "standard frame" */
ID >>= 0x15; /* Result the identification */
*FrameType = (CANRXIDR1 & 0x10)? REMOTE_FRAME : DATA_FRAME; /* Result the frame type */
}
*MessageID = ID; /* Result the identification */
*FrameFormat = (CANRXIDR1 & 0x08)? EXTENDED_FORMAT : STANDARD_FORMAT; /* Result the frame type */
*Length = CANRXDLR & 0x0F; /* Result length of the message */
if (*FrameType == DATA_FRAME)
{ /* Is frame "data frame" */
for(i=0; i<*Length; i++)
Data[i] = *((byte *)&CANRXDSR0 + i); /* Return received data */
}
}
#pragma CODE_SEG __NEAR_SEG NON_BANKED /* Interrupt section for this module. Placement will be in NON_BANKED area. */
interrupt 34 void CAN_FullRxBuffer(void)
{
CAN_OnFullRxBuffer(); /* If yes then invoke user event */
CANRFLG_RXF = 1; /* Reset the reception complete flag */
}
#pragma CODE_SEG DEFAULT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -