📄 f50x_can0_transmit.c
字号:
//-----------------------------------------------------------------------------
// F50x_CAN0_Transmit.c
//-----------------------------------------------------------------------------
// Copyright 2008 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// This program transmits data to another CAN node using a configurable number
// of message objects and datasize. The message identifier is set based on the
// message object number. The corresponding receive firmware is
// F50x_CAN0_Receive.c. The following two #defines should be set to the
// same values in both the transmit and receive code:
//
// #define MESSAGE_OBJECTS
// #define MESSAGE_SIZE
//
// #define TX_COMPLETE_MASK should also be set. See definition for details
//
// The purpose of this example is to show how to initialize a message object
// for transfer and how to handle certain error conditions.
//
// How To Test:
//
// 1) Verify the LED and switch pin jumpers are populated
// (J19 for device A and J11 for device B).
//
// 2) Make sure the CAN jumpers in J17 (for A side) and J26 (for B side)
// are connected.
//
// 3) Download the code to a F50x-TB (either device A or device B) that is
// connected as above to another device running the F50x_CAN0_Receive
// code.
//
// 4) Run the code on the Receiver first, then run the code on the Transmitter.
//
// 5) After all the transmissions are complete, the LED will be lit if
// the transfers were sucessful.
//
// Target: C8051F500 (Side A of a C8051F500-TB)
// Tool chain: Keil C51 8.0 / Keil EVAL C51
// Command Line: None
//
// Release 1.2 / 18 JUL 2008 (ADT)
// - Removed Oscillator calibration
//
// Release 1.1 / 11 JUN 2008 (ADT)
// - Edited Formatting
//
// Release 1.0 / 11 MAR 2008 (GP)
// - Initial Revision
//
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include "compiler_defs.h"
#include "C8051F500_defs.h" // SFR declarations
//-----------------------------------------------------------------------------
// Function Prototypes
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void);
void PORT_Init (void);
void CAN0_Init (void);
void CAN0_TransferMO (U8 obj_num);
INTERRUPT_PROTO (CAN0_ISR, INTERRUPT_CAN0);
//-----------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------
#define SYSCLK 24000000 // System clock speed in Hz
#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
#define TX_COMPLETE_MASK 0xFFFFFFFF // Set this to (2^MESSAGE_OBJECTS - 1)
//-----------------------------------------------------------------------------
// 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
UU32 CAN_TX_COMPLETE; // Bit status register that is updated
// when a TX complete is received for
// a specific message object. Should be
// equal to TX_COMPLETE_MASK when done
//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
void main (void)
{
U16 iter; // Loop counter
SFRPAGE = ACTIVE_PAGE; // Set for PCA0MD
PCA0MD &= ~0x40; // Disable Watchdog Timer
OSCILLATOR_Init (); // Initialize oscillator
PORT_Init (); // Initialize crossbar and GPIO
CAN0_Init (); // Start CAN peripheral
CAN_TX_COMPLETE.U32 = 0x0000; // Initialize as no messages transmitted
EIE2 |= 0x02; // Enable CAN interupts
EA = 1; // Enable global interrupts
// CAN0_TransferMO will automatically generate data and send it using the
// specified Message Object. The receive code knows what data to expect
// for each Message Object and performs the data verification.
LED = 0;
for (iter = 0; iter < MESSAGE_OBJECTS; iter++)
{
CAN0_TransferMO (iter);
}
// Check Transmission Requests registers to wait for completion
SFRPAGE = CAN0_PAGE;
while (CAN0TR1 | CAN0TR2)
{
LED = !LED;
for (iter = 0; iter < 65000; iter++);
}
// Check global variable that all transfers completed without error
if (CAN_TX_COMPLETE.U32 != TX_COMPLETE_MASK)
{
CAN_ERROR = 1;
}
// Once all transmissions are complete, turn off the LED or leave it on
// based on the error status
if (CAN_ERROR)
{ // If any errors occurred
LED = 0; // Turn off LED
}
else
{
LED = 1; // No error, so keep LED on
}
while (1);
}
//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// OSCILLATOR_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Initialize the internal oscillator to 24 MHz
//
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void)
{
U8 SFRPAGE_save = SFRPAGE;
SFRPAGE = CONFIG_PAGE;
OSCICN = 0x87; // Set internal oscillator divider to 1
SFRPAGE = SFRPAGE_save;
}
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This function configures the crossbar and ports pins.
//
// P0.6 digital push-pull CAN TX
// P0.7 digital open-drain CAN RX
//
// P1.3 digital push-pull LED
//
//-----------------------------------------------------------------------------
void PORT_Init (void)
{
U8 SFRPAGE_save = SFRPAGE;
SFRPAGE = CONFIG_PAGE; // Port SFR's on Configuration page
P0MDOUT |= 0x40; // P0.6 (CAN0 TX) is push-pull
P1MDOUT |= 0x08; // P1.3 (LED) is push-pull
XBR0 = 0x02; // Enable CAN0 on Crossbar
XBR2 = 0x40; // Enable Crossbar and weak pull-ups
SFRPAGE = SFRPAGE_save;
}
//-----------------------------------------------------------------------------
// CAN0_Init
//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -