📄 f500_spi0_eeprom_polled_mode.c
字号:
//-----------------------------------------------------------------------------
// F500_SPI0_EEPROM_Polled_Mode.c
//-----------------------------------------------------------------------------
// Copyright 2008 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// This program accesses a SPI EEPROM using polled mode access. The 'F500 MCU
// is configured in 4-wire Single Master Mode, and the EEPROM is the only
// slave device connected to the SPI bus. The read/write operations are
// tailored to access a Microchip 4 kB EEPROM 25LC320. The relevant hardware
// connections of the 'F500 MCU are shown here:
//
// P0.0 - SPI SCK (digital output, push-pull)
// P0.1 - SPI MISO (digital input, open-drain)
// P0.2 - SPI MOSI (digital output, push-pull)
// P0.3 - SPI NSS (digital output, push-pull)
// P0.4 - UART TXD (digital output, push-pull)
// P0.5 - UART RXD (digital input, open-drain)
// P1.3 - LED (digital output, push-pull)
//
//
// How To Test:
//
// Method1:
// 1) Download the code to a 'F500 device that is connected as above.
// 2) Run the code. The LED will blink fast during the write/read/verify
// operations.
// 3) If the verification passes, the LED will blink slowly. If it fails,
// the LED will be OFF.
//
// Method2 (optional):
// 1) Download code to a 'F500 device that is connected as above
// 2) Connect USB cable from the development board to a PC
// 3) On the PC, open HyperTerminal (or any other terminal program) and connect
// to the USB port (virtual com port) at <BAUDRATE>, 8 data bits, no parity,
// 1 stop bit, no flow control.
// 4) HyperTerminal will print the progress of the write/read operation, and in
// the end will print the test result as pass or fail. Additionally, if the
// verification passes, the LED will blink slowly. If it fails, the LED will
// be OFF.
//
//
// Target: C8051F500 (Side A of a C8051F500-TB)
// Tool chain: Keil C51 8.0 / Keil EVAL C51
// Command Line: None
//
// Release 1.0 / 06 MAR 2008 (GP)
// -Initial Revision
//
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <compiler_defs.h>
#include <C8051F500_defs.h> // SFR declarations
#include <stdio.h> // printf is declared here
//-----------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------
#define BAUDRATE 115200 // Baud rate of UART in bps
#define SYSCLK 24000000 // Internal oscillator frequency in Hz
// Microchip 25AA320 Slave EEPROM Parameters
#define F_SCK_MAX 2000000 // Max SCK freq (Hz)
#define T_NSS_DISABLE_MIN 500 // Min NSS disable time (ns)
#define EEPROM_CAPACITY 4096 // EEPROM capacity (bytes)
// EEPROM Instruction Set
#define EEPROM_CMD_READ 0x03 // Read Command
#define EEPROM_CMD_WRITE 0x02 // Write Command
#define EEPROM_CMD_WRDI 0x04 // Reset Write Enable Latch Command
#define EEPROM_CMD_WREN 0x06 // Set Write Enable Latch Command
#define EEPROM_CMD_RDSR 0x05 // Read Status Register Command
#define EEPROM_CMD_WRSR 0x01 // Write Status Register Command
SBIT (LED, SFR_P1, 3); // LED==1 means ON
//-----------------------------------------------------------------------------
// Function Prototypes
//-----------------------------------------------------------------------------
void PCA0_Init (void);
void OSCILLATOR_Init (void);
void PORT_Init (void);
void TIMER2_Init (void);
void UART0_Init (void);
void SPI0_Init (void);
void Init_Device (void);
void Delay_us (U8 time_us);
void Delay_ms (U8 time_ms);
void EEPROM_Write (U16 address, U8 value);
U8 EEPROM_Read (U16 address);
//-----------------------------------------------------------------------------
// main() Routine
//-----------------------------------------------------------------------------
void main (void)
{
U16 address; // EEPROM address
U8 test_byte; // Used as a temporary variable
Init_Device (); // Initializes hardware peripherals
// The following code will test the EEPROM by performing write/read/verify
// operations. The first test will write 0xFFs to the EEPROM, and the
// second test will write the LSBs of the EEPROM addresses.
SFRPAGE = ACTIVE_PAGE; // Set for printf()
// Fill EEPROM with 0xFF's
LED = 1;
printf("Filling with 0xFF's...\n");
for (address = 0; address < EEPROM_CAPACITY; address++)
{
test_byte = 0xFF;
EEPROM_Write (address, test_byte);
// Print status to UART0
if ((address % 16) == 0)
{
printf ("\nWriting 0x%04x: %02x ", address, (U16)test_byte);
LED = !LED;
}
else
{
printf ("%02x ", (U16)test_byte);
}
}
// Verify EEPROM with 0xFF's
printf("\n\nVerifying 0xFF's...\n");
for (address = 0; address < EEPROM_CAPACITY; address++)
{
test_byte = EEPROM_Read (address);
// Print status to UART0
if ((address % 16) == 0)
{
printf ("\nVerifying 0x%04x: %02x ", address, (U16)test_byte);
LED = !LED;
}
else
{
printf ("%02x ", (U16)test_byte);
}
if (test_byte != 0xFF)
{
LED = 0;
printf ("Error at %u\n", address);
while (1); // Stop here on error (for debugging)
}
}
// Fill EEPROM with LSB of EEPROM addresses
printf("\n\nFilling with LSB of EEPROM addresses...\n");
for (address = 0; address < EEPROM_CAPACITY; address++)
{
test_byte = address & 0xFF;
EEPROM_Write (address, test_byte);
// Print status to UART0
if ((address % 16) == 0)
{
printf ("\nWriting 0x%04x: %02x ", address, (U16)test_byte);
LED = !LED;
}
else
{
printf ("%02x ", (U16)test_byte);
}
}
// Verify EEPROM with LSB of EEPROM addresses
printf("\n\nVerifying LSB of EEPROM addresses...\n");
for (address = 0; address < EEPROM_CAPACITY; address++)
{
test_byte = EEPROM_Read (address);
// print status to UART0
if ((address % 16) == 0)
{
printf ("\nVerifying 0x%04x: %02x ", address, (U16)test_byte);
LED = !LED;
}
else
{
printf ("%02x ", (U16)test_byte);
}
if (test_byte != (address & 0xFF))
{
LED = 0;
printf ("Error at %u\n", address);
while (1); // Stop here on error (for debugging)
}
}
printf ("\n\nVerification success!\n");
while (1) // Loop forever
{
LED = !LED; // Flash LED when done (all verified)
Delay_ms (200);
}
}
//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// PCA0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This function disables the watchdog timer.
//
//-----------------------------------------------------------------------------
void PCA0_Init (void)
{
U8 SFRPAGE_save = SFRPAGE;
SFRPAGE = ACTIVE_PAGE;
PCA0MD &= ~0x40;
SFRPAGE = SFRPAGE_save;
}
//-----------------------------------------------------------------------------
// OSCILLATOR_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This function initializes the system clock to use the internal oscillator
// at 24 MHz.
//
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void)
{
U8 SFRPAGE_save = SFRPAGE;
SFRPAGE = CONFIG_PAGE;
OSCICN = 0x87;
SFRPAGE = SFRPAGE_save;
}
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This function configures the crossbar and GPIO ports.
//
// P0.0 - SCK (SPI0), Push-Pull, Digital
// P0.1 - MISO (SPI0), Open-Drain, Digital
// P0.2 - MOSI (SPI0), Push-Pull, Digital
// P0.3 - NSS (SPI0), Push-Pull, Digital
// P0.4 - TX0 (UART0), Push-Pull, Digital
// P0.5 - RX0 (UART0), Open-Drain, Digital
//
// P1.3 - Skipped, Push-Pull, Digital (LED D2 on Target Board)
// P1.4 - Skipped, Open-Drain, Digital (Switch S2 on Target Board)
//
//-----------------------------------------------------------------------------
void PORT_Init (void)
{
U8 SFRPAGE_save = SFRPAGE;
SFRPAGE = CONFIG_PAGE;
P0MDOUT = 0x1D; // Configure P0.0/2/3/4 to push-pull
P1MDOUT = 0x08; // Configure P1.3 to push-pull
P1SKIP = 0x18; // Skip P1.3 and P1.4 on the crossbar
XBR0 = 0x05; // Enable SPI and UART0 on crossbar
XBR2 = 0x40; // Enable crossbar
SFRPAGE = SFRPAGE_save;
}
//-----------------------------------------------------------------------------
// TIMER2_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Initializes Timer2 to be clocked by SYSCLK for use as a delay timer.
//
//-----------------------------------------------------------------------------
void TIMER2_Init (void)
{
// CKCON is available on all pages
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -