//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <compiler_defs.h>
#include <C8051F500_defs.h> // SFR declarations
#include <stdio.h>
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define SYSCLK 24000000 // SYSCLK frequency in Hz
#define BAUDRATE 115200 // Baud rate of UART in bps
#define MESSAGE_OBJECTS 32 // Number of message objects to use
// Range is 1-32
#define MESSAGE_SIZE 8 // Size in bytes of each CAN message
// Range is 1-8
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
U8 UART_Buffer_Size=0;
U8 TX_Ready = 1;
U8 UART_Buffer[10];
U8 TER_ter=0;
static U8 Byte;
//-----------------------------------------------------------------------------
// Bit Definition Masks
//-----------------------------------------------------------------------------
// CAN0STAT
#define BOff 0x80 // Busoff Status
#define EWarn 0x40 // Warning Status
#define EPass 0x20 // Error Passive
#define RxOk 0x10 // Receive Message Successfully
#define TxOk 0x08 // Transmitted Message Successfully
#define LEC 0x07 // Last Error Code
//-----------------------------------------------------------------------------
// Pin Definitions
//-----------------------------------------------------------------------------
//SBIT (LED, SFR_P1, 3); // LED = 1 turns on the LED
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
bit CAN_ERROR = 0; // 0 = No Errors during transmission
// 1 = Some error(s) occurred
//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void);
void UART0_Init (void);
void PORT_Init (void);
void CAN0_Init (void);
void CAN0_TransferMO (U8 obj_num);
void *memset(void *s,int c,size_t n);
INTERRUPT_PROTO (UART0_ISR, INTERRUPT_UART0);
//INTERRUPT_PROTO (CAN0_ISR, INTERRUPT_CAN0);
//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
void main (void)
{
// U8 SFRPAGE_save;
SFRPAGE = ACTIVE_PAGE; // Change for PCA0MD
PCA0MD &= ~0x40; // Disable watchdog timer
OSCILLATOR_Init (); // Initialize Oscillator
PORT_Init (); // Initialize Port I/O
UART0_Init (); // Initialize UART
CAN0_Init (); // Start CAN peripheral
EIE2 |= 0x02; // Enable CAN interupts
EA = 1; // Enable global interrutpts
memset(UART_Buffer,0,10*sizeof(U8));
// putchar('A');
while (1)
{
// If the complete word has been entered via the terminal followed by
// carriage return
if((TX_Ready == 1) && (UART_Buffer_Size != 0) && (Byte == 35))
{
TER_ter++;
TX_Ready = 0; // Set the flag to zero
TI0 = 1;
if(TER_ter>5)
{
TER_ter=0;
}
CAN0_TransferMO (TER_ter);
// SFRPAGE_save = SFRPAGE;
// SFRPAGE = CAN0_PAGE;
// while (CAN0TR1 | CAN0TR2)
// {
// LED = !LED;
// for (iter = 0; iter < 6500; iter++);
// }
// SFRPAGE=SFRPAGE_save;
}
// if (CAN_ERROR)
// { // If any errors occurred
// LED = 1; // Turn off LED
// }
// else
// {
// LED = 0; // No error, so keep LED on
// }
}
}
//-----------------------------------------------------------------------------
// OSCILLATOR_Init
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void)
{
U8 SFRPAGE_save = SFRPAGE;
SFRPAGE = CONFIG_PAGE;
OSCICN |= 0x87; // Configure internal oscillator for
// its maximum frequency
RSTSRC = 0x04; // Enable missing clock detector
SFRPAGE = SFRPAGE_save;
}
//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
void UART0_Init (void)
{
U8 SFRPAGE_save = SFRPAGE;
SFRPAGE = CONFIG_PAGE;
SCON0 = 0x10; // SCON0: 8-bit variable bit rate
// clear RI0 and TI0 bits
// Baud Rate = [BRG Clock / (65536 - (SBRLH0:SBRLL0))] x 1/2 x 1/Prescaler
#if ((SYSCLK / BAUDRATE / 2 / 0xFFFF) < 1)
SBRL0 = -(SYSCLK / BAUDRATE / 2);
SBCON0 |= 0x03; // Set prescaler to 1
#elif ((SYSCLK / BAUDRATE / 2 / 0xFFFF) < 4)
SBRL0 = -(SYSCLK / BAUDRATE / 2 / 4);
SBCON0 &= ~0x03;
SBCON0 |= 0x01; // Set prescaler to 4
#elif ((SYSCLK / BAUDRATE / 2 / 0xFFFF) < 12)
SBRL0 = -(SYSCLK / BAUDRATE / 2 / 12);
SBCON0 &= ~0x03; // Set prescaler to 12
#else
SBRL0 = -(SYSCLK / BAUDRATE / 2 / 48);
SBCON0 &= ~0x03;
SBCON0 |= 0x02; // Set prescaler to 48
#endif
SBCON0 |= 0x40; // Enable baud rate generator
ES0 = 1; // Enable UART0 interrupts
TX_Ready = 1; // Indicate TX0 ready
TI0 = 0;
SFRPAGE = SFRPAGE_save;
}
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Configure the Crossbar and GPIO ports.
//
// P0.4 digital push-pull UART TX
// P0.5 digital open-drain UART RX
// P0.6 digital push-pull CAN TX
// P0.7 digital open-drain CAN RX
//
//-----------------------------------------------------------------------------
void PORT_Init (void)
{
U8 SFRPAGE_save = SFRPAGE;
SFRPAGE = CONFIG_PAGE;
P0MDOUT |= 0x50; // Enable UTX and CAN_TX as push-pull output
// P1MDOUT |= 0x08; // P1.3 (LED) is push-pull
XBR0 = 0x03; // Enable UART on P0.4(TX) and P0.5(RX) CAN_TX, CAN_RX routed to Port pins P0.6 and P0.7.
XBR2 = 0x40; // Enable crossbar and weak pull-ups
SFRPAGE = SFRPAGE_save;
}
//-----------------------------------------------------------------------------
// CAN0_Init
//-----------------------------------------------------------------------------
void CAN0_Init (void)
{
U8 iter;
U8 SFRPAGE_save = SFRPAGE;
SFRPAGE = CAN0_PAGE; // All CAN register are on page 0x0C
CAN0CN |= 0x01; // Start Intialization mode
//---------Initialize general CAN peripheral settings
CAN0CN |= 0x4E; // Enable Status, Error,
// Module Interrupts
// Enable access to bit timing register
// See the CAN Bit Timing Spreadsheet for how to calculate this value
CAN0BT = 0x1402; // Based on 24 Mhz CAN clock, set the
// CAN bit rate to 1 Mbps
//---------Initialize settings common to all message objects
// Command Mask Register
CAN0IF1CM = 0x00F0; // Write Operation
// Transfer ID Mask, MDir, MXtd
// Transfer ID, Dir, Xtd, MsgVal
// Transfer Control Bits
// Don't set TxRqst or transfer data
// Mask Registers
CAN0IF1M1 = 0x0000; // Mask Bits 15-0 not used for filtering
CAN0IF1M2 = 0x5FFC; // Ignore Extended Identifier for
// filtering
// Used Direction bit for filtering
// Use ID bits 28-18 for filtering
// Arbitration Registers
CAN0IF1A1 = 0x0000; // 11-bit ID, so lower 16-bits not used
// Message Control Registers
CAN0IF1MC = 0x0880 | MESSAGE_SIZE; // Enable Transmit Interrupt
// Message Object is a Single Message
// Message Size set by #define
//---------Initialize unique settings for each valid message object
for (iter = 0; iter < MESSAGE_OBJECTS; iter++)
{
// For example purposes, set 11-bit identifier based on the message
// object that is used to send it.
// Arbitration Registers
CAN0IF1A2 = 0xA000 | (iter << 2); // Set MsgVal to valid
// Set Direction to write
// Set 11-bit Identifier to iter
CAN0IF1CR = iter; // Start command request
while (CAN0IF1CRH & 0x80) {} // Poll on Busy bit
}
//---------Initialize settings for unused message objects
for (iter = MESSAGE_OBJECTS; iter < 32; iter++)
{
// Set remaining message objects to be Ignored
CAN0IF1A2 = 0x0000; // Set MsgVal to 0 to Ignore
CAN0IF1CR = iter; // Start command request
while (CAN0IF1CRH & 0x80) {} // Poll on Busy bit
}
CAN0CN &= ~0x41; // Return to Normal Mode and disable
// access to bit timing register
SFRPAGE = SFRPAGE_save;
}
//-----------------------------------------------------------------------------
// Supporting Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// CAN0_TransferMO
//-------------------------------------------------------------------------
void CAN0_TransferMO (U8 obj_num)
{
// This function assumes that the message object is fully initialized
// in CAN0_Init and so all it has to do is fill the data registers and
// initiate transmission
U8 SFRPAGE_save = SFRPAGE;
SFRPAGE = CAN0_PAGE; // All CAN register are on page 0x0C
// Initialize all 8 data bytes even though they might not be sent
// The number to send was configured earlier by setting Message Control
CAN0IF1DA1H = obj_num; // Initialize data registers based
CAN0IF1DA1L = obj_num + 1; // on message object used
CAN0IF1DA2H = obj_num + 2;
CAN0IF1DA2L = obj_num + 3;
CAN0IF1DB1H = obj_num + 4;
CAN0IF1DB1L = obj_num + 5;
CAN0IF1DB2H = obj_num + 6;
CAN0IF1DB2L = obj_num + 7;
CAN0IF1CM = 0x0087; // Set Direction to Write
// Write TxRqst, all 8 data bytes
CAN0IF1CR = obj_num; // Start command request
while (CAN0IF1CRH & 0x80) {} // Poll on Busy bit
}
//-----------------------------------------------------------------------------
// Interrupt Service Routines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// UART0_Interrupt
//-----------------------------------------------------------------------------
//
// This routine is invoked whenever a character is entered or displayed on the
// Hyperterminal.
//
//-----------------------------------------------------------------------------
INTERRUPT(UART0_ISR, INTERRUPT_UART0)
{
if (RI0 == 1)
{
TX_Ready=1;
RI0 = 0; // Clear interrupt flag
Byte = SBUF0; // Read a character from UART
UART_Buffer[UART_Buffer_Size] = Byte; // Store in array
UART_Buffer_Size++; // Update array's size
}
if (TI0 == 1) // Check if transmit flag is set
{
TI0 = 0; // Clear interrupt flag
if(UART_Buffer_Size<10)
{
UART_Buffer_Size--;
if (UART_Buffer[UART_Buffer_Size-1]==97) // If buffer not empty
{
Byte =65;
}
else if(UART_Buffer[UART_Buffer_Size-1]==98)
{
Byte =66;
}
else
{
Byte=78;
}
SBUF0 = Byte; // Transmit to Hyperterminal
UART_Buffer_Size = 0; // Update counter
memset(UART_Buffer,0,10*sizeof(U8));
}
else
{
UART_Buffer_Size=0; // Update counter
memset(UART_Buffer,0,10*sizeof(U8));
}
}
}
//-----------------------------------------------------------------------------
// End Of File
//----------------------------------------------------------------------------- |