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

📄 spi_ee_f30x.c

📁 spi协议的驱动程序源代码
💻 C
字号:
//-----------------------------------------------------------------------------
// SPI_EE_F30x.c
//-----------------------------------------------------------------------------
// Copyright 2001 Cygnal Integrated Products, Inc.
//
// AUTH: BD
// DATE: 14 DEC 01
//
// This program demonstrates how a collection of SPI master routines for the
// 8051F30x devices can be used in a C program.
//
// In this example, a Microchip 25LC320 4k X 8 Serial EEPROM is interfaced to a
// SPI master device implemented in the C8051F30x. The EEPROM is written with
// two test patterns: 1) all locations are 0xFF and 2) each location is written
// with the LSB of the corresponding address.
// The EEPROM contents are then verified with the test patterns. If the test
// patterns are verified with no errors, the LED blinks on operation completion.
// Otherwise, the LED stays off. Progress can also be monitored by a terminal
// connected to UART0 operating at 115.2kbps.
//
// For this code to be functional, *one* of the following files should also be
// compiled or assembled, and the resulting object file must be linked to the
// object file produced from this code:
//
// SPI_MODE0.c Mode 0 SPI Master Implementation in C
// SPI_MODE0.asm Mode 0 SPI Master Implementation in Assembly
// SPI_MODE3.c Mode 3 SPI Master Implementation in C
// SPI_MODE3.asm Mode 3 SPI Master Implementation in Assembly
//
// This EEPROM’s serial port will only operate with a Mode 0 or Mode 3
// SPI configuration.
//
// Target: C8051F30x
// Tool chain: KEIL C51 6.03 / KEIL EVAL C51
//
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <c8051f300.h> // SFR declarations
#include <stdio.h> // Standard I/O
#include “SPI_defs.h” // SPI port definitions
//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for ‘F30x
//-----------------------------------------------------------------------------
sfr16 DP = 0x82; // data pointer
sfr16 TMR2RL = 0xca; // Timer2 reload value
sfr16 TMR2 = 0xcc; // Timer2 counter
sfr16 PCA0CP1 = 0xe9; // PCA0 Module 1 Capture/Compare
sfr16 PCA0CP2 = 0xeb; // PCA0 Module 2 Capture/Compare
sfr16 PCA0 = 0xf9; // PCA0 counter
sfr16 PCA0CP0 = 0xfb; // PCA0 Module 0 Capture/Compare
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define SYSCLK 24500000 // SYSCLK frequency in Hz
#define BAUDRATE 115200 // Baud rate of UART in bps
#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
sbit LED = P0^6; // LED Indicator
//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
void PORT_Init (void); // Port I/O configuration
void SYSCLK_Init (void); // SYSCLK Initialization
void UART0_Init (void); // UART0 Initialization
extern char SPI_Transfer (char); // SPI Transfer routine
void Timer0_ms (unsigned ms);
void Timer0_us (unsigned us);
unsigned char EE_Read (unsigned Addr);
void EE_Write (unsigned Addr, unsigned char value);
//-----------------------------------------------------------------------------
// Global VARIABLES
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
void main (void) {
unsigned EE_Addr; // address of EEPROM byte
unsigned char test_byte;
// Disable Watchdog timer
PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer
// enable)
SYSCLK_Init (); // initialize oscillator
PORT_Init (); // initialize ports and GPIO
UART0_Init (); // initialize UART0
EA = 1; // enable global interrupts
SCK = 0;
// fill EEPROM with 0xFF’s
LED = 1;
for (EE_Addr = 0; EE_Addr < EE_SIZE; EE_Addr++)
{
test_byte = 0xff;
EE_Write (EE_Addr, test_byte);
// print status to UART0
if ((EE_Addr % 16) == 0)
{
printf (“\nwriting 0x%04x: %02x “, EE_Addr, (unsigned) test_byte);
}
else
{
printf (“%02x “, (unsigned) test_byte);
}
}
// verify EEPROM with 0xFF’s
LED = 0;
for (EE_Addr = 0; EE_Addr < EE_SIZE; EE_Addr++)
{
test_byte = EE_Read (EE_Addr);
// print status to UART0
if ((EE_Addr % 16) == 0)
{
printf (“\nverifying 0x%04x: %02x “, EE_Addr, (unsigned) test_byte);
}
else
{
printf (“%02x “, (unsigned) test_byte);
}
if (test_byte != 0xFF)
{
printf (“Error at %u\n”, EE_Addr);
while (1); // stop here on error
}
}
LED = 1;
for (EE_Addr = 0; EE_Addr < EE_SIZE; EE_Addr++)
{
test_byte = EE_Addr & 0xff;
EE_Write (EE_Addr, test_byte);
// print status to UART0
if ((EE_Addr % 16) == 0)
{
printf (“\nwriting 0x%04x: %02x “, EE_Addr, (unsigned) test_byte);
}
else
{
printf (“%02x “, (unsigned) test_byte);
}
}
// verify EEPROM memory with LSB of EEPROM address
LED = 0;
for (EE_Addr = 0; EE_Addr < EE_SIZE; EE_Addr++)
{
test_byte = EE_Read (EE_Addr);
// print status to UART0
if ((EE_Addr % 16) == 0)
{
printf (“\nverifying 0x%04x: %02x “, EE_Addr, (unsigned) test_byte);
}
else
{
printf (“%02x “, (unsigned) test_byte);
}
if (test_byte != (EE_Addr & 0xFF))
{
printf (“Error at %u\n”, EE_Addr);
while (1); // stop here on error
}
}
while (1)
{ // Flash LED when done
Timer0_ms (100);
LED = ~LED;
}
}
//-----------------------------------------------------------------------------
// Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports.
// P0.0 - MOSI (push-pull)
// P0.1 - MISO
// P0.2 - SCK (push-pull)
// P0.3 - NSS (push-pull)
// P0.4 - UART TX (push-pull)
// P0.5 - UART RX
// P0.6 - LED
// P0.7 -
//
void PORT_Init (void)
{
XBR0 = 0x0F; // skip SPI pins in XBAR
XBR1 = 0x03; // UART0 TX and RX pins enabled
XBR2 = 0x40; // Enable crossbar and weak pull-ups
P0MDOUT |= 0x5D; // enable TX0, MOSI, SCK, LED and NSS as
// push-pull outputs
}
//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
//
// This routine initializes the system clock to use the internal 24.5 MHz clock
// as its clock source.
//
void SYSCLK_Init (void)
{
OSCICN = 0x07; // select internal oscillator as SYSCLK
// source
}
//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1.
//
void UART0_Init (void)
{
SCON0 = 0x10; // SCON0: 8-bit variable bit rate
// level of STOP bit is ignored
// RX enabled
// ninth bits are zeros
// clear RI0 and TI0 bits
if (SYSCLK/BAUDRATE/2/256 < 1)
{
TH1 = -(SYSCLK/BAUDRATE/2);
CKCON &= ~0x13;
CKCON |= 0x10; // T1M = 1; SCA1:0 = xx
}
else if (SYSCLK/BAUDRATE/2/256 < 4)
{
TH1 = -(SYSCLK/BAUDRATE/2/4);
CKCON &= ~0x13;
CKCON |= 0x01; // T1M = 0; SCA1:0 = 01
}
else if (SYSCLK/BAUDRATE/2/256 < 12)
{
TH1 = -(SYSCLK/BAUDRATE/2/12);
CKCON &= ~0x13; // T1M = 0; SCA1:0 = 00
}
else
{
TH1 = -(SYSCLK/BAUDRATE/2/48);
CKCON &= ~0x13;
CKCON |= 0x02; // T1M = 0; SCA1:0 = 10
}
TL1 = 0xff; // set Timer1 to overflow immediately
TMOD |= 0x20; // TMOD: timer 1 in 8-bit autoreload
TMOD &= ~0xD0; // mode
TR1 = 1; // START Timer1
TI0 = 1; // Indicate TX0 ready
}
//-----------------------------------------------------------------------------
// 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
}
}
//-----------------------------------------------------------------------------
// Timer0_us
//-----------------------------------------------------------------------------
//
// Configure Timer0 to delay <us> microseconds before returning.
//
void Timer0_us (unsigned us)
{
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 < us; i++) { // count microseconds
TR0 = 0; // STOP Timer0
TH0 = (-SYSCLK/1000000) >> 8; // set Timer0 to overflow in 1us
TL0 = -SYSCLK/1000000;
TR0 = 1; // START Timer0
while (TF0 == 0); // wait for overflow
TF0 = 0; // clear overflow indicator
}
}
//-----------------------------------------------------------------------------
// EE_Read
//-----------------------------------------------------------------------------
//
// This routine reads and returns a single EEPROM byte whose address is
// given in <Addr>.
//
unsigned char EE_Read (unsigned Addr)
{
unsigned char retval; // value to return
NSS = 0; // select EEPROM
Timer0_us (1); // wait at least 250ns (CS setup time)
// transmit READ opcode
retval = SPI_Transfer(EE_READ);
// transmit Address MSB-first
retval = SPI_Transfer((Addr & 0xFF00) >> 8); // transmit MSB of address
retval = SPI_Transfer((Addr & 0x00FF)); // transmit LSB of address
// initiate dummy transmit to read data
retval = SPI_Transfer(0x00);
Timer0_us (1); // wait at least 250ns (CS hold time)
NSS = 1; // de-select EEPROM
Timer0_us (1); // wait at least 500ns (CS disable time)
return retval;
}
//-----------------------------------------------------------------------------
// EE_Write
//-----------------------------------------------------------------------------
//
// This routine writes a single EEPROM byte <value> to address <Addr>.
//
void EE_Write (unsigned Addr, unsigned char value)
{
unsigned char retval; // return value from SPI
NSS = 0; // select EEPROM
Timer0_us (1); // wait at least 250ns (CS setup time)
// transmit WREN (Write Enable) opcode
retval = SPI_Transfer(EE_WREN);
Timer0_us (1); // wait at least 250ns (CS hold time)
NSS = 1; // de-select EEPROM to set WREN latch
Timer0_us (1); // wait at least 500ns (CS disable
// time)
NSS = 0; // select EEPROM
Timer0_us (1); // wait at least 250ns (CS setup time)
// transmit WRITE opcode
retval = SPI_Transfer(EE_WRITE);
// transmit Address MSB-first
retval = SPI_Transfer((Addr & 0xFF00) >> 8); // transmit MSB of address
retval = SPI_Transfer((Addr & 0x00FF)); // transmit LSB of address
// transmit data
retval = SPI_Transfer(value);
Timer0_us (1); // wait at least 250ns (CS hold time)
NSS = 1; // deselect EEPROM (initiate EEPROM
// write cycle)
// now poll Read Status Register (RDSR) for Write operation complete
do {
Timer0_us (1); // wait at least 500ns (CS disable
// time)
NSS = 0; // select EEPROM to begin polling
Timer0_us (1); // wait at least 250ns (CS setup time)
retval = SPI_Transfer(EE_RDSR);
retval = SPI_Transfer(0x00);
Timer0_us (1); // wait at least 250ns (CS hold
// time)
NSS = 1; // de-select EEPROM
} while (retval & 0x01); // poll until WIP (Write In
// Progress) bit goes to ‘0’
Timer0_us (1); // wait at least 500ns (CS disable
// time)
}

⌨️ 快捷键说明

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