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

📄 spi_eeprom.c

📁 TMS320X281X DSP原理及C程序开发(光盘) -苏奎峰 吕强
💻 C
字号:
//
//      SPI_EEPROM : TMS320F2812  Teaching CD ROM
//      (C) Frank Bormann
//
//###########################################################################
//
// FILE:	Lab7B.c
//
// TITLE:	SPI - EEPROM M95080  
//			CPU Timer0 ISR every 50 ms
//			Watchdog active , served in ISR and main-loop 
//
//###########################################################################
//
//  Ver | dd mmm yyyy | Who  | Description of changes
// =====|=============|======|===============================================
//  2.0 | 11 Nov 2003 | F.B. | adapted to header-files Version 1.00  
//###########################################################################

#include "DSP281x_Device.h"

// Commands for the EEPROM
#define WREN 0x06	// Write Enable
#define WRDI 0x04	// Write Disable
#define RDSR 0x05	// Read Status Register
#define WRSR 0x01	// Write Status Register
#define READ 0x03	// Read Command
#define WRITE 0x02	// Write Command 

// Prototype statements for functions found within this file.

void Gpio_select(void);
void InitSystem(void);
void SPI_Init(void);
int  SPI_EEPROM_Read_Status(void);
void SPI_EEPROM_Write_Enable(void);
void SPI_EEPROM_Write(int,int);
int SPI_EEPROM_Read(int);
interrupt void cpu_timer0_isr(void); // Prototype for Timer 0 Interrupt Service Routine

// Global Variables
int dummy;

void main(void)
{
	InitSystem();		// Initialize the DSP's core Registers
	
	Gpio_select();		// Setup the GPIO Multiplex Registers
	
	InitPieCtrl();		// Function Call to init PIE-unit ( code : DSP281x_PieCtrl.c)
	
	InitPieVectTable(); // Function call to init PIE vector table ( code : DSP281x_PieVect.c )
	
	// re-map PIE - entry for Timer 0 Interrupt 
	EALLOW;  // This is needed to write to EALLOW protected registers
   	PieVectTable.TINT0 = &cpu_timer0_isr;
   	EDIS;    // This is needed to disable write to EALLOW protected registers
	
	InitCpuTimers();
	
	// Configure CPU-Timer 0 to interrupt every 50 ms:
	// 150MHz CPU Freq, 50000 祍econds interrupt period
    ConfigCpuTimer(&CpuTimer0, 150, 50000);
    
    // Enable TINT0 in the PIE: Group 1 interrupt 7
   	PieCtrlRegs.PIEIER1.bit.INTx7 = 1;

	// Enable CPU INT1 which is connected to CPU-Timer 0:
    IER = 1;
    
	// Enable global Interrupts and higher priority real-time debug events:
   	EINT;   // Enable Global interrupt INTM
   	ERTM;   // Enable Global realtime interrupt DBGM
   	
   	CpuTimer0Regs.TCR.bit.TSS = 0;
   	
	SPI_Init();
	
	while(1)
	{    
 		while(CpuTimer0.InterruptCount < 4); // wait for Timer 0
  		CpuTimer0.InterruptCount = 0;
    	EALLOW;
    	SysCtrlRegs.WDKEY = 0xAA;		// and serve watchdog #2		
	   	EDIS;
		if ( GpioDataRegs.GPDDAT.bit.GPIOD1 == 0)
    	{									//  do an EEPROM write if D1 was pushed
        	SPI_EEPROM_Write_Enable();		// enable EPROM for write
       		while( !(SPI_EEPROM_Read_Status() & 0x0002));	
       										// wait for WEL = 1
       		SPI_EEPROM_Write(0x40,GpioDataRegs.GPBDAT.all >> 8);	
    							 			// read input-switches and
    							 			// write it into 0x40
	    	while (SPI_EEPROM_Read_Status()&0x0001);	// test for write in progress
    	}
    	if ( GpioDataRegs.GPDDAT.bit.GPIOD6 == 0)	
  											// do an EEPROM-read if D6 was pushed
    		GpioDataRegs.GPBDAT.all = SPI_EEPROM_Read(0x40); // show value on LED's  
 
	}
} 	

void Gpio_select(void)
{
	EALLOW;
	GpioMuxRegs.GPAMUX.all = 0x0;	// all GPIO port Pin's to I/O
    GpioMuxRegs.GPBMUX.all = 0x0;   
    GpioMuxRegs.GPDMUX.all = 0x0;
    GpioMuxRegs.GPFMUX.all = 0xF;	// SPI pins enabled	 
    GpioMuxRegs.GPEMUX.all = 0x0; 
    GpioMuxRegs.GPGMUX.all = 0x0;			
										
    GpioMuxRegs.GPADIR.all = 0x0;		// GPIO PORT  as input
    GpioMuxRegs.GPBDIR.all = 0x00FF;	// GPIO Port B15-B8 input , B7-B0 output
    GpioMuxRegs.GPDDIR.all = 0x0;		// GPIO PORT  as input
    GpioMuxRegs.GPDDIR.bit.GPIOD0 = 1; 	// D0 is /CS for DAC
    GpioMuxRegs.GPDDIR.bit.GPIOD5 = 1;	// D5 is /CS for EEPROM
    GpioMuxRegs.GPEDIR.all = 0x0;		// GPIO PORT  as input
    GpioMuxRegs.GPFDIR.all = 0x0;		// GPIO PORT  as input
    GpioMuxRegs.GPGDIR.all = 0x0;		// GPIO PORT  as input

    GpioMuxRegs.GPAQUAL.all = 0x0;	// Set GPIO input qualifier values to zero
    GpioMuxRegs.GPBQUAL.all = 0x0;
    GpioMuxRegs.GPDQUAL.all = 0x0;
    GpioMuxRegs.GPEQUAL.all = 0x0;
    
    GpioDataRegs.GPBDAT.all = 0;		// swich off LED's at B7..B0
    GpioDataRegs.GPDDAT.bit.GPIOD0 = 1;	// /CS DAC passive
    GpioDataRegs.GPDDAT.bit.GPIOD5 = 1;	// /CS EEPROM passive	
    EDIS;
}     


void InitSystem(void)
{
   	EALLOW;
   	SysCtrlRegs.WDCR= 0x00AF;		// Setup the watchdog 
   									// 0x00E8  to disable the Watchdog , Prescaler = 1
   									// 0x00AF  to NOT disable the Watchdog, Prescaler = 64
   	SysCtrlRegs.SCSR = 0; 			// Watchdog generates a RESET	
   	SysCtrlRegs.PLLCR.bit.DIV = 10;	// Setup the Clock PLL to multiply by 5
    
   	SysCtrlRegs.HISPCP.all = 0x1; // Setup Highspeed Clock Prescaler to divide by 2
   	SysCtrlRegs.LOSPCP.all = 0x2; // Setup Lowspeed CLock Prescaler to divide by 4
      	
   	// Peripheral clock enables set for the selected peripherals.   
   	SysCtrlRegs.PCLKCR.bit.EVAENCLK=0;
   	SysCtrlRegs.PCLKCR.bit.EVBENCLK=0;
   	SysCtrlRegs.PCLKCR.bit.SCIAENCLK=0;
   	SysCtrlRegs.PCLKCR.bit.SCIBENCLK=0;
   	SysCtrlRegs.PCLKCR.bit.MCBSPENCLK=0;
   	SysCtrlRegs.PCLKCR.bit.SPIENCLK=1;
   	SysCtrlRegs.PCLKCR.bit.ECANENCLK=0;
   	SysCtrlRegs.PCLKCR.bit.ADCENCLK=0;
   	EDIS;
}

void SPI_Init(void)
{
	SpiaRegs.SPICCR.bit.SPISWRESET = 0;  // Reset SPI
	SpiaRegs.SPICCR.bit.CLKPOLARITY = 1; // Data Out falling / In rising edge
										 // SPICLK passive = high
	SpiaRegs.SPICCR.bit.SPILBK = 0; 	 // no loobback mode
	SpiaRegs.SPICCR.bit.SPICHAR = 15;	 // 16 characters
	SpiaRegs.SPICCR.bit.SPISWRESET = 1;	 // relinq. from reset
	
	SpiaRegs.SPICTL.bit.CLK_PHASE = 0;	 // no clock delay
	SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;// SPI - Master
	SpiaRegs.SPICTL.bit.TALK = 1;		 // enable TALK
	SpiaRegs.SPICTL.bit.SPIINTENA = 0;	 // no SPI-Interrupts enabled
	SpiaRegs.SPICTL.bit.OVERRUNINTENA =0;// overrun interrupt disabled
	
	SpiaRegs.SPIBRR = 0x124;
	// SPI Baud Rate =  LSPCLK / ( SPIBRR + 1)
	//				 =  37,5 MHz / ( 124 + 1 )
	//			     =  300 kHz
}

int SPI_EEPROM_Read_Status(void)
{
	int k;
	GpioDataRegs.GPDDAT.bit.GPIOD5 = 0;		// activate /CS for the EEPROM  
	SpiaRegs.SPITXBUF = RDSR<<8;			// read status register command
	
	while (SpiaRegs.SPISTS.bit.INT_FLAG == 0) ; // wait for end of transmission
											// int-flag is reset when RXBUF was red

	k=SpiaRegs.SPIRXBUF;					// read status , LSB is WIP
	GpioDataRegs.GPDDAT.bit.GPIOD5 = 1;		// deactivate /CS for the EEPROM 
	return (k); 
}

void SPI_EEPROM_Write_Enable(void)
{
	GpioDataRegs.GPDDAT.bit.GPIOD5 = 0;		// activate /CS for the EEPROM
	SpiaRegs.SPITXBUF = WREN<<8;			// read status register command
	while (SpiaRegs.SPISTS.bit.INT_FLAG == 0) ; // wait for end of transmission
											// int-flag is reset when RXBUF was red
	dummy=SpiaRegs.SPIRXBUF;				// dummy read 
	GpioDataRegs.GPDDAT.bit.GPIOD5 = 1;		// deactivate /CS for the EEPROM 
}

void SPI_EEPROM_Write(int address,int data)
{
	GpioDataRegs.GPDDAT.bit.GPIOD5 = 0;		// activate /CS for the EEPROM
	SpiaRegs.SPITXBUF = (WRITE<<8)+(address>>8);
											// instruction + upper addressbyte 	
	while (SpiaRegs.SPISTS.bit.INT_FLAG == 0) ; // wait for end of transmission
											// int-flag is reset when RXBUF was red
	dummy=SpiaRegs.SPIRXBUF;				// dummy read 
	
	SpiaRegs.SPITXBUF = (address<<8)+(data & 0x00FF);	
											// write lower address + databyte
	while (SpiaRegs.SPISTS.bit.INT_FLAG == 0) ; // wait for end of transmission
	dummy=SpiaRegs.SPIRXBUF;				// dummy read 
	
	GpioDataRegs.GPDDAT.bit.GPIOD5 = 1;		// deactivate /CS for the EEPROM 
}

int SPI_EEPROM_Read(int address)
{
	int data;
	GpioDataRegs.GPDDAT.bit.GPIOD5 = 0;		// activate /CS for the EEPROM
	SpiaRegs.SPITXBUF = (READ<<8)+ (address>>8);
											// command + upper addressbyte	
	while (SpiaRegs.SPISTS.bit.INT_FLAG == 0) ; // wait for end of transmission
											// int-flag is reset when RXBUF was red
	dummy=SpiaRegs.SPIRXBUF;				// dummy read 
	
	SpiaRegs.SPITXBUF = (address<<8);			// write lower address 
												// and read data with 16 clk's
	while (SpiaRegs.SPISTS.bit.INT_FLAG == 0) ; // wait for end of transmission
	data=SpiaRegs.SPIRXBUF;					// read data 
	
	GpioDataRegs.GPDDAT.bit.GPIOD5 = 1;		// deactivate /CS for the EEPROM 
	return(data);
}

interrupt void cpu_timer0_isr(void)
{
    CpuTimer0.InterruptCount++;
   	// Serve the watchdog every Timer 0 interrupt
   	EALLOW;
	SysCtrlRegs.WDKEY = 0x55;		// Serve watchdog #1
	EDIS;

   // Acknowledge this interrupt to receive more interrupts from group 1
   PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
//===========================================================================
// End of SourceCode.
//===========================================================================

⌨️ 快捷键说明

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