?? can_block_receive_f040.c
字號:
//-----------------------------------------------------------------------------
// CAN_block_receive.c
//-----------------------------------------------------------------------------
// Copyright (C) 2004 Silicon Laboratories, Inc.
//
// AUTH: LS
// DATE: 30 APR 02
//
// This program configures the external memory interface and CAN
// to receieve data in a FIFO buffer and store the data in XRAM.
// Meant to receive data from another CAN device.
//
// 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.
//
//
// CAN RAM FIFO buffer uses all 32 message objects.
//
// Developed using two C8051F040TB target board's.
//
// Other Target board transmits its die temperature after storing data in
// XRAM.
//
// Target: C8051F04x
// Tool chain: KEIL C51 6.03 / KEIL EVAL C51, Silicon Labs IDE.
//
//-----------------------------------------------------------------------------
// 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
//////////////////////////////////////////////////////////////////////////////////
void SYSCLK_Init (void);
void PORT_Init (void);
void config_CAN_timing (void);
void start_CAN (void);
void stop_CAN (void);
void test_reg_write (char test);
void init_FIFO_Buffer (void);
void init_msg_object_RX (void);
void downloadFIFO (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
#define lastMsg 32 // Last desired Mg Obj number in FIFO
#define RAM_BANK 0x20; // bank select bit is P4^5
#define RAM_CS 0x10; // chip select bit is P4^4
//-----------------------------------------------------------------------------
// 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
init_FIFO_Buffer (); // initialize CAN FIFO buffer
init_msg_object_RX (); // initialize last msg object in FIFO
SFRPAGE = CONFIG_PAGE;
EIE2 = 0x20; // Enable CAN int's
EA = 1; // Global enable int's
start_CAN (); // start CAN controller
while (1);
}
//-----------------------------------------------------------------------------
// 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 oscillator 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
}
//////////////////////////////////////////////////////////////////////////////////
//CAN Functions
//////////////////////////////////////////////////////////////////////////////////
//Initialize Message Objects for FIFO Buffer
void init_FIFO_Buffer (void)
{
char msgNum;
SFRPAGE = CAN0_PAGE;
CAN0ADR = IF1CMDMSK; // Point to Command Mask 1
CAN0DAT = 0x00B8; // 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 = 0x8000; // Autoincrement to Arb2 high byte: no extended ID, Dir = WRITE
CAN0DAT = 0x0000;//0x0008? // Msg Cntrl: DLC = 8, remote frame function not enabled
for (msgNum=firstMsg; msgNum<fifoSize; msgNum++){
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.
}
}
//Initialize Last Message Object for RX FIFO buffer
void init_msg_object_RX (void)
{
SFRPAGE = CAN0_PAGE;
CAN0ADR = IF2CMDMSK; // Point to Command Mask 1
CAN0DAT = 0x00B8; // Set to WRITE, and alter all Msg Obj except ID MASK and data bits
CAN0ADR = IF2ARB1; // Point to arbitration1 register
CAN0DAT = 0x0000; // Set arbitration1 ID to "0"
CAN0DAT = 0x8000; // Arb2 high byte:Set MsgVal bit, no extended ID, Dir = RECEIVE
CAN0DAT = 0x0480; // Msg Cntrl: set RX IE, remote frame function not enabled
CAN0ADR = IF2CMDRQST; // Point to Command Request reg.
CAN0DATL = lastMsg; // Select Msg Obj passed into function parameter list --initiates write to Msg Obj
// 3-6 CAN clock cycles to move IF register contents to the Msg Obj in CAN RAM.
}
//Start CAN
void start_CAN (void)
{
SFRPAGE = CAN0_PAGE;
CAN0CN |= 0x02; //Enables Int's, status ints
CAN0CN &= ~0x01; //Clear the INIT bit starts state machine
}
//////////////////////////////////////////////////////////////////////////////////
//Interrupt Service Routine
//////////////////////////////////////////////////////////////////////////////////
void ISRname (void) interrupt 19
{
status = CAN0STA;
if ((status&0x10) != 0){
downloadFIFO ();
}
}
void downloadFIFO (void){
static int k = 0;
char i;
char MsgNum = firstMsg;
SFRPAGE = CAN0_PAGE;
CAN0ADR = IF2CMDMSK;
CAN0DAT = 0x003F; // Read arb,conrol,clear int,clear NewDat, get dataA/B
for (MsgNum=firstMsg; MsgNum < (fifoSize+1); MsgNum++){
CAN0ADR = IF2CMDRQST;
CAN0DATL = MsgNum; // transfer Msg Obj to IF2 registers
CAN0ADR = IF2MSGC;
if ((CAN0DAT&0x8000)!= 0){ // Is NewDat set?
CAN0ADR = IF2DATA1; // NewDat set, so get data from Msg Obj
for (i=0;i<4;i++){
templog[k] = CAN0DAT; // Move four data words into xram data array
k++;
}
}
else {MsgNum--;} // NewDat was not set, reload Msg Obj and check again
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -