📄 can1.c
字号:
MsgBuff->IDR3 = ((DwordSwap *)&tmpId)->b.b3; /* Store the message ID */
MsgBuff->IDR2 = ((DwordSwap *)&tmpId)->b.b2;
MsgBuff->IDR1 = ((DwordSwap *)&tmpId)->b.b1;
MsgBuff->IDR0 = ((DwordSwap *)&tmpId)->b.b0;
if (FrameType == DATA_FRAME) { /* Is it a data frame? */
for (i=0; i<Length; i++) {
MsgBuff->Data[i] = Data[i]; /* Store data to the transmit register */
}
if (MessageID & CAN_EXTENDED_FRAME_ID) { /* Is it the extended frame? */
MsgBuff->IDR3 &= 254; /* If no then set message type as "data frame" */
}
else {
MsgBuff->IDR1 &= 239; /* If yes then set message type as "data frame" */
}
}
else { /* Remote frame */
if (MessageID & CAN_EXTENDED_FRAME_ID) { /* Is it the extended frame? */
MsgBuff->IDR3 |= 1; /* If yes then set message type as "remote frame" */
}
else {
MsgBuff->IDR1 |= 16; /* If yes then set message type as "remote frame" */
}
}
CANTXDLR = Length; /* Set the length of the message */
CANTXTBPR = 0; /* Set the priority (high) */
CANTFLG = CANTBSEL; /* Start transmission */
ExitCritical(); /* Enable global interrupts */
return ERR_OK; /* OK */
}
/*
** ===================================================================
** Method : CAN1_ReadFrame (bean FreescaleCAN)
**
** Description :
** Reads a frame from the CAN device. The user is informed
** about CAN reception through OnFullRxBuffer event or
** GetStateRX method.
** Parameters :
** NAME - DESCRIPTION
** * MessageID - Pointer to a 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.
** Note: This parameter is obsolete and
** will be removed in future releases.
** * Length - Pointer to a length of the frame
** * Data - The buffer for received data
** Returns :
** --- - Error code, possible codes:
** ERR_OK - OK
** ERR_SPEED - This device does not work in
** the active speed mode
** ERR_DISABLED - This bean is disabled by
** user
** ERR_RXEMPTY - The receive buffer is
** empty
** ERR_OVERRUN - The previous message in
** the receive buffer was overwriten by a
** new message.
** ===================================================================
*/
byte CAN1_ReadFrame(dword *MessageID,byte *FrameType,byte *FrameFormat,byte *Length,byte *Data)
{
byte i;
dword tmpId = 0;
if (!(SerFlag & FULL_RX_BUF)) { /* Is the receive buffer empty? */
return ERR_RXEMPTY; /* If yes then error */
}
((DwordSwap*)&tmpId)->b.b0 = CANRXIDR0;
((DwordSwap*)&tmpId)->b.b1 = CANRXIDR1;
((DwordSwap*)&tmpId)->b.b2 = CANRXIDR2;
((DwordSwap*)&tmpId)->b.b3 = CANRXIDR3;
if (tmpId & MB_ID_IDE) {
*MessageID = ((tmpId >> 1) & 0x3FFFFUL) | ((tmpId >> 3) & 0x1FFC0000UL) | CAN_EXTENDED_FRAME_ID; /* Extended frame */
}
else {
*MessageID = tmpId >> 21; /* Standard frame */
}
if (*MessageID & CAN_EXTENDED_FRAME_ID) {
*FrameFormat = EXTENDED_FORMAT;
*FrameType = (CANRXIDR3 & 1)? (byte)REMOTE_FRAME : (byte)DATA_FRAME; /* Result the frame type */
*MessageID &= ~CAN_EXTENDED_FRAME_ID; /* Remove EXTENDED_FRAME indicator, frame type will be returned in FrameType parameter */
}
else {
*FrameFormat = STANDARD_FORMAT;
*FrameType = (CANRXIDR1 & 16)? (byte)REMOTE_FRAME : (byte)DATA_FRAME; /* Result the frame type */
}
*Length = CANRXDLR & 15; /* Result length of the message */
if (*FrameType == DATA_FRAME) { /* Is it "data frame"? */
for (i=0; i<*Length; i++) {
Data[i] = *((byte *)&CANRXDSR0 + i); /* Return received data */
}
}
SerFlag &= ~FULL_RX_BUF; /* Clear flag "full RX buffer" */
if (SerFlag & CANRFLG_OVRIF_MASK) { /* Is the overrun detected? */
SerFlag &= ~CANRFLG_OVRIF_MASK; /* Clear the internal overrun flag */
return ERR_OVERRUN; /* If yes then error */
}
return ERR_OK; /* OK */
}
/*
** ===================================================================
** Method : CAN1_Init (bean FreescaleCAN)
**
** Description :
** Initializes the associated peripheral(s) and the beans
** internal variables. The method is called automatically as a
** part of the application initialization code.
** This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
void CAN1_Init(void)
{
/* CANCTL1: CANE=1,CLKSRC=0,LOOPB=0,LISTEN=0,??=0,WUPM=0,SLPAK=0,INITAK=0 */
CANCTL1 = 128; /* Set the control register */
/* CANCTL0: RXFRM=0,RXACT=0,CSWAI=0,SYNCH=0,TIME=0,WUPE=0,SLPRQ=0,INITRQ=1 */
CANCTL0 = 1; /* Set the control register */
CANIDAC_IDAM = 0; /* Set the acceptance mode */
CANIDAR0 = 0; /* Set the acceptance code, register CANIDAR0 */
CANIDAR1 = 0; /* Set the acceptance code, register CANIDAR1 */
CANIDAR2 = 0; /* Set the acceptance code, register CANIDAR2 */
CANIDAR3 = 0; /* Set the acceptance code, register CANIDAR3 */
CANIDAR4 = 0; /* Set the acceptance code, register CANIDAR4 */
CANIDAR5 = 0; /* Set the acceptance code, register CANIDAR5 */
CANIDAR6 = 0; /* Set the acceptance code, register CANIDAR6 */
CANIDAR7 = 0; /* Set the acceptance code, register CANIDAR7 */
CANIDMR0 = 255; /* Set the acceptance mask, register CANIDMR0 */
CANIDMR1 = 255; /* Set the acceptance mask, register CANIDMR1 */
CANIDMR2 = 255; /* Set the acceptance mask, register CANIDMR2 */
CANIDMR3 = 255; /* Set the acceptance mask, register CANIDMR3 */
CANIDMR4 = 255; /* Set the acceptance mask, register CANIDMR4 */
CANIDMR5 = 255; /* Set the acceptance mask, register CANIDMR5 */
CANIDMR6 = 255; /* Set the acceptance mask, register CANIDMR6 */
CANIDMR7 = 255; /* Set the acceptance mask, register CANIDMR7 */
/* CANBTR0: SJW1=0,SJW0=1,BRP5=0,BRP4=0,BRP3=0,BRP2=1,BRP1=0,BRP0=0 */
CANBTR0 = 68; /* Set the device timing register */
/* CANBTR1: SAMP=0,TSEG22=0,TSEG21=1,TSEG20=1,TSEG13=0,TSEG12=1,TSEG11=1,TSEG10=1 */
CANBTR1 = 55; /* Set the device timing register */
CANCTL1_CLKSRC = 0; /* Select the clock source from crystal */
CANCTL0_INITRQ = 0; /* Start device */
while(CANCTL1_INITAK) {} /* Wait for enable */
/* CANRFLG: WUPIF=1,CSCIF=1,RSTAT1=1,RSTAT0=1,TSTAT1=1,TSTAT0=1,OVRIF=1 */
CANRFLG |= 254; /* Reset error flags */
/* CANRIER: WUPIE=0,CSCIE=1,RSTATE1=1,RSTATE0=1,TSTATE1=1,TSTATE0=1,OVRIE=0,RXFIE=1 */
CANRIER = 125; /* Enable interrupts */
}
/*
** ===================================================================
** Method : CAN1_GetStateTX (bean FreescaleCAN)
**
** Description :
** Returns a value of the transmission complete flags.
** Parameters : None
** Returns :
** --- - Content of the transmitter complete
** flag register.
** ===================================================================
*/
/*
byte CAN1_GetStateTX(void)
** This method is implemented as a macro in the header module. **
*/
/*
** ===================================================================
** Method : CAN1_SetAcceptanceMask (bean FreescaleCAN)
**
** Description :
** Sets the acceptance mask registers. This method writes an
** acceptance mask directly to the acceptance mask registers.
** Parameters :
** NAME - DESCRIPTION
** AccMask1 - Acceptance mask for the
** message filtering. This acceptance mask
** will be written to the acceptance mask
** registers IDMR0-IDMR3. The most
** significant byte of the acceptance mask
** will be written to the IDMR0 register
** and the least significant byte of the
** acceptance mask will be written to the
** IDMR3 register.
** AccMask2 - Acceptance mask for the
** message filtering. This acceptance mask
** will be written to the acceptance mask
** registers IDMR4-IDMR7. The most
** significant byte of the acceptance mask
** will be written to the IDMR4 register
** and the least significant byte of the
** acceptance mask will be written to the
** IDMR7 register.
** Returns :
** --- - Error code, possible codes:
** ERR_OK - OK
** ERR_SPEED - This device does not work in
** the active speed mode
** ERR_DISABLED - This bean is disabled by
** user
** ===================================================================
*/
byte CAN1_SetAcceptanceMask(dword AccMask1, dword AccMask2)
{
EnterCritical(); /* Enter critical section */
CANCTL0_INITRQ = 1; /* Disable device */
while(!CANCTL1_INITAK){} /* Wait for disable */
CANIDMR3 = ((DwordSwap *)&AccMask1)->b.b3; /* Set acceptance mask, register CANIDMR3 */
CANIDMR2 = ((DwordSwap *)&AccMask1)->b.b2; /* Set acceptance mask, register CANIDMR2 */
CANIDMR1 = ((DwordSwap *)&AccMask1)->b.b1; /* Set acceptance mask, register CANIDMR1 */
CANIDMR0 = ((DwordSwap *)&AccMask1)->b.b0; /* Set acceptance mask, register CANIDMR0 */
CANIDMR7 = ((DwordSwap *)&AccMask2)->b.b3; /* Set acceptance mask, register CANIDMR7 */
CANIDMR6 = ((DwordSwap *)&AccMask2)->b.b2; /* Set acceptance mask, register CANIDMR6 */
CANIDMR5 = ((DwordSwap *)&AccMask2)->b.b1; /* Set acceptance mask, register CANIDMR5 */
CANIDMR4 = ((DwordSwap *)&AccMask2)->b.b0; /* Set acceptance mask, register CANIDMR4 */
CANCTL0_INITRQ = 0; /* Start device */
while(CANCTL1_INITAK) {} /* Wait for device initialization acknowledge */
/* CANRFLG: WUPIF=1,CSCIF=1,OVRIF=1 */
CANRFLG |= 194; /* Reset error flags */
/* CANRIER: WUPIE=0,CSCIE=1,RSTATE1=1,RSTATE0=1,TSTATE1=1,TSTATE0=1,OVRIE=0,RXFIE=1 */
CANRIER = 125; /* Enable interrupts */
ExitCritical(); /* Exit critical section */
return ERR_OK; /* OK */
}
/*
** ===================================================================
** Method : CAN1_InterruptRx (bean FreescaleCAN)
**
** Description :
** The method services the receive interrupt of the selected
** peripheral(s) and eventually invokes the beans event(s).
** This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
#define ON_OVERRUN 1
ISR(CAN1_InterruptRx)
{
if (SerFlag & FULL_RX_BUF) { /* Is any char already present in the receive buffer? */
SerFlag |= CANRFLG_OVRIF_MASK; /* If yes then set internal flag OVERRUN */
}
SerFlag |= FULL_RX_BUF; /* Set flag "full RX buffer" */
__DI(); /* Disable maskable interrupts */
CAN1_OnFullRxBuffer(); /* If yes then invoke user event. Parameter is always 1 because the CAN module has only one RX message buffer */
CANRFLG = CANRFLG_RXF_MASK; /* Reset the reception complete flag and release the RX buffer */
}
#pragma CODE_SEG CAN1_CODE
/*
** ===================================================================
** Method : CAN1_InterruptError (bean FreescaleCAN)
**
** Description :
** The method services the error interrupt of the selected
** peripheral(s) and eventually invokes the beans event(s).
** This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
ISR(CAN1_InterruptError)
{
byte Status = CANRFLG; /* Read the status register */
CANRFLG = 254; /* Reset error flags */
}
#pragma CODE_SEG CAN1_CODE
/* END CAN1. */
/*
** ###################################################################
**
** This file was created by UNIS Processor Expert 2.96 [03.76]
** for the Freescale HCS12 series of microcontrollers.
**
** ###################################################################
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -