英锐恩单片机论坛,Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流

 找回密码
 立即注册
搜索
电子烟方案单片机单片机开发深圳单片机开发
单片机方案国产单片机8位单片机电子烟方案开发
查看: 3865|回复: 0
打印 上一主题 下一主题

以C语言完成读写24LCxx系列的EEPROM的实例

[复制链接]
跳转到指定楼层
1#
发表于 2009-5-6 10:09:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//************************************************************************  
//*            Using I2C Master Mode for access Slave (EEPRM)         
//*                                                                                                                                 
//* Written by:  Richard Yang                                                                    
//*              Sr. Corporate Application Engineer                                                
//*              Microchip Technology Inc.                                                    
//* Date:        Oct. 3nd '2002                                                                
//* Revision:        1.00
//* Language tools : MPLAB-C18 v2.09.13
//*                                         MPLINK v3.10
//*                                         MPLAB-IDE v6.00.17 & ICD2                                                                      
//************************************************************************
/* Include Header files  */

#include <p18f452.h>
#include <i2c.h>                        // Load I2C Header file from defult direct
#include <timers.h>
#include "P18LCD.h"                        // Load P18LCD Header file form current working direct

/* Declare the Function Prototype */

void Initialize_I2C_Master(void);
void EE_Page_Write(unsigned char,unsigned char,unsigned char,unsigned char *);
void EE_SEQU_Read(unsigned char,unsigned char,unsigned char,unsigned char *);
void EEPROM_Write(unsigned char,unsigned char,unsigned char);
void EEPROM_ACK(unsigned char);
unsigned char EEPROM_Read(unsigned char,unsigned char);
void I2C_Done(void);
void Initialize_Timer2(void);
void isr_high_direct(void);
void isr_high(void);

#pragma romdata My_romdata=0x1000
const rom far unsigned char LCD_MSG1[]="SW2: Byte Write ";
const rom far unsigned char LCD_MSG2[]="SW6: Random Read";
const rom far unsigned char LCD_MSG3[]="Byte Write Mode ";
const rom far unsigned char LCD_MSG4[]="Random Read Mode";
const rom far unsigned char LCD_MSG5[]="Sended:         ";
const rom far unsigned char LCD_MSG6[]="Send:           ";
const rom unsigned char I2C_Write_Buffer[]="Microchip Technology";
#pragma romdata

/* Define following array in data memory */

unsigned char I2C_Read_Buffer [32];

/* define following variable in data memory at Access Bank */
#pragma udata access My_RAM
near unsigned char Debounce;
near unsigned char Send_Addr;
near unsigned char Send_Data;
near unsigned char Send_Length;
near unsigned char Read_Data;
near unsigned char P_SW2;
near unsigned char P_SW6;
#pragma udata

#define Page_Length        8
#define        SW2                PORTAbits.RA4
#define SW6                PORTEbits.RE1
#define Bounce_Time        6
#define EE_CMD        0xA0

//***********************************************************
/*                                                                                                                   */
/*                                                 Main         Program                                           */
/*                                                                                                                   */
//***********************************************************


void main(void)
{
        ADCON1=0b00000110;                // Disable A/D Function
        TRISAbits.TRISA4=1;                // Set SW2 for input
        TRISEbits.TRISE1=1;                // Set SW6 for Input       
        Initialize_Timer2( );
        Initialize_I2C_Master( );
        OpenLCD( );
       
        if (SW2 & SW6)Debounce=0;
        else Debounce = Bounce_Time;
       
        while(1)
        {
                LCD_Set_Cursor(0,0);                                // Put LCD Cursor on (0,0)
                putrsLCD(LCD_MSG1);       
                LCD_Set_Cursor(1,0);                                // Put LCD Cursor on (1,0)
                putrsLCD(LCD_MSG2);
       
                P_SW2=P_SW6=0;       
                Send_Addr=0;
               
                while(1)
                {
                        if (P_SW2)
                        {
                                P_SW2=0;
                                Debounce = Bounce_Time;
                                LCD_Set_Cursor(0,0);                                // Put LCD Cursor on (0,0)
                                putrsLCD(LCD_MSG3);       
                                LCD_Set_Cursor(1,0);                                // Put LCD Cursor on (0,0)
                                putrsLCD(LCD_MSG5);
                               
                                do
                                {
                                        while (!P_SW2);
                                        P_SW2=0;
                                        LCD_Set_Cursor(1,8);
                                        Send_Data=I2C_Write_Buffer[Send_Addr];
                                        EEPROM_Write(EE_CMD,Send_Addr,Send_Data);
                                        puthexLCD(EE_CMD);
                                        putcLCD(' ');
                                        puthexLCD(Send_Addr);
                                        putcLCD(' ');
                                        puthexLCD(Send_Data);
                                        EEPROM_ACK(EE_CMD);
                                        Send_Addr++;
                                } while (I2C_Write_Buffer[Send_Addr]!=0x00);
                        break;
                        }
                       
                        if (P_SW6)
                        {
                                P_SW6=0;
                                Debounce = Bounce_Time;
                                LCD_Set_Cursor(0,0);                                // Put LCD Cursor on (0,0)
                                putrsLCD(LCD_MSG4);       
                                LCD_Set_Cursor(1,0);                                // Put LCD Cursor on (0,0)
                                putrsLCD(LCD_MSG6);
                               
                 
                                while(1)
                                {
                                        if        (P_SW6)
                                        {
                                        P_SW6=0;
                                        LCD_Set_Cursor(1,5);
                                        Read_Data = EEPROM_Read(EE_CMD,Send_Addr);
                                        puthexLCD(EE_CMD);
                                        putcLCD(' ');
                                        puthexLCD(Send_Addr);
                                        putcLCD(' ');
                                        puthexLCD(EE_CMD);
                                        putcLCD(' ');
                                        puthexLCD(Read_Data);
                                        Send_Addr++;
                                        }
                                        if (P_SW2) break;
                                }
                                if (P_SW2) break;
                        }
                        if (P_SW2)
                        {
                                P_SW2=0;
                                 break;
                        }
                }       
        }
}
//************************************************
//*       #pragma Interrupt Declarations         *
//*                                                                                                 *
//* Function: isr_high_direct                    *
//*   - Direct execution to the actual           *
//*     high-priority interrupt code.            *
//************************************************
#pragma code isrhighcode = 0x0008

void isr_high_direct(void)       
{                                                                 
     _asm                                         //begin in-line assembly
     goto isr_high                        //go to isr_high function
     _endasm                                 //end in-line assembly
}
#pragma code

//************************************************
//* Function: isr_high(void)                     *     
//*   High priority interrupt for Timer2         *         
//************************************************
#pragma interrupt isr_high

void isr_high(void)
{
        PIR1bits.TMR2IF=0;                                        // Clear Timer2 interrupt Flag
       
        if (Debounce==0)
        {
                if (!SW2)
                { P_SW2=1; Debounce =Bounce_Time; }
                if (!SW6)
                { P_SW6=1; Debounce =Bounce_Time; }
        }               
        else if (SW2 & SW6)Debounce--;
                 else Debounce =Bounce_Time;                         
}                                                               
#pragma code

//***********************************************
//*         Write a Byte to EEPROM               
//*   - ctrl : Control Byte of EEPROM                         
//*   - addr : Location of EEPROM                         
//*   - data : Data Byte of EEPROM                                 
//***********************************************

void Initialize_Timer2(void)
{

                RCONbits.IPEN=1;                        // Enable Interrupt Priority bit
                IPR1bits.TMR2IP=1;                        // Set Timer2 for High Priority
                INTCONbits.GIEH=1;                        // Enable High Priority Interrupt

                OpenTimer2 (TIMER_INT_ON                // Turn On the Timer2 with Interrupt
                            & T2_PS_1_4                        // (4Mhz/4) [4*10*(99+1)] = 4mS */
                            & T2_POST_1_10);

                PR2 = 99;
}

//***********************************************
//*         Write a Byte to EEPROM              *
//*   - ctrl : Control Byte of EEPROM                        *
//*   - addr : Location of EEPROM                        *
//*   - data : Data Byte of EEPROM                                *
//***********************************************
void EEPROM_Write(unsigned char ctrl,unsigned char addr,unsigned char data)
{
        IdleI2C();                                     // ensure module is idle
          StartI2C();                                                // Start condition
        I2C_Done();                                                // Wait Start condition completed and clear SSPIF flag                               

        WriteI2C(ctrl);                                        // Write Control+Write to EEPROM & Check BF flag
        while(SSPCON2bits.ACKSTAT);         // wait until received the Acknowledge from EEPROM
        I2C_Done();                                                // Clear SSPIF flag

        WriteI2C(addr);                                        // Write Address to EEPROM
        while(SSPCON2bits.ACKSTAT);                // wait until received the Acknowledge from EEPROM
        I2C_Done();

        WriteI2C(data);                                        // Write Data to EEPROM
        while(SSPCON2bits.ACKSTAT);         // wait until received the Acknowledge from EEPROM
        I2C_Done();

        StopI2C();                                                // Stop condition
        I2C_Done();                                                // Wait the Stop condition completed
}

//***********************************************
//*         Pae Write to EEPROM               
//*
//*   - ctrl : Control Byte of EEPROM  
//*   - addr : Location of EEPROM                         
//*   - length : Write counter
//*   - *dptr : RAM point --> EEPROM
//*
//***********************************************
void EE_Page_Write(unsigned char ctrl,unsigned char addr,unsigned char length,unsigned char *dptr)
{
        IdleI2C();                                     // ensure module is idle
          StartI2C();                                                // Start condition
        I2C_Done();                                                // Wait Start condition completed
       
        WriteI2C(ctrl);                                        // Write Control+Write to EEPROM & Check BF flag
        while(SSPCON2bits.ACKSTAT);         // wait until received the Acknowledge from EEPROM
        I2C_Done();                                                // Clear SSPIF flag

        WriteI2C(addr);                                        // Write Address to EEPROM
        while(SSPCON2bits.ACKSTAT);                // wait until received the Acknowledge from EEPROM
        I2C_Done();

        while (length!=0)                                // Check write completed ?
        {
                WriteI2C(*dptr);                        // Write data to EEPROM
                while(SSPCON2bits.ACKSTAT); // wait until received the Acknowledge from EEPROM
                I2C_Done();       
                dptr++;                                                // Point to next byte
                length--;
        }
       
        StopI2C();                                                // Stop condition
        I2C_Done();                                                // Wait the Stop condition completed
}       
       
//***********************************************
//*         EEPROM Acknowledge Polling          *
//*   --  The routine will polling the ACK                *
//*       response from EEPROM                                   *
//*   --  ACK=0 return                                                         *
//*          --  ACK=1 send Restart & loop check                *
//***********************************************
void EEPROM_ACK(unsigned char ctrl)
{
        unsigned char i;

        IdleI2C();                                     // ensure module is idle
          StartI2C();                                                // Start condition
        I2C_Done();                                                // Wait Start condition completed

        WriteI2C(ctrl);                                        // Write Control to EEPROM (WRITE)
        I2C_Done();                                                // Clear SSPIF flag

        while (SSPCON2bits.ACKSTAT)                // test for Acknowledge from EEPROM
    {
                for (i=0;i<100;i++);                // Delay for next Repet-Start

              RestartI2C();                      // initiate Repet-Start condition
                I2C_Done();                               // Wait Repet-Start condition completed

                WriteI2C(ctrl);                                // Write Control to EEPROM (WRITE)
                I2C_Done();                                         // Clear SSPIF flag
    }   
        StopI2C();                      // send STOP condition
        I2C_Done();                                                // wait until stop condition is over
}

//***********************************************
//*    Random Read a Byte from EEPROM           *
//*   - ctrl : Control Byte of EEPROM (Write)        *
//*     (Ctrl +1 ) : Read Command                                *
//*   - addr : Address Byte of EEPROM                        *
//*   - Return : Read Data from EEPROM                        *
//***********************************************
unsigned char EEPROM_Read(unsigned char ctrl,unsigned char addr)
{
        unsigned char f;
       
        IdleI2C();                                     // ensure module is idle
          StartI2C();                                                // Start condition
        I2C_Done();                                                // Wait Start condition completed

        WriteI2C(ctrl);                                        // Write Control to EEPROM   
    while(SSPCON2bits.ACKSTAT);           // test for ACK condition, if received
        I2C_Done();                                                // Clear SSPIF flag

        WriteI2C(addr);                                        // Write Address to EEPROM         
    while(SSPCON2bits.ACKSTAT);          // test for ACK condition, if received  
        I2C_Done();                                                // Clear SSPIF flag

           RestartI2C();                              // initiate Restart condition
        I2C_Done();

        WriteI2C(ctrl+1);                                // Write Control to EEPROM              
        while(SSPCON2bits.ACKSTAT);           // test for ACK condition, if received
        I2C_Done();                                                // Clear SSPIF flag

        f=ReadI2C();                                        // Enable I2C Receiver & wait BF=1 until received data
        I2C_Done();                                                // Clear SSPIF flag

        NotAckI2C();                                        // Genarate Non_Acknowledge to EEPROM
        I2C_Done();          
                     
    StopI2C();                          // send STOP condition
        I2C_Done();                                                // wait until stop condition is over

        return(f);                                                // Return Data from EEPROM
}

//***********************************************
//*         Sequential Read from EEPROM               
//*
//*   - ctrl : Control Byte of EEPROM  
//*   - addr : Location of EEPROM                         
//*   - length : Read counter
//*   - *dptr : Store EEPROM data to RAM
//*
//***********************************************
void EE_SEQU_Read(unsigned char ctrl,unsigned char addr,unsigned char length,unsigned char *dptr)
{
        IdleI2C();                                     // ensure module is idle
          StartI2C();                                                // Start condition
        I2C_Done();                                                // Wait Start condition completed

        WriteI2C(ctrl);                                        // Write Control to EEPROM   
    while(SSPCON2bits.ACKSTAT);           // test for ACK condition, if received
        I2C_Done();                                                // Clear SSPIF flag

        WriteI2C(addr);                                        // Write Address to EEPROM         
    while(SSPCON2bits.ACKSTAT);          // test for ACK condition, if received  
        I2C_Done();                                                // Clear SSPIF flag

           RestartI2C();                              // initiate Restart condition
        I2C_Done();

        WriteI2C(ctrl+1);                                // Write Control to EEPROM              
        while(SSPCON2bits.ACKSTAT);           // Test for ACK condition, if received
        I2C_Done();                                                // Clear SSPIF flag

        while (length!=0)
        {
                *dptr=ReadI2C();                        // Enable I2C Receiver & Store EEPROM data to Point buffer
                I2C_Done();       
                dptr++;       
                length--;
                               
                if (length==0) NotAckI2C();
                else AckI2C();                                // Continue read next data, send a acknowledge to EEPROM
               
                I2C_Done();
        }

    StopI2C();                          // send STOP condition
        I2C_Done();                                                // wait until stop condition is over
}

//***********************************************
//*   Check I2C action that is completed        *
//***********************************************
void I2C_Done(void)
{
        while (!PIR1bits.SSPIF);                // Completed the action when the SSPIF is Hi.
        PIR1bits.SSPIF=0;                           // Clear SSPIF
}

//************************************************
//* Initial I2C Master Mode with 7 bits Address  *
//* Clock Speed : 100KHz @4MHz                                         *
//************************************************
void Initialize_I2C_Master(void)
{
        OpenI2C(MASTER,SLEW_ON);
        SSPADD= 9;
}
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|公司首页|Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流 ( 粤ICP备09008620号 )

GMT+8, 2024-11-27 21:15 , Processed in 0.055983 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表