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

📄 spi_ee_int1.c

📁 c8051f020开发板的所有参考程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
// SPI_EE_Int1.c
//-----------------------------------------------------------------------------
// Copyright 2001 Cygnal Integrated Products, Inc.
//
// AUTH: BW
// DATE: 14 SEP 01
//
// This program shows an example of how to interface to an SPI EEPROM using
// the SPI0 interface in interrupt-mode. The SPI EEPROM used here is a 
// Microchip 25LC320 (4k bytes).  The hardware connections are as follows:
//
// P0.0 - TX -- UART used for display/testing purposes
// P0.1 - RX
//
// P0.2 - SCK  (connected to SCK on EEPROM)
// P0.3 - MISO (connected to SI on EEPROM)
// P0.4 - MOSI (connected to SO on EEPROM)
// P0.5 - NSS  (unconnected, but pulled high by on-chip pull-up resistor)
//
// P1.7 - EE_CS (connected to /CS on EEPROM)
//
// Assumes an 22.1184MHz crystal is attached between XTAL1 and XTAL2.
//
// In this example, the attached SPI device is loaded with a test pattern.
// The EEPROM contents are then verified with the test pattern.  If the test
// pattern is verified with no errors, the LED blinks on operation complete.
// Otherwise, the LED stays off.  Progress can also be monitored by a terminal
// connected to UART0 operating at 115.2kbps.
//
// Target: C8051F02x 
// Tool chain: KEIL C51 6.03 / KEIL EVAL C51
//

//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------

#include <c8051f020.h>                 // SFR declarations
#include <stdio.h>

//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F00x
//-----------------------------------------------------------------------------

sfr16 DP       = 0x82;                 // data pointer
sfr16 TMR3RL   = 0x92;                 // Timer3 reload value
sfr16 TMR3     = 0x94;                 // Timer3 counter
sfr16 ADC0     = 0xbe;                 // ADC0 data
sfr16 ADC0GT   = 0xc4;                 // ADC0 greater than window
sfr16 ADC0LT   = 0xc6;                 // ADC0 less than window
sfr16 RCAP2    = 0xca;                 // Timer2 capture/reload
sfr16 T2       = 0xcc;                 // Timer2
sfr16 DAC0     = 0xd2;                 // DAC0 data
sfr16 DAC1     = 0xd5;                 // DAC1 data

//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------

#define     TRUE     1
#define     FALSE    0

#define     SYSCLK   22118400          // SYSCLK frequency in Hz
#define     BAUDRATE 115200            // Baud rate of UART in bps

sbit        LED = P1^6;                // LED='1' means ON
sbit        EE_CS = P1^7;              // EEPROM CS signal

#define     EE_SIZE     4096           // EEPROM size in bytes
#define     EE_READ     0x03           // EEPROM Read command
#define     EE_WRITE    0x02           // EEPROM Write command
#define     EE_WRDI     0x04           // EEPROM Write disable command
#define     EE_WREN     0x06           // EEPROM Write enable command
#define     EE_RDSR     0x05           // EEPROM Read status register
#define     EE_WRSR     0x01           // EEPROM Write status register

//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------

void SYSCLK_Init (void);
void PORT_Init (void);
void UART0_Init (void);
void SPI0_Init (void);
void Timer0_Init (void);
void Timer0_ms (unsigned ms);

unsigned char EE_Read (unsigned Addr);
void EE_Write (unsigned Addr, unsigned char value);

//-----------------------------------------------------------------------------
// Global VARIABLES
//-----------------------------------------------------------------------------

bit EE_Ready = FALSE;                  // semaphore for SPI0/EEPROM
bit EE_WR = FALSE;                     // TRUE = write; FALSE = read
unsigned EE_Addr = 0x0000;             // EEPROM address
unsigned char EE_Data = 0x00;          // EEPROM data

//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------

void main (void) {

   unsigned test_addr;                 // address of EEPROM byte
   unsigned char test_byte;

   WDTCN = 0xde;                       // disable watchdog timer
   WDTCN = 0xad;

   SYSCLK_Init ();                     // initialize oscillator
   PORT_Init ();                       // initialize crossbar and GPIO
   UART0_Init ();                      // initialize UART0
   Timer0_Init ();                     // initialize Timer0

   SPI0_Init ();                       // initialize SPI0

   EA = 1;                             // enable global interrupts

   // fill EEPROM with 0xFF's
   LED = 1;
   for (test_addr = 0; test_addr < EE_SIZE; test_addr++) {
      test_byte = 0xff;
      EE_Write (test_addr, test_byte);

      // print status to UART0
      if ((test_addr % 16) == 0) {
         printf ("\nwriting 0x%04x: %02x ", test_addr, (unsigned) test_byte);
      } else {
         printf ("%02x ", (unsigned) test_byte);
      }
   }

   // verify EEPROM with 0xFF's
   LED = 0;
   for (test_addr = 0; test_addr < EE_SIZE; test_addr++) {
      test_byte = EE_Read (test_addr);

      // print status to UART0
      if ((test_addr % 16) == 0) {
         printf ("\nverifying 0x%04x: %02x ", test_addr, (unsigned) test_byte);
      } else {
         printf ("%02x ", (unsigned) test_byte);
      }
      if (test_byte != 0xFF) {
         printf ("Error at %u\n", test_addr);
         while (1);                    // stop here on error
      }
   }

   // fill EEPROM memory with LSB of EEPROM address.
   LED = 1;
   for (test_addr = 0; test_addr < EE_SIZE; test_addr++) {
      test_byte = test_addr & 0xff;
      EE_Write (test_addr, test_byte);

      // print status to UART0
      if ((test_addr % 16) == 0) {
         printf ("\nwriting 0x%04x: %02x ", test_addr, (unsigned) test_byte);
      } else {
         printf ("%02x ", (unsigned) test_byte);
      }
   }

   // verify EEPROM memory with LSB of EEPROM address
   LED = 0;
   for (test_addr = 0; test_addr < EE_SIZE; test_addr++) {
      test_byte = EE_Read (test_addr);

      // print status to UART0
      if ((test_addr % 16) == 0) {
         printf ("\nverifying 0x%04x: %02x ", test_addr, (unsigned) test_byte);
      } else {
         printf ("%02x ", (unsigned) test_byte);
      }
      if (test_byte != (test_addr & 0xFF)) {
         printf ("Error at %u\n", test_addr);
         while (1);                    // stop here on error
      }
   }

   ET0 = 0;                            // disable Timer0 interrupts

   while (1) {                         // Flash LED when done
      Timer0_ms (100);
      LED = ~LED;
   }
}

//-----------------------------------------------------------------------------
// Subroutines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
//
// This routine initializes the system clock to use an 22.1184 MHz crystal
// as its clock source.
//
void SYSCLK_Init (void)
{
   int i;                              // delay counter

   OSCXCN = 0x67;                      // start external oscillator with
                                       // 22.1184 MHz crystal

   for (i=0; i < 256; i++) ;           // Wait for osc. to start up

   while (!(OSCXCN & 0x80)) ;          // Wait for crystal osc. to settle

   OSCICN = 0x88;                      // select external oscillator as SYSCLK
                                       // source and enable missing clock
                                       // detector
}

//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports
//
void PORT_Init (void)
{
   XBR0   |= 0x06;                     // Enable SPI0 and UART0
   XBR1    = 0x00;
   XBR2    = 0x40;                     // Enable crossbar and weak pull-ups
   P0MDOUT |= 0x15;                    // enable P0.0 (TX), P0.2 (SCK), and 
                                       // P0.4 (MOSI) as push-pull outputs 
   P1MDOUT |= 0xC0;                    // enable P1.6 (LED) and P1.7 (EE_CS)
                                       // as push-pull outputs
}

//-----------------------------------------------------------------------------
// SPI0_Init
//-----------------------------------------------------------------------------
//
// Configure SPI0 for 8-bit, 2MHz SCK, Master mode, interrupt operation, data 
// sampled on 1st SCK rising edge.  SPI0 interrupts are enabled here
//
void SPI0_Init (void)
{
   SPI0CFG = 0x07;                     // data sampled on 1st SCK rising edge
                                       // 8-bit data words

   SPI0CN = 0x03;                      // Master mode; SPI enabled; flags
                                       // cleared
   SPI0CKR = SYSCLK/2/2000000;         // SPI clock <= 2MHz (limited by 
                                       // EEPROM spec.)
   EE_Ready = TRUE;                    // post SPI0/EEPROM available
   EIE1 |= 0x01;                       // enable SPI0 interrupts
}

//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Configure the UART0 using Timer1, for <baudrate> and 8-N-1.
//
void UART0_Init (void)
{
   SCON0  = 0x50;                      // SCON0: mode 1, 8-bit UART, enable RX
   TMOD   = 0x20;                      // TMOD: timer 1, mode 2, 8-bit reload
   TH1    = -(SYSCLK/BAUDRATE/16);     // set Timer1 reload value for baudrate
   TR1    = 1;                         // start Timer1
   CKCON |= 0x10;                      // Timer1 uses SYSCLK as time base
   PCON  |= 0x80;                      // SMOD00 = 1 (disable baud rate 
                                       // divide-by-two)
   TI0    = 1;                         // Indicate TX0 ready
}

//-----------------------------------------------------------------------------
// Timer0_Init
//-----------------------------------------------------------------------------
//
// Configure Timer0 for 16-bit interrupt mode.
//
void Timer0_Init (void)
{
   TCON  &= ~0x30;                     // STOP Timer0 and clear overflow flag
   TMOD  &= ~0x0f;                     // configure Timer0 to 16-bit mode
   TMOD  |=  0x01;
   CKCON |=  0x08;                     // Timer0 counts SYSCLKs
}

//-----------------------------------------------------------------------------
// Timer0_ms
//-----------------------------------------------------------------------------
//
// Configure Timer0 to delay <ms> milliseconds before returning.
//
void Timer0_ms (unsigned ms)
{
   unsigned i;                         // millisecond counter

   TCON  &= ~0x30;                     // STOP Timer0 and clear overflow flag
   TMOD  &= ~0x0f;                     // configure Timer0 to 16-bit mode
   TMOD  |=  0x01;
   CKCON |=  0x08;                     // Timer0 counts SYSCLKs

   for (i = 0; i < ms; i++) {          // count milliseconds
      TR0 = 0;                         // STOP Timer0
      TH0 = (-SYSCLK/1000) >> 8;       // set Timer0 to overflow in 1ms
      TL0 = -SYSCLK/1000;
      TR0 = 1;                         // START Timer0
      while (TF0 == 0);                // wait for overflow
      TF0 = 0;                         // clear overflow indicator
   }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -