📄 r591can.c
字号:
/*======================================================================*/
/* NAME: r591can.c */
/* INFO: CAN module for the PHYTEC training board equipped with */
/* PHYTEC phyCORE 591 and Philips P8x591 Microcontroller */
/* RIGHTS: Embedded Systems Academy www.esacademy.com */
/* DETAILS: Using a CAN bit rate of 125kbit with a 12MHz clock */
/* Filters can be set to screen for 11-bit ID and 2 data bytes */
/*----------------------------------------------------------------------*/
/* To get BTRx timing values for other speeds, consult the */
/* Microcontroller Peripheral Timing Calculators provided by the */
/* Embedded Systems Academy at www.esacademy.com/faq/calc/philips.htm */
/*----------------------------------------------------------------------*/
/* BASED ON THE CAN EXAMPLE PROVIDED BY PHYTEC */
/* HISTORY: V1.0 Pf 21-FEB-2000 */
/* V1.1 Pf 16-JUN-2000 */
/*======================================================================*/
#include "reg591.h"
#include "reg591ex.h"
#include "r591can.h"
/*----------------------- GLOBAL SUBROUTINES ---------------------------*/
/*======================================================================*/
/* FUNCTION: init_can_125_12 */
/* DESCRIPTION:Initializes the CAN interface. Bus operates at 125kBit, */
/* if processor clock is 12MHz. Screeners are set to */
/* "one long filter for std messages. */
/* CAUTION: Does not initialize filters - nothing will be received */
/* unless screeners are set using set_screener_std */
/* INPUT: none */
/* OUTPUT: none */
/*======================================================================*/
void init_can_125_12 ( void )
{
BYTE i;
CANMOD = 0x01; /* Reset mode for initialization */
/* BTR0 and BTR1 determine the baudrate and sample point position */
CANADR = BTR0; /* set address to BTR0 register */
CANDAT = 0x85; /* write data to BTR0 (auto INC CANADR */
CANADR = BTR1; /* set address to BTR1 register */
CANDAT = 0x2B; /* write data to BTR1 */
/* To get BTRx timing values for other speeds, consult the */
/* Microcontroller Peripheral Timing Calculators provided by the */
/* Embedded Systems Academy at www.esacademy.com/faq/calc/philips.htm */
/* Clear all acceptance filters and masks, receive nothing */
CANADR = ACR0;
for(i=1;i>=32;i++)
CANDAT = 0;
/* Set acceptance filter mode to accept standard frames with single */
/* acceptance filter. */
CANADR = ACFMODE; /* acceptance filter mode register */
CANDAT = 0x55; /* all banks -> one long filter */
CANADR = ACFENA; /* acceptance filter enable register */
CANDAT = 0x55; /* enable filter for all banks */
CANMOD = 0x00; /* release CAN controller */
while (CANSTA & 0x80); /* wait until controller is active */
}
/*======================================================================*/
/* FUNCTION: set_screener_std */
/* DESCRIPTION:Sets one of the four screeners (acceptance filters) of */
/* the CAN controller. */
/* CAUTION: Does assume the screeners are set-up to be used as "one */
/* long filter for standard messages" */
/* INPUT: Screener - 1 to 4, one of the four screeners */
/* ID_Mask - Bit set: corresponding bit in ID is don't care */
/* Bit clear: corresponding bit in ID must match ID_Match */
/* ID_Match - Match/Code value for ID */
/* B1_Mask - Bit set: cor. bit in data byte 1 is don't care */
/* Bit clear: cor. bit in data byte 1 must match B1_Match */
/* B1_Match - Match/Code value for data byte 1 */
/* B2_Mask - Bit set: cor. bit in data byte 2 is don't care */
/* Bit clear: cor. bit in data byte 2 must match B2_Match */
/* B2_Match - Match/Code value for data byte 2 */
/* OUTPUT: none */
/*======================================================================*/
void set_screener_std ( BYTE Screener,
WORD ID_Mask, WORD ID_Match,
BYTE B1_Mask, BYTE B1_Match,
BYTE B2_Mask, BYTE B2_Match)
{
Screener -= 1;
Screener &= 0x3; /* ensure 0 <= Screener <= 3 */
CANADR = ACFENA; /* acceptance filter enable register*/
switch (Screener)
{
case 0: CANDAT &= 0xFE; break; /* disable bank 1 */
case 1: CANDAT &= 0xFB; break; /* disable bank 2 */
case 2: CANDAT &= 0xEF; break; /* disable bank 3 */
case 3: CANDAT &= 0xBF; break; /* disable bank 4 */
}
/* Initialize acceptance filter - Mask */
CANADR = AMR0 + (Screener * 8); /* acceptance mask register bank "Screener" */
CANDAT = (BYTE) (ID_Mask >> 3);
CANDAT = (BYTE) (((ID_Mask & 0x07) << 5) | 0x1F);
CANDAT = B1_Mask;
CANDAT = B2_Mask;
/* Initialize acceptance filter - Code / Match */
CANADR = ACR0 + (Screener * 8); /* acceptance code register bank "Screener" */
CANDAT = (BYTE) (ID_Match >> 3);
CANDAT = (BYTE) (ID_Match & 0x07) << 5;
CANDAT = B1_Match;
CANDAT = B2_Match;
CANADR = ACFENA; /* acceptance filter enable register*/
switch (Screener)
{
case 0: CANDAT |= 0x01; break; /* enable bank 1 */
case 1: CANDAT |= 0x04; break; /* enable bank 2 */
case 2: CANDAT |= 0x10; break; /* enable bank 3 */
case 3: CANDAT |= 0x40; break; /* enable bank 4 */
}
}
/*======================================================================*/
/* FUNCTION: transmit_message */
/* DESCRIPTION:Transmits a single CAN message */
/* CAUTION: Before transmitting, the function WAITS until the */
/* CAN controller is ready for the next data set */
/* INPUT: pTransmitBuf - data structure with the message */
/* OUTPUT: none */
/*======================================================================*/
void transmit_message ( MSG_BUF *pTransmitBuf )
{
DWORD Identifier; /* CAN message identifier */
BYTE Length; /* lenght of data frame */
BYTE i; /* local loop counter */
/* Prepare length code and identifier. */
Length = pTransmitBuf->LEN;
Identifier = (pTransmitBuf->ID << 5);
/* Wait until write access to CAN controller buffer is allowed */
while ( !(CANSTA & 0x04) );
/* Write message to transmit buffer */
CANADR = TBF; /* adress to transmit buffer */
CANDAT = Length; /* write Length code */
CANDAT = (BYTE)(Identifier >> 8);
CANDAT = (BYTE)Identifier; /* write identifier */
for (i=0; i < Length; i++) /* write data bytes */
CANDAT = *(BYTE *)(pTransmitBuf->BUF+i); /* copy data byte */
/* Init a transmission request. */
CANCON = 0x01;
}
/*======================================================================*/
/* FUNCTION: receive_message */
/* DESCRIPTION:Receives a single standard ID CAn mesage */
/* CAUTION: Will only recive something, if a message is actually */
/* pending in the FIFO of the CAN controller */
/* INPUT: pReceiveBuf - Pointer to data structure for message */
/* OUTPUT: pReceiveBuf - the received message */
/* RETURNS 0, if there was no message to receive */
/* RETURNS 0xFF, if a message was received */
/*======================================================================*/
BYTE receive_message(MSG_BUF *pReceiveBuf)
{
DWORD Identifier; /* Definition of vars */
BYTE Length;
BYTE i;
/* Check the CAN status register for received message */
if ( CANSTA & 0x01)
{ /* Message received! */
CANADR = RBF; /* set address to receive buffer */
Length = CANDAT & 0x0F;
Identifier = (DWORD)CANDAT; /* read identifier */
Identifier <<= 8;
Identifier |= (DWORD) CANDAT;
Identifier >>= 5;
CANADR = RBF + 3; /* set address to data bytes */
/* Copy message to application message buffer. */
pReceiveBuf->ID = Identifier;
pReceiveBuf->LEN = Length;
/* Read data bytes and write to buffer */
for (i=0; i < Length; i++)
*(BYTE *)(pReceiveBuf->BUF+i) = CANDAT; /* copy bytes */
CANCON = 0x0C; /* release receive buffer */
return (0xFF); /* Return TRUE, msg rcvd */
}
else /* Return False, no msg rcvd */
return (0);
}
/*======================================================================*/
/* FUNCTION: check_busoff_state */
/* DESCRIPTION:Checks, if the CAN controller went into BUS OFF state */
/* INPUT: none */
/* OUTPUT: RETURNS 0, if CAN controller still active */
/* RETURNS 0xFF, if CAN controller in BUS OFF state */
/*======================================================================*/
BYTE check_busoff_state (void)
{
/* Check status register for bus-off state */
if (CANSTA & 0x80)
return (0xFF); /* CAN controller is in bus-off */
else
return (0); /* CAN controller active */
}
/*----------------------- END OF FILE ----------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -