EEPROM读写操作使用SPI通信(PIC32MX350F1128L)(使用UART检查EEPROM值)

时间:2016-02-10 10:00:16

标签: pic uart spi eeprom

我正在使用SPI通信进行EEPROM读写操作,我正在使用UART通信检查收到的字节。我在这段代码中遇到的问题是我正在写入EEPROM并从EEPROM读取值并在UART(putty)中显示读取值。在这段代码中,我能够在UART中获得输出,但没有得到我写入EEPROM的确切值。我不知道问题是什么。我附上了我的代码。 我在用: PIC32MX350F1128L SST26VF032B EEPROM MPLAB X x32编译器。

// PIC32MX350F128L Configuration Bit Settings

// 'C' source line configuration statements

#include <xc.h>
#include <stdio.h>
#include <plib.h>

/* Configuration Bits */

#pragma config FSRSSEL = PRIORITY_7     // Shadow Register Set Priority Select (SRS Priority 7)
#pragma config PMDL1WAY = ON            // Peripheral Module Disable Configuration (Allow only one reconfiguration)
#pragma config IOL1WAY = ON             // Peripheral Pin Select Configuration (Allow only one reconfiguration)

// DEVCFG2
#pragma config FPLLIDIV = DIV_2         // PLL Input Divider (2x Divider)
#pragma config FPLLMUL = MUL_20         // PLL Multiplier (20x Multiplier)
#pragma config FPLLODIV = DIV_2        // System PLL Output Clock Divider (PLL Divide by 1)

// DEVCFG1
#pragma config FNOSC = PRI              // Oscillator Selection Bits (Primary Osc (XT,HS,EC))
#pragma config FSOSCEN = ON             // Secondary Oscillator Enable (Enabled)
#pragma config IESO = ON                // Internal/External Switch Over (Enabled)
#pragma config POSCMOD = XT             // Primary Oscillator Configuration (XT osc mode)
#pragma config OSCIOFNC = ON            // CLKO Output Signal Active on the OSCO Pin (Enabled)
#pragma config FPBDIV = DIV_8           // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/8)
#pragma config FCKSM = CSDCMD           // Clock Switching and Monitor Selection (Clock Switch Disable, FSCM Disabled)
#pragma config WDTPS = PS1048576        // Watchdog Timer Postscaler (1:1048576)
#pragma config WINDIS = OFF             // Watchdog Timer Window Enable (Watchdog Timer is in Non-Window Mode)
#pragma config FWDTEN = OFF             // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls))
#pragma config FWDTWINSZ = WINSZ_25     // Watchdog Timer Window Size (Window Size is 25%)

// DEVCFG0
#pragma config DEBUG = OFF              // Background Debugger Enable (Debugger is Disabled)
#pragma config JTAGEN = OFF             // JTAG Enable (JTAG Disabled)
#pragma config ICESEL = ICS_PGx2        // ICE/ICD Comm Channel Select (Communicate on PGEC2/PGED2)
#pragma config PWP = OFF                // Program Flash Write Protect (Disable)
#pragma config BWP = OFF                // Boot Flash Write Protect bit (Protection Disabled)
#pragma config CP = OFF                 // Code Protect (Protection Disabled)

/* MACRO DEFINITIONS */

/* Defining the Slave Select Pin */
#define SS      LATDbits.LATD9

/* System Clock Frequency */
#define SYSCLK  4000000

 /* Macro to get array size in bytes
 * note that array size can't be found after passing pointer to a function */
#define LEN(x)  (sizeof(x) / sizeof(x[0]))

/* SST26VF032B EEPROM instructions */

/* Write Enable */
#define WREN    0x06    

/* Write Disable */
#define WRDI    0x04    

/* Initialize Start of Write Sequence */
#define WRITE   0x02     

/* Initialize Start of Read Sequence */
#define READ    0x03   

/*  Erase all sectors of Memory */
#define CE      0xc7    

/*  Read STATUS Register */
#define RDSR    0x05    

/* Function Prototypes */

/* UART bit configuration */
void Bitconfig_uart(void);

/* SPI Initialization */
void SPI1_Init(void);

/* UART Initialization */
void Init_uart(void);

/* Send a Character Byte through UART */
void UART4PutChar(unsigned char Ch);

/* Function to Read and Write SPI1 buffer */
char SPI1_transfer( char b);

/* Function to check the Status of SPI */
void waitBusy();

/* Function to erase the contents in EEPROM */
void eraseEEPROM();

/* Function to Read data from EEPROM */
void readEEPROM( unsigned short address, char* loadArray, unsigned short loadArray_size);

/* Function to Write to EEPROM */
void writeEEPROM( unsigned short address, char* storeArray, unsigned short storeArray_size);

/* Global Variables Declaration */
/* Declare variables to check the functionality of EEPROM */
int i,j = 0;

/*******************************************************************************
* Function Name: main()
********************************************************************************
* Summary:
*  Initializes SPI
*  Erase EEPROM
*  Writes to EEPROM
*  Read from EEPROM 
*
* Parameters:
*  None.
*
* Return:
*  None.
*
*******************************************************************************/
int main()
{     
    /* optimize PIC32 performance and guarantee correct system clock frequency */
    SYSTEMConfigPerformance(SYSCLK);

    /* UART bit configuration */
    Bitconfig_uart();

    /* Set the Controller OScillator Register bits */
    OSCCON = 0x00002200;

    /* Initialize a String to Write to EEPROM and an array to Read back contents */
    char writeData[] = "12345678910111213141516";

    /* Array to read 35 bytes of data */
    char readData[35]; 

    /* SPI Initialization */
    SPI1_Init();

    /* UART Initialization */
    Init_uart();

    /* Erase contents of EEPROM */
    eraseEEPROM();

    /* Write contents of writeData array to address 180 */
    writeEEPROM( 180, writeData, LEN(writeData));

    while( 1)
    {    
        /* Read contents of EEPROM into readData array
         * start at address 180 and read up to 180+length(readData) */
        readEEPROM( 180, readData, LEN(readData) );

    }
} /* END main() */


/*******************************************************************************
* Function Name: SPI1_Init()
********************************************************************************
* Summary:
*  SPI1 Initialization 
*
* Parameters:
*  None.
*
* Return:
*  None.
*
*******************************************************************************/
void SPI1_Init(void)
{
    /* Configure Peripheral Pin Select (PPS) for the SPI1 module
    * Note: SS will be toggled manually in code
    * SCK is hardwired to pin 55 */

    /* Output Pin Selection for MOSI and MISO */
    RPE5Rbits.RPE5R = 8;
    SDI1Rbits.SDI1R = 3;

    /* RB4 (Slave Select 1) : output */
    TRISDbits.TRISD9 = 0;       

    /* RF6 (Serial clock) : output */
    TRISFbits.TRISF6 = 0;

    /* SPI configuration */

    /* SPI1CON Register Configuration 
     * MSTEN: Master Mode Enable bit = 1 (Master)
     * CKP (clock polarity control) = 0
     * CKE (clock edge control) = 1
     * ON: SPI Peripheral On bit 
     * 8-bit, Master Mode */
    SPI1CON = 0x8120;

    /* SPI1BRG Register Configuration */
    SPI1BRG = 0x0004; 
}

/*******************************************************************************
* Function Name: SPI1_transfer()
********************************************************************************
* Summary:
*  Write to and Read from SPI1 buffer
*
* Parameters:
*  char b - Writes a Character to Buffer
*
* Return:
*  Char - Returns the Character Read from EEPROM
*
*******************************************************************************/
char SPI1_transfer( char b)
{
    /* write to buffer for TX */
    SPI1BUF = b;     

    /* wait transfer complete */
    while(!SPI1STATbits.SPIRBF);        

    /* read the received value */
    return SPI1BUF;                     
} /* END SPI1_transfer() */


/*******************************************************************************
* Function Name: waitBusy()
********************************************************************************
* Summary: 
*  Checks if EEPROM is ready to be modified and waits if not ready
*
* Parameters:
*  None.
*
* Return:
*  None.
*
*******************************************************************************/
void waitBusy()
{
    char status = 0;

    do{
        /* Select EEPROM */
        SS = 0;

        /* Read EEPROM status register */
        SPI1_transfer(RDSR);        

        /* send dummy byte to receive incoming data */
        status = SPI1_transfer(1);   

        /* Release EEPROM */
        SS = 1;                            
    }

    /* write-in-progress while status<0> set to '1' */
    while( status & 0x01);             

} /* END waitBusy() */




/*******************************************************************************
* Function Name: readEEPROM()
********************************************************************************
* Summary:
* Reads data from EEPROM
*
* Parameters:
* Inputs:  address - address from 0-0xffff (64kB / 512kbits)
*          loadArray - array to load EEPROM data to
*          loadArray_size - number of bytes of EEPROM data to load into array 
*
* Return:
*  None.
*
*******************************************************************************/
void readEEPROM( unsigned short address, char* loadArray, unsigned short loadArray_size)
{
    unsigned short i;

    /* Wait until EEPROM is not busy */
    waitBusy();

    /* Select EEPROM */
    SS = 0;                  

    /* Initiate Read */
    SPI1_transfer( READ);         

    /* Address must be 16-bits but we're transferring it in two 8-bit sessions */
    SPI1_transfer( address >> 8);   
    SPI1_transfer( address);        

    /* Request and store loadArray_size number of bytes into loadArray */
    for( i=0 ; i<loadArray_size ; i++)
    {
        /* send dummy byte to read 1 byte */
        loadArray[i] = SPI1_transfer( 0x00);    
    }
    /* Release EEPROM */
    SS = 1;                         

        /* UART Test */
        for(i=0;i<35;i++)
        {
            UART4PutChar(loadArray[i]);
            for(j=0;j<20000;j++)
            {}
        }

} /* END readEEPROM() */

/*******************************************************************************
* Function Name: writeEEPROM()
********************************************************************************
* Summary:
* Write data to EEPROM
*
* Parameters:
* Inputs:  address - address from 0-0xffff (64kB / 512kbits)
*          storeArray - array of which contents are stored in EEPROM
*          storeArray_size - number of bytes in array to store into EEPROM 
*
* Return:
*  None.
*
*******************************************************************************/

void writeEEPROM( unsigned short address, char* storeArray, unsigned short storeArray_size)
{
    unsigned short i;

    /* Wait until EEPROM is not busy */
    waitBusy();

    /* Select EEPROM */
    SS = 0;

    /* Send WRITE_ENABLE command */
    SPI1_transfer( WREN);

    /* Release EEPROM */
    SS = 1;                 

    /* Select EEPROM again after WREN cmd */
    SS = 0; 

    /* Initiate Write */
    SPI1_transfer( WRITE);  

    SPI1_transfer( address >> 8 );
    SPI1_transfer( address );

    /* write 1 byte at a time from array */
    /* MSB at lowest address (0 - first letter in string) */
    for( i=0 ; i<storeArray_size; i++)
    {
        /* New write cycle must be initiated if writing across 128-byte pages */
        if( (address+i)%128 == 0 && i!=0 )
        {
            /* Release EEPROM */
            SS = 1;       

            /* Wait until EEPROM is not busy */
            waitBusy();

            /* Select EEPROM */
            SS = 0;           

             /* Send WRITE_ENABLE command */
            SPI1_transfer( WREN);  

            /* Release EEPROM */
            SS = 1;             

             /* Select EEPROM again after WREN cmd */
            SS = 0;     

            /* Initiate Write */
            SPI1_transfer( WRITE); 
            SPI1_transfer( (address+i) >> 8 );
            SPI1_transfer( address+i );
        }
        SPI1_transfer( storeArray[i]);
    }
    /* Release EEPROM */
    SS = 1;                        

} /* END writeEEPROM() */

/*******************************************************************************
* Function Name: eraseEEPROM()
********************************************************************************
* Summary:
* Erase entire contents of EEPROM
*
* Parameters:
*  None
*
* Return:
*  None.
*
*******************************************************************************/
void eraseEEPROM()
{
    /* Wait until EEPROM is not busy */
    waitBusy();

    /* Select EEPROM */
    SS = 0;                

    /* Send WRITE_ENABLE command */
    SPI1_transfer( WREN);   

    /* Release EEPROM */
    SS = 1;                 

    /* Select EEPROM again after WREN cmd */
    SS = 0;             

    /* send CHIP_ERASE command */
    SPI1_transfer( CE);    

    /* Release EEPROM */
    SS = 1;                 

} /* END eraseEEPROM() */

/*******************************************************************************
* Function Name: Init_uart()
********************************************************************************
* Summary:
* Initialize UART4
*
* Parameters:
*  None
*
* Return:
*  None.
*
*******************************************************************************/
void Init_uart()
{
    /* Enable UART */
   U4MODEbits.ON = 1 ;

   /* set baud rate(9600) */
   U4BRG = 25; 

   /* Set U4STA Register for Enabling tx and rx */
   U4STA=0x9400;

}

/*******************************************************************************
* Function Name: UART4PutChar(unsigned char Ch)
********************************************************************************
* Summary:
* Send data from controller to putty GUI
*
* Parameters:
* input
* unsigned char Ch -  To Send a byte of data over UART
*
* Return:
*  None.
*
*******************************************************************************/
void UART4PutChar(unsigned char Ch)
{
while(U4STAbits.UTXBF == 1);
U4TXREG=Ch;  
}

/*******************************************************************************
* Function Name: Bitconfig_uart()
********************************************************************************
* Summary:
* UART Pin Configuration
*
* Parameters:
*  None
*
* Return:
*  None.
*
*******************************************************************************/
void Bitconfig_uart(void)
{
    /* UART4 Initialization */
    OSCCON=0x00002200;

    /* Set pins as digital */
    ANSELBbits.ANSB14 = 0;
    ANSELGbits.ANSG6 = 0;
    ANSELGbits.ANSG7 = 0;

    /* Set UART Tx pin as Output */
    TRISDbits.TRISD4 = 0;  

    /* Set UART Rx pin as Input */
    TRISBbits.TRISB14 =1;

    /* Peripheral Pin select for UART4 */
    U4RXR=0x0002;
    RPD4R=0x0002;

    /* GPIO PIN selection for MUX */
    TRISGbits.TRISG6 = 0;
    TRISGbits.TRISG7= 0;  

    /* MUX value selection for UART */
    PORTGbits.RG6 = 1;
    PORTGbits.RG7 = 1;
}

0 个答案:

没有答案