PIC单片机的EEPROM读写实例及说明

合集下载

PIC读写24LCxx系列的EEPROM的实例C语言程序

PIC读写24LCxx系列的EEPROM的实例C语言程序

PIC:读写24LCxx系列的EEPROM的实例C语言程序//********************************************************* //* 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 */#i nclude <p18f452.h>#i nclude <i2c.h> // Load I2C Header file from defult direct#i nclude <timers.h>#i nclude "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=0x1000const 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_RAMnear 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 FunctionTRISAbits.TRISA4=1; // Set SW2 for inputTRISEbits.TRISE1=1; // Set SW6 for InputInitialize_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 = 0x0008void isr_high_direct(void){_asm //begin in-line assemblygoto 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_highvoid isr_high(void){PIR1bits.TMR2IF=0; // Clear Timer2 interrupt Flagif (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 bitIPR1bits.TMR2IP=1; // Set Timer2 for High PriorityINTCONbits.GIEH=1; // Enable High Priority InterruptOpenTimer2 (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 idleStartI2C(); // Start conditionI2C_Done(); // Wait Start condition completed and clear SSPIF flagWriteI2C(ctrl); // Write Control+Write to EEPROM & Check BF flagwhile(SSPCON2bits.ACKSTAT); // wait until received the Acknowledge from EEPROMI2C_Done(); // Clear SSPIF flagWriteI2C(addr); // Write Address to EEPROMwhile(SSPCON2bits.ACKSTAT); // wait until received the Acknowledge from EEPROMI2C_Done();WriteI2C(data); // Write Data to EEPROMwhile(SSPCON2bits.ACKSTAT); // wait until received the Acknowledge from EEPROMI2C_Done();StopI2C(); // Stop conditionI2C_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 idleStartI2C(); // Start conditionI2C_Done(); // Wait Start condition completedWriteI2C(ctrl); // Write Control+Write to EEPROM & Check BF flagwhile(SSPCON2bits.ACKSTAT); // wait until received the Acknowledge from EEPROMI2C_Done(); // Clear SSPIF flagWriteI2C(addr); // Write Address to EEPROMwhile(SSPCON2bits.ACKSTAT); // wait until received the Acknowledge from EEPROMI2C_Done();while (length!=0) // Check write completed ?{WriteI2C(*dptr); // Write data to EEPROMwhile(SSPCON2bits.ACKSTAT); // wait until received the Acknowledge from EEPROMI2C_Done();dptr++; // Point to next bytelength--;}StopI2C(); // Stop conditionI2C_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 idleStartI2C(); // Start conditionI2C_Done(); // Wait Start condition completedWriteI2C(ctrl); // Write Control to EEPROM (WRITE)I2C_Done(); // Clear SSPIF flagwhile (SSPCON2bits.ACKSTAT) // test for Acknowledge from EEPROM{for (i=0;i<100;i++); // Delay for next Repet-StartRestartI2C(); // initiate Repet-Start conditionI2C_Done(); // Wait Repet-Start condition completedWriteI2C(ctrl); // Write Control to EEPROM (WRITE)I2C_Done(); // Clear SSPIF flag}StopI2C(); // send STOP conditionI2C_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 idleStartI2C(); // Start conditionI2C_Done(); // Wait Start condition completedWriteI2C(ctrl); // Write Control to EEPROM while(SSPCON2bits.ACKSTAT); // test for ACK condition, if receivedI2C_Done(); // Clear SSPIF flagWriteI2C(addr); // Write Address to EEPROM while(SSPCON2bits.ACKSTAT); // test for ACK condition, if receivedI2C_Done(); // Clear SSPIF flagRestartI2C(); // initiate Restart conditionI2C_Done();WriteI2C(ctrl+1); // Write Control to EEPROMwhile(SSPCON2bits.ACKSTAT); // test for ACK condition, if receivedI2C_Done(); // Clear SSPIF flagf=ReadI2C(); // Enable I2C Receiver & wait BF=1 until received dataI2C_Done(); // Clear SSPIF flagNotAckI2C(); // Genarate Non_Acknowledge to EEPROMI2C_Done();StopI2C(); // send STOP conditionI2C_Done(); // wait until stop condition is overreturn(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 idleStartI2C(); // Start conditionI2C_Done(); // Wait Start condition completedWriteI2C(ctrl); // Write Control to EEPROMwhile(SSPCON2bits.ACKSTAT); // test for ACK condition, if receivedI2C_Done(); // Clear SSPIF flagWriteI2C(addr); // Write Address to EEPROMwhile(SSPCON2bits.ACKSTAT); // test for ACK condition, if receivedI2C_Done(); // Clear SSPIF flagRestartI2C(); // initiate Restart conditionI2C_Done();WriteI2C(ctrl+1); // Write Control to EEPROMwhile(SSPCON2bits.ACKSTAT); // Test for ACK condition, if receivedI2C_Done(); // Clear SSPIF flagwhile (length!=0){*dptr=ReadI2C(); // Enable I2C Receiver & Store EEPROM data to Point bufferI2C_Done();dptr++;length--;if (length==0) NotAckI2C();else AckI2C(); // Continue read next data, send a acknowledge to EEPROMI2C_Done();}StopI2C(); // send STOP conditionI2C_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;}。

I2C24LC02C读写例程(PIC单片机)

I2C24LC02C读写例程(PIC单片机)

I2C24LC02C读写例程(PIC单片机)I2C 24LC02 C读写例程(PIC单片机)[单片机]发布时间:2008-04-22 10:11:001 I2C总线特点I2C总线最主要的优点是其简单性和有效性。

由于接口直接在组件之上,因此I2C总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。

总线的长度可高达25英尺,并且能够以10Kbps的最大传输速率支持40个组件。

I2C总线的另一个优点是,它支持多主控(multimastering),其中任何能够进行发送和接收的设备都可以成为主总线。

一个主控能够控制信号的传输和时钟频率。

当然,在任何时间点上只能有一个主控。

2 I2C总线工作原理I2C总线上的数据稳定规则,SCL为高电平时SDA上的数据保持稳定,SCL为低电平时允许SDA变化。

如果SCL处于高电平时,SDA 上产生下降沿,则认为是起始位,SDA上的上升沿认为是停止位。

通信速率分为常规模式(时钟频率100kHz)和快速模式(时钟频率400kHz)。

同一总线上可以连接多个带有I2C接口的器件,每个器件都有一个唯一的地址,既可以是单接收的器件,也可以是能够接收发送的器件。

每次数据传输都是以一个起始位开始,而以停止位结束。

传输的字节数没有限制。

最高有效位将首先被传输,接收方收到第8位数据后会发出应答位。

数据传输通常分为两种:主设备发送从设备接收和从设备发送主设备接收。

这两种模式都需要主机发送起始位和停止位,应答位由接收方产生。

从设备地址一般是1或2个字节,用于区分连接在同一I2C上的不同器件。

I2C总线在传送数据过程中共有三种类型信号,它们分别是:开始信号、结束信号和应答信号。

开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。

结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。

应答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC 发出特定的低电平脉冲,表示已收到数据。

PIC16F877 EEPROM读写实验

PIC16F877 EEPROM读写实验

PIC16F877 EEPROM每一个单元的读/写所用时间典型值为:4ms,最大值为8ms。

在烧写每个EEPROM 单元过程中,需要CPU插入等待时间,既可利用中断功能,也可利用软件查询方式来解决。

在此我们利用了软件查询方式,循环检测WR烧写控制位兼烧写完成标志位。

程序如下:;实战《16F877内部EEPROM读/写实验》;本实战的目的是让大家熟悉PIC16F87X内部EEPROM的读/写方法;项目实现的功能:对于地址为00H-3FH的64个EEPROM数据存储单元,分;别将数据0-63依次烧写进去,然后再循环读出,显示在LED数码管上;程序清单如下:;************************************INCLUDE"P16F877.INC"STATUS EQU 3H ;定义状态寄存器地址RP0 EQU 5H ;定义页选位RP0的位地址RP1 EQU 6H ;定义页选位RP1的位地址Z EQU 2H ;定义0状态位的位地址PORTC EQU 7H ;定义RC口数据寄存器地址PORTD EQU 8HTRISC EQU 87H ;定义RC口方向控制寄存器地址TRISD EQU 88HEECON1 EQU 18CH ;定义写控制寄存器1的地址EECON2 EQU 18DH ;定义写控制寄存器2的地址EEDATA EQU 10CH ;定义读/写数据寄存器地址EEADR EQU 10DH ;定义读/写地址寄存器地址RD EQU 0 ;定义读启动控制位位地址WR EQU 1 ;定义写启动控制位位地址WREN EQU 2 ;定义写使能控制位位地址EEPGD EQU 7 ;定义访问目标选择控制位位址F EQU 1 ;定义目标寄存器为RAM的指示符W EQU 0 ;定义目标寄存器为W的指示符ADDR EQU 70H ;定义地址变量DATA1 EQU 71H ;定义数据变量;*************************************ORG 0000H ;NOP ;放置一条ICD必须的空操作指令GOTO MAIN ;ORG 0008H ;MAINBCF STATUS,RP1 ;选体1为当前体BSF STATUS,RP0 ;MOVLW 00H ;设定RC全部为输出MOVWF TRISC ;BSF STATUS,RP1 ;体3为当前体CLRF ADDR ;地址变量清0CLRF DATA1 ;数据变量清0WRITEBSF STATUS,RP1 ;选定体3BTFSC EECON1,WR ;上一次写操作是否完成GOTO $-1 ;否!返回继续检测BCF STATUS,RP0 ;选定体2MOVF ADDR,W ;取地址MOVWF EEADR ;送地址寄存器MOVF DATA1,W ;取数据MOVWF EEDATA ;送数据寄存器BSF STATUS,RP0 ;选定体3BCF EECON1,EEPGD ;选定EEPROM为访问对向BSF EECON1,WREN ;开放写操作使能控制MOVLW 55H ;MOVWF EECON2 ;送55H到寄存器EECON2(读写内部EEPROM,这句是固定的) MOVLW 0AAH ;MOVWF EECON2 ;送AAH到寄存器EECON2(读写内部EEPROM,这句是固定的) BSF EECON1,WR ;启动写操作BCF EECON1,WREN ;禁止写操作发生INCF DATA1,F ;数据递增INCF ADDR,F ;地址递增MOVF ADDR,W ;XORLW D'64' ;将当前地址与64比较BTFSS STATUS,Z ;检测=64否GOTO WRITE ;否!继续写后面单元READ1DECF ADDR,F ;地址递减BCF STATUS,RP0 ;选体2为当前体BSF STATUS,RP1 ;MOVF ADDR,W ;取地址MOVWF EEADR ;送地址寄存器BSF STATUS,RP0 ;选体3为当前体BCF EECON1,EEPGD ;选定EEPROM为访问对象BSF EECON1,RD ;启动读操作BCF STATUS,RP0 ;体2为当前体MOVF EEDATA,W ;取数据BCF STATUS,RP1 ;体0为当前体MOVWF PORTC ;送显LEDCALL DELAY ;调用廷时子程序MOVF ADDR,F ;检测当前地址BTFSS STATUS,Z ;是否为0?是!跳一步GOTO READ1 ;否!返回继续读出和显示READ2INCF ADDR,F ;地址递增BCF STATUS,RP0 ;选体2为当前体BSF STATUS,RP1 ;MOVF ADDR,W ;取地址MOVWF EEADR ;送地址寄存器BSF STATUS,RP0 ;选体3为当前体BCF EECON1,EEPGD ;选定EEPROM为访问对象BSF EECON1,RD ;启动读操作BCF STATUS,RP0 ;体2为当前体MOVF EEDATA,W ;取数据BCF STATUS,RP1 ;体0为当前体CALL LED_SHOW ;送数码管显示CALL DELAY ;调用廷时子程序MOVF ADDR,W ;检测当前地址与64比较XORLW D'64' ;BTFSS STATUS,Z ;是否等于64GOTO READ2 ;否!返回继续读出和显示GOTO READ1 ;返回大循环起点;******************************************DELAYMOVLW 0 ;MOVWF 72H ;将外层循环参数值256送外层循环寄存器DELAY1MOVLW 0 ;将内层循环参数值256送内层循环寄存器MOVWF 73H ;DECFSZ 73H,1 ;递减廷时程序GOTO $-1 ;DECFSZ 72H,1 ;GOTO DELAY1 ;RETURN;==========================================================; 2位LED共阳数码管显示模块; 入口: 待显示的数据在W中;----------------------------------------------------------LCD1 EQU 20H ;定义显示缓存单元LCD2 EQU 21HW_TEMP EQU 22H ;保护单元STATUS_TEMP EQU 23HCOUNT0 EQU 24HCOUNT1 EQU 25HCOUNT2 EQU 26HLED_SHOW; MOVLW 7FH ;;;;;;;MOVWF LCD1 ;现场保护,将W的内容暂存于LCD1MOVWF W_TEMP ;现场保护[W-->W_TEMP]SWAPF STATUS,W ;用SWAPF才不会影响标志位[W与STATUS高低4位交换] MOVWF STATUS_TEMP ;将W和STATUS存入各保护寄存器[STATUS-->STATUS_TEMP]BCF STATUS,RP1 ;选体1为当前体BSF STATUS,RP0 ;MOVLW 00HMOVWF TRISD ;设RD为输出口BCF STATUS,RP0 ;恢复体0; MOVWF LCD1 ;W-->LCD1MOVF LCD1,W ;LCD1-->WANDLW B'11110000' ;0FH与W相"与"后送WMOVWF LCD2 ;W-->FSWAPF LCD2 ;F高低4位互换MOVF LCD2,WCALL CONVERT ;绎码MOVWF PORTCMOVLW 02HMOVWF PORTD ;开LCD十位CALL DELAY2 ;延时MOVLW 0HMOVWF PORTD ;关LCD个位MOVF LCD1,W ;F-->WANDLW B'00001111' ;0FH与W相"与"后送WCALL CONVERT ;绎码MOVWF PORTCMOVLW 01HMOVWF PORTD ;开LCD个位CALL DELAY2 ;延时MOVLW 0HMOVWF PORTD ;关LCD个位SWAPF STATUS_TEMP,W ;恢复中断前STATUS,W的值MOVWF STATUSSWAPF W_TEMP,F ;W_TEMP高低4位互换SWAPF W_TEMP,W ;(用SWAPF才不会影响STATUS的值)RETURN ;子程序返回;==========================================================;-------------------- 共阳顺序7段数码管段码 --------------- CONVERT ;取数码管段码ADDWF PCL,1 ;地址偏移量加当前PC值TABLE RETLW 0C0H ;0RETLW 0F9H ;1 RETLW 0A4H ;2RETLW 0B0H ;3RETLW 99H ;4RETLW 92H ;5RETLW 82H ;6RETLW 0F8H ;7RETLW 80H ;8RETLW 90H ;9RETLW 88H ;ARETLW 83H ;bRETLW 0C6H ;cRETLW 0A1H ;dRETLW 86H ;ERETLW 8EH ;F; RETLW 7FH ;. 小数点RETLW 00H ;结束符;---------------------------------------------------------- ;--------------------------- 廷时子程序 ----------------- DELAY2MOVLW .2 ;设置延时常数 [.2--即为2] MOVWF COUNT0L1MOVLW .50 ;MOVWF COUNT1L2MOVLW .100 ;MOVWF COUNT2L3DECFSZ COUNT2,1 ;递减循环GOTO L3 ;DECFSZ COUNT1,1 ;GOTO L2 ;DECFSZ COUNT0,1 ;GOTO L1 ;RETLW 0;========================================================== END。

PIC16F526片内FLSH做EEPROM使用程序及说明资料

PIC16F526片内FLSH做EEPROM使用程序及说明资料

1.由于PIC16F526内部没有EEPROM,只有内部闪存(程序ROM)数据存储器,故用闪存来代替EEPROM存储关键数据。

2.闪存和EEPROM的对比:①二者在掉电后都能保存数据不丢失,和RAM不同,因此,闪存可以当EEPROM用。

②EEPROM使用灵活,每个字节都可以进行单独的读、写操作。

③闪存每个字节也都可以进行单独的读、写操作。

④但是,闪存不能进行单字节的擦除,在擦除时只能按区块(按页,按行)擦除。

⑤闪存只能把1改为0,不能把0改为1,因此,如果闪存里存了二进制数据0101_0101,直接改写为1010_1010是不可能的,结果只能变成0000_0000。

⑥基于上述原因,在改写某个单元时,要先将该单元擦除,变成0xFF。

⑦因此,对闪存写入数据的一般操作步骤应该是:先读出全部的数据并备份,再改写其中需要改写的数据,最后将全部数据再次写入。

3.对闪存的读写用不到中断,只要控制几个特殊功能寄存器就可以了,详见资料PIC16F526.pdf的第21页,22页,23页。

4.PIC16F526的闪存共64个Byte,分成8行,每行8个Byte。

要读写某个单元,只要将地址(0x00~0x3f)放入EEADR再按相应操作即可。

单元分布如下:其中红色改动为0x00的部分是每行的开始单元。

通过此表可以对闪存进行数据改动,然后通过【Program】下的Program功能将改动数据写入闪存。

5.子程序实例如下:①读一个字节子程序:void Read_one_byte(unsigned char Read_byte_ADR){EEADR=Read_byte_ADR; RD=1;}②擦除一行闪存子程序:void Erase_one_line(unsigned char Erase_line_ADR){EEADR=Erase_line_ADR; FREE=1; WREN=1; WR=1;}③写一个字节子程序:void write_one_byte(unsigned char WR_IN_ADR, unsigned char WR_IN_DATA) {EEADR=WR_IN_ADR; EEDATA=WR_IN_DATA; WREN=1; WR=1;}④写完后的校验程序:void Data_check (unsigned char Data_ch_ADR, unsigned char WR_IN_DATA) {Read_one_byte(Data_ch_ADR); //读出的数据在EEDATA中If(WR_IN_DATA != EEDATA) Data_write_in_error=1;Else Data_write_in_error=0; //和已写入的数据对比}6.整体操作子程序:①闪存初始化子程序:void Flsh_rom_init(void){Read_one_byte(0x00); //读出第一行第0x00地址的数据Read_byte_1= EEDATA; EEDATA=0;Read_one_byte(0x01); //读出第一行第0x01地址的数据Read_byte_2= EEDATA; EEDATA=0;……Read_one_byte(0x08); //读出第二行第0x00地址的数据Read_byte_1= EEDATA; EEDATA=0;Read_one_byte(0x09); //读出第二行第0x01地址的数据Read_byte_2= EEDATA; EEDATA=0;……Read_one_byte(0x3f); //读出第八行第0x07地址的数据Read_byte_1= EEDATA; EEDATA=0;if((Read_byte_1==0xff)||(Read_byte_2==0xff)||(Read_byte_3==0xff)){Erase_one_line(0x00); //擦掉第一行,8个Byte全部变为0xFFErase_one_line(0x08); //擦掉第二行,8个Byte全部变为0xFFErase_one_line(0x10); //擦掉第三行,8个Byte全部变为0xFFErase_one_line(0x18); //擦掉第四行,8个Byte全部变为0xFF……//其余行地址:0x20,0x28,0x30,0x38For(i=0;i<64;i++)write_one_byte(i,0); //全部初始化为0x00 }}②向闪存存数据的一般步骤及程序示例:首先,读出旧数据。

PCI-PCI 桥在线读写EEPROM 的技巧

PCI-PCI 桥在线读写EEPROM 的技巧
①ROM 数据寄存器(RDR)。8 位宽,用于存放读写数据。偏移地址是 0x0CA。
②ROM 地址寄存器(RAR)。24 位宽,偏移地址是 0x0CC,比特分配如下:
bit 位置 意义
23:11 无用
10:9 操作码
8:7 操作码扩展
6:0 地址
操作码的意义: 01b——写(SROM_OpWrite); 10b——读(SROM_OpRead); 11b——擦;
EEPROM 选用的是 ATMEL 公司生产的 AT93LC66,4Kbit,按 512×8bit 组织。AT93LC66 与 Dec21554 的硬件连线如图 1 所示。
Dec21554 提供了一组寄存器,用于访问外接的串行 ROM。寄存器位于 CSR(控制状态寄存器组) 空间中,基地址是 PCI 配置头部 Secondary BAR2 寄存器的值,文中定义为 base。寄存器包括:
表1
bit 位置 名称
意义
7:4 Reserved
保留
3 SROM_POLL
反映串行 ROM 的 查询结果
2 RW_CTL
并行 ROM 读写控 制
1
ห้องสมุดไป่ตู้
0
P_ROM_START
ROM_START
开始并行 ROM 的 读写操作,并返回 状态
开始串行 ROM 的 读写操作,并返回 状态
寄存器 8 位宽,偏移地址是 0x0CF。
00b——见操作码扩展位(SROM_OpGeneral)。
操作码扩展位的意义: 00b——写无效; 01b——全写; 10b——全擦; 11b——写有效(SROM_GeneralWriteEnable)。 操作码扩展位同时兼作地址的 7、8 位。该寄存器上电后的默认值为 0x000400。 ③ROM 控制寄存器(RCR)。各 bit 含义如表 1 所列。

PIC单片机EEPROM的读写程序

PIC单片机EEPROM的读写程序

。TEEHSATAD 考参 �似类 MORPEE 写读与程过体具写读的 HSALF �3 。)个这考参要前序程编(TEEHSATAD 见可序程编汇体具 。零清被否是 RW�置设被否是 FIEE 查检须必件软则�成完有没 1 骤步果如。 �零清件软由须 必 FIEE�置设被 FIEE 而零清被位 RW�时束结期周写在 �01 。NERW 除清 。 �断中到用要需果如�断中放开 。位 RW 置设 �3� 。 �2NOCEE 入写后 然�W 入写先首�步两含包� 。2NOCEE 入写 AAX0 将 �2� 。 �2NOCEE 入写后 然�W 入写先首�步两含包� 。2NOCEE 入写 55X0 将 �1� �序顺的骤步个 5 面下行执格严 。断中 elbasiD 。NERW 置设 。位 DGPEE 清 .ATADEE 入写据数位 8 将 。制限的件硬于大会不度长址地保确�RDAEE 入写址地将 �7 �6 �5 �4 �3 �2 CIP
。程 过写于处正是不是看位 RW 查检�成完有没 01 骤步果如 �1
�骤步的 MORPEE 写 。行进在正作操写有没证保要前程过作操写个 一始开在。零清 NERW 对须必件软后完写。RW 置设能才后置设被 NERW 在有只 。零持保须必间时它其 �据数写在正了除位 NERW 据数 MORPEE 写 。TEEHSATAD 见可序程编汇体具 。数读 ATADEE 从 。位 DR 置设 。位 DGPEE 除清 。制限的件硬于大会不度长址地保确 �ATADEE 入写址地将 �4 �3 �2 �1 �3
的中 ATADEE:HTADEE 而�除擦被会将据数的中 RDAEE:HRDAEE 。 令 指 行 执 止 停 会 将 机 片 单 � 置 设 被 R W 和 N E RW 旦 一 �HSALF 于对 。1 置被 FIEE �零清被会将址地的 RDAEE 后然 �入写据 数的中 ATADEE 将会就 RW 和 NERW 了置设旦一�据数 MORPEE 于 对 。 零 清 位 识 标 该 对 先 首 须 必 前 之 RW 置 设 在 � 置 设 被 后 束 结 程过写当 FIEE 志标断中。零清动自被会后束结作操写�位始初作操 写是位 RW。作操写行进以可则 1=�位能使作操写是 NERW。FIEE 和 RRERW 位志标个两�NERW 和 RW 位制控个两有作操写 。据数到读器 存寄 ATADEE:HTADEE 从以可令指条两后置设被在 �据数的 HSALF 于 对 而 。 据 数 到 读 器 存 寄 ATADEE 从 以 可 上 马 会 就 后 置 设 被位 该 �作操读的 MORPEE 于对。零清动自会后束结作操读。据数到读器 存寄据数从能就 1 成置设被旦一�DR 位加附个一到用要作操读 。作操行进 HSALF 对是则 1= �作操行进 MORPEE 对 �0=DGPEE 。断中外意的中程过写止防来用被是而�器存 寄的上义意正真个一是不 2NOCEE�化始初置配来用 1NOCEE 器存寄 2NOCEE 和 1NOCEE �1 。写读的节字/字行进�行执常正的序程响影 会不 MORPEE 。 �列系 X78F61�据数位 41 储存 ATADEE:HTADEE � 址 地 位 31 存 保 RDAEE:HRDAEE � 断 中 和 令 指 条 一 下 行 执会才束结作操写到直�行运的令指停暂会作操写的 HSALF 对

PIC30F4011_EEPROM

PIC30F4011_EEPROM
ReadEEByTable(__builtin_tblpage(&ArrayInEEData[0]), __builtin_tbloffset(&ArrayInEEData[0]), &ArrayInRAM1[0]);
CORCONbits.PSV = 1;
ReadEEByPSV(__builtin_psvpage(&ArrayInEEData[0]), &ArrayInRAM1[0]);
NVMKEY = 0x55; //写密钥序列
NVMKEY = 0xAA;
NVMCONbits.WR = 1; //开始编程
while(NVMCONbits.WR = =1);
}
int main()
{
InitializeSys();
while(1);
}
int failmemory[40];
// 在EEPROM中安排16个字的数据
int _EEDATA(32) ArrayInEEData[16] = {0,1,2,3,4,5,6,7,8,9,0xA,0xB,0xC,0xD,0xE,0xF};
// 在RAM中安排16个字的数据
int ArrayInRAM0[16] = {0xf,0xe,0xd,0xc,0xb,0xa,9,8,7,6,5,4,3,2,1,0};
int ArrayInRAM1[16];
// 初始化系统
void InitializeSys()
{
SRbits.IPL = 7; // 关闭所有可屏蔽中断
}
// 通过表读指令从EEPROM中读一行数据至RAM
void ReadEEByTable(register int SourceAddr, register int OffsetAddr, int* DestArray)

单片机EEPROM读写数据流程解析

单片机EEPROM读写数据流程解析

单片机EEPROM读写数据流程解析EEPROM 写数据流程第一步,首先是I2C 的起始信号,接着跟上首字节,也就是我们前边讲的I2C 的器件地址,并且在读写方向上选择“写”操作。

第二步,发送数据的存储地址。

24C02 一共256 个字节的存储空间,地址从0x00~0xFF,我们想把数据存储在哪个位置,此刻写的就是哪个地址。

第三步,发送要存储的数据第一个字节、第二个字节??注意在写数据的过程中,EEPROM 每个字节都会回应一个“应答位0”,来告诉我们写EEPROM 数据成功,如果没有回应答位,说明写入不成功。

在写数据的过程中,每成功写入一个字节,EEPROM 存储空间的地址就会自动加1,当加到0xFF 后,再写一个字节,地址会溢出又变成了0x00。

EEPROM 读数据流程第一步,首先是I2C 的起始信号,接着跟上首字节,也就是我们前边讲的I2C 的器件地址,并且在读写方向上选择“写”操作。

这个地方可能有同学会诧异,我们明明是读数据为何方向也要选“写”呢?刚才说过了,24C02 一共有256 个地址,我们选择写操作,是为了把所要读的数据的存储地址先写进去,告诉EEPROM 我们要读取哪个地址的数据。

这就如同我们打电话,先拨总机号码(EEPROM 器件地址),而后还要继续拨分机号码(数据地址),而拨分机号码这个动作,主机仍然是发送方,方向依然是“写”。

第二步,发送要读取的数据的地址,注意是地址而非存在EEPROM 中的数据,通知EEPROM 我要哪个分机的信息。

第三步,重新发送I2C 起始信号和器件地址,并且在方向位选择“读”操作。

这三步当中,每一个字节实际上都是在“写”,所以每一个字节EEPROM 都会回应一个“应答位0”。

第四步,读取从器件发回的数据,读一个字节,如果还想继续读下一个字节,就发送一个“应答位ACK(0)”,如果不想读了,告诉EEPROM,我不想要数据了,别再发数据了,那就发送一个“非应答位NAK(1)”。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

PIC单片机的EEPROM读写实例及说明
; PIC 单片机的EEPROM 读写实例及说明;
********************************************************************
********; This is a program to test the function of readingwritting for EEPROM.; You can observe the value of register(30H--?) buy changing “VALU” and “WRC_”.; Notice that:it must be { ADDR+WRC_=0ffh } !;*******************************************************************
*********include “p16f877.inc”ADDR EQU 20H ;写入地址寄存器VALU EQU
21H ;写入值REC_ EQU 22H ;读计数WRC_ EQU 24H ;写计数org 0goto mainmainbcf STATUS,RP1bcf STATUS,RP0 ;bank0movlw 10hmovwf ADDR ;写入EEPROM 初始值movlw 90hmovwf VALU ;初始写入值movlw 30hmovwf FSR ;间址,读出值初始存放地址movlw 0Fhmovwf WRC_ ;写入次数movwf REC_;incf REC_ ;读出次数wri_ ;写子程序bsf STATUS,RP1bsf STATUS,RP0 ;bank3btfsc EECON1,WRgoto $-1bcf STATUS,RP0bcf STATUS,RP1 ;bank0movf ADDR,Wbsf STATUS,RP1 ;bank2movwf EEADRbcf STATUS,RP1 ;bank0movf VALU,Wbsf STATUS,RP1 ;bank2movwf EEDATAbsf STATUS,RP0 ;bank3bcf EECON1,EEPGD ;to data memorybsf EECON1,WRENbcf INTCON,GIEmovlw 55hmovwf EECON2movlw 0aahmovwf EECON2bsf EECON1,WRbcf STATUS,RP0bcf STATUS,RP1 ;bank0incf ADDR,1decf VALU,1decfsz WRC_ ;all write,to read_goto wri_read_ ;读子程序bcf STATUS,RP1bcf STATUS,RP0 ;bank0decf ADDR ;next valuebsf STATUS,RP1 ;bank2movwf EEADRbsf STATUS,RP0 ;bank3EEwr.asm 程序说明:1、本程序是对PIC16F877 单片机的EEPROM 数据区进行读写的演示程序;。

相关文档
最新文档