?? can_block_transmit_f040.c
字號:
//-----------------------------------------------------------------------------
// CAN_block_transmit.c
//-----------------------------------------------------------------------------
// Copyright (C) 2004 Silicon Laboratories, Inc.
//
// AUTH: LS
// DATE: 25 APR 02
//
// This program configures the external memory interface to log
// temperature data with ADC0 to XRAM, then transmit the data
// via the CAN bus. Uses a FIFO buffer in the CAN msg RAM.
//
// ADC Voltage Reference: Ensure jumper is installed on J22 (pin3 to pin4).
//
// Developed using two C8051F040TB target board's.
//
// Program one target board with CAN_block_receive.c and another
// target board with CAN_block_transmit.c. Connect the boards with
// the CAN cable provided in the development kit. Run the code on
// both devices and one device will log temperature data, stors the
// data, and then tranfer the data to the other board over the CAN bus.
// The CAN uses the FIFO mode (concantonates message objects with the
// same message ID/Arbitration number). See page 32 of the Bosch CAN
// User's Guide for more information concerning FIFO buffers.
//
//
// Target: C8051F04x
// Tool chain: KEIL C51 6.03 / KEIL EVAL C51
//
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <c8051f040.h> // SFR declarations
#include <stdio.h>
/////////////////////////////////////////////////////////////////////////////////////
//CAN Protocol Register Index for CAN0ADR, from TABLE 18.1 of the C8051F040 datasheet
/////////////////////////////////////////////////////////////////////////////////////
#define CANCTRL 0x00 //Control Register
#define CANSTAT 0x01 //Status register
#define ERRCNT 0x02 //Error Counter Register
#define BITREG 0x03 //Bit Timing Register
#define INTREG 0x04 //Interrupt Low Byte Register
#define CANTEST 0x05 //Test register
#define BRPEXT 0x06 //BRP Extension Register
/////////////////////////////////////////////////////////////////////////////////
//IF1 Interface Registers
/////////////////////////////////////////////////////////////////////////////////
#define IF1CMDRQST 0x08 //IF1 Command Rest Register
#define IF1CMDMSK 0x09 //IF1 Command Mask Register
#define IF1MSK1 0x0A //IF1 Mask1 Register
#define IF1MSK2 0x0B //IF1 Mask2 Register
#define IF1ARB1 0x0C //IF1 Arbitration 1 Register
#define IF1ARB2 0x0D //IF1 Arbitration 2 Register
#define IF1MSGC 0x0E //IF1 Message Control Register
#define IF1DATA1 0x0F //IF1 Data A1 Register
#define IF1DATA2 0x10 //IF1 Data A2 Register
#define IF1DATB1 0x11 //IF1 Data B1 Register
#define IF1DATB2 0x12 //IF1 Data B2 Register
/////////////////////////////////////////////////////////////////////////////////
//IF2 Interface Registers
/////////////////////////////////////////////////////////////////////////////////
#define IF2CMDRQST 0x20 //IF2 Command Rest Register
#define IF2CMDMSK 0x21 //IF2 Command Mask Register
#define IF2MSK1 0x22 //IF2 Mask1 Register
#define IF2MSK2 0x23 //IF2 Mask2 Register
#define IF2ARB1 0x24 //IF2 Arbitration 1 Register
#define IF2ARB2 0x25 //IF2 Arbitration 2 Register
#define IF2MSGC 0x26 //IF2 Message Control Register
#define IF2DATA1 0x27 //IF2 Data A1 Register
#define IF2DATA2 0x28 //IF2 Data A2 Register
#define IF2DATB1 0x29 //IF2 Data B1 Register
#define IF2DATB2 0x2A //IF2 Data B2 Register
/////////////////////////////////////////////////////////////////////////////////
//Message Handler Registers
/////////////////////////////////////////////////////////////////////////////////
#define TRANSREQ1 0x40 //Transmission Rest1 Register
#define TRANSREQ2 0x41 //Transmission Rest2 Register
#define NEWDAT1 0x48 //New Data 1 Register
#define NEWDAT2 0x49 //New Data 2 Register
#define INTPEND1 0x50 //Interrupt Pending 1 Register
#define INTPEND2 0x51 //Interrupt Pending 2 Register
#define MSGVAL1 0x58 //Message Valid 1 Register
#define MSGVAL2 0x59 //Message Valid 2 Register
/////////////////////////////////////////////////////////////////////////////////
//Global Variables
/////////////////////////////////////////////////////////////////////////////////
char status;
int i;
int StatusCopy;
int MsgIntNum;
sbit BUTTON = P3^7;
sbit LED = P1^6;
int i=0;
//////////////////////////////////////////////////////////////////////////////////
// Function PROTOTYPES
//////////////////////////////////////////////////////////////////////////////////
// Initialize Message Object
void SYSCLK_Init (void);
void PORT_Init (void);
void ADC0_Init (void);
void Timer2_Init (void);
void config_CAN_timing (void);
void clear_msg_objects (void);
void start_CAN (void);
void stop_CAN (void);
void test_reg_write (char test);
void get_samples (void);
void init_FIFO_Buffer (void);
void transmit_templog (void);
void transmit_message (char MsgNum);
void transmit_FIFO_block (void);
//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F04x
//-----------------------------------------------------------------------------
//sfr16 DP = 0x82; // data pointer
sfr16 RCAP2 = 0xCA; // Timer2 reload/capture value
//sfr16 RCAP3 = 0xCA; // Timer3 reload/capture value
//sfr16 RCAP4 = 0xCA; // Timer4 reload/capture value
sfr16 TMR2 = 0xCC; // Timer2 counter/timer
//sfr16 TMR3 = 0xCC; // Timer3 counter/timer
//sfr16 TMR4 = 0xCC; // Timer4 counter/timer
sfr16 ADC0 = 0xBE; // ADC0 data
//sfr16 ADC0GT = 0xC4; // ADC0 greater than window
//sfr16 ADC0LT = 0xC6; // ADC0 less than window
//sfr16 DAC0 = 0xD2; // DAC0 data
//sfr16 DAC1 = 0xD2; // DAC1 data
sfr16 CAN0DAT = 0xD8; // CAN data window
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define SYSCLK 22118400 // SYSCLK frequency in Hz
#define BAUDRATE 115200 // Baud rate of UART in bps
#define numSamples 1024 // Number of ADC0 samples
#define numBlocks numSamples/128 // Number of FIFO blocks
#define fifoSize 32 // Desired number of msg obj's to use in FIFO block
#define firstMsg 1 // First desired Msg Object's number in FIFO Buffer
//-----------------------------------------------------------------------------
// Global VARIABLES
//-----------------------------------------------------------------------------
// xram memory array for logging temp samples
unsigned int xdata templog [numSamples];
//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
void main (void) {
WDTCN = 0xde; // disable watchdog timer
WDTCN = 0xad;
SYSCLK_Init (); // initialize oscillator
PORT_Init (); // initialize crossbar and GPIO
ADC0_Init();
init_FIFO_Buffer (); // initialize CAN FIFO buffer
start_CAN (); // start CAN controller
SFRPAGE = CONFIG_PAGE;
EIE2 = 0x02; // Enable ADC0 EOC interrupt
IE = 0x80; // Global enable interrupts
get_samples ();
transmit_templog ();
while (1);
}
void get_samples (void)
{
SFRPAGE = ADC0_PAGE;
ADC0CN |= 0x80; // start ADC0
while ((ADC0CN & 0x80)!= 0); // Wait for all samples to be logged
}
void transmit_message (char MsgNum)
{
static int k = 0;
int i;
SFRPAGE = CAN0_PAGE;
CAN0ADR = IF1CMDMSK; // Point to Command Mask 1
CAN0DAT = 0x0087; // Config to WRITE to CAN RAM, write data bytes, set TXrqst/NewDat, Clr IntPnd
CAN0ADR = IF1ARB2; // Point to Arbitration2 register
CAN0DATH |= 0x80;
CAN0ADR = IF1DATA1; // Point to 1st byte of Data Field
for (i=0;i<4;i++) {
CAN0DAT = templog[k]; // Autoincrement through IF data bytes
k++;
}
CAN0ADR = IF1CMDRQST; // Point to Command Request Reg.
CAN0DATL = MsgNum; // Move new data for TX to Msg Obj "MsgNum"
}
void transmit_FIFO_block (void)
{
char blockIndex = firstMsg;
int l;
for (l=0;l<fifoSize;l++){
transmit_message (blockIndex);
blockIndex++;
}
SFRPAGE = CAN0_PAGE;
CAN0ADR = TRANSREQ2;
while ((CAN0DATH & 0x80) != 0) {}
}
void transmit_templog (void)
{
int l;
for (l=0;l<numBlocks;l++) {
transmit_FIFO_block ();
}
}
//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
//
// This routine initializes the system clock to use an 22.1184MHz crystal
// as its clock source.
//
void SYSCLK_Init (void)
{
int i; // delay counter
SFRPAGE = CONFIG_PAGE; // set SFR page for oscillatoe config
OSCXCN = 0x67; // start external oscillator with
// 22.1184MHz crystal
for (i=0; i < 256; i++) ; // wait for oscillator to start
while (!(OSCXCN & 0x80)) ; // Wait for crystal osc. to settle
CLKSEL = 0x01; // select external oscillator as SYSCLK
// source and enable missing clock
// detector
}
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports
//
void PORT_Init (void)
{
SFRPAGE = CONFIG_PAGE;
XBR2 |= 0x40; // Enable crossbar and weak pull-ups
XBR3 = 0x80; // Configure CAN TX pin (CTX) as push-pull (digital output)
P1MDOUT |= 0x40; // enable LED as push-pull output
}
//Init ADC0 to measure temp sensor
void ADC0_Init (void)
{
SFRPAGE = ADC0_PAGE;
AMX0CF = 0x00;
AMX0SL = 0x08; // Select AIN0.0 for test input
ADC0CF = 0x50; // Gain=1, Fsar=2.2MHz
ADC0CN = 0x4C; // Low-power track, track/conv upon timer2 OV
REF0CN = 0x07; // internal ref & temp sensor enabled
Timer2_Init (); // Init T2 for sample rate
}
void Timer2_Init (void)
{
SFRPAGE = TMR2_PAGE;
TMR2CF = 0x08; // T2 timebase -> SYSCLK
RCAP2 = (-5000); // Configure reload for 8kHz OV rate
TMR2CN = 0x04; // Timer/reload mode, start T2
}
void ADC0_ISR (void) interrupt 15 using 3
{
static int i = 0;
if (i < numSamples)
{
templog[i] = ADC0;
i++;
AD0INT = 0;
} else {
ADC0CN &= ~(0x80);
AD0INT = 0; }
}
//////////////////////////////////////////////////////////////////////////////////
//CAN Functions
//////////////////////////////////////////////////////////////////////////////////
//Initialize Message Objects for FIFO Buffer
void init_FIFO_Buffer (void)
{
char msgNum;
SFRPAGE = CAN0_PAGE;
for (msgNum=firstMsg; msgNum<(fifoSize+1); msgNum++){
CAN0ADR = IF1CMDMSK; // Point to Command Mask 1
CAN0DAT = 0x00B3; // Set to WRITE, and alter all Msg Obj except ID MASK bits
CAN0ADR = IF1ARB1; // Point to arbitration1 register
CAN0DAT = 0x0000; // Set arbitration1 ID to highest priority
CAN0DAT = 0xA000; // Autoincrement to Arb2 high byte: no extended ID, Dir = WRITE
CAN0DAT = 0x0088; // Msg Cntrl: DLC = 8, remote frame function not enabled
CAN0ADR = IF1CMDRQST; // Point to Command Request reg.
CAN0DATL = msgNum; // Select Msg Obj passed into function parameter list --initiates write to Msg Obj
// 3-6 CAN clock cycles to move IF reg contents to the Msg Obj in CAN RAM.
}
}
//Start CAN
void start_CAN (void)
{
SFRPAGE = CAN0_PAGE;
CAN0CN |= 0x0E; //Enables Int's, status ints
CAN0CN &= ~0x01; //Clear the INIT bit starts state machine
}
//////////////////////////////////////////////////////////////////////////////////
//Interrupt Service Routine
//////////////////////////////////////////////////////////////////////////////////
void ISRname (void) interrupt 19
{
status = CAN0STA;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -