⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 can_block_transmit_f040.c

📁 This program configures the external memory interface and CAN to receieve data in a FIFO buffer and
💻 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 + -