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)”。

单片机读写EEPROM例子

单片机读写EEPROM例子

单⽚机读写EEPROM例⼦eeprom.c#ifndef _EEPROM_H_#define _EEPROM_H_#include <intrins.h>#include <reg52.h>typedef unsigned int uint;typedef unsigned char uchar;/********STC89C52扇区分布*******第⼀扇区:2000H--21FF第⼆扇区:2200H--23FF第三扇区:2400H--25FF第四扇区:2600H--27FF第五扇区:2800H--29FF第六扇区:2A00H--2BFF第七扇区:2C00H--2DFF第⼋扇区:2E00H--2FFF*******************************/#define RdCommand 0x01 //字节编程数据命令#define PrgCommand 0x02 //字节读数据命令#define EraseCommand 0x03 //扇区擦除数据命令#define Error 1#define Ok 0#define WaitTime 0x01 //定义CPU的等待时间,40M以下为0,20M以下为1,10M以下为2,5M以下为3/*****ISP/IAP特殊功能寄存器声明********/sfr ISP_DATA = 0xE2;sfr ISP_ADDRH = 0xE3;sfr ISP_ADDRL = 0xE4;sfr ISP_CMD = 0xE5;sfr ISP_TRIG = 0xE6;sfr ISP_CONTR = 0xE7;unsigned char byte_read(unsigned int byte_addr);void byte_write(unsigned int byte_addr,unsigned char Orig_data);void SectorErase(unsigned int sector_addr);#endifeeprom.c#include "eeprom.h"/**********打开ISP/IAP功能**************/void ISP_IAP_Enable(void){EA = 0; //关中断ISP_CONTR = ISP_CONTR & 0x18;ISP_CONTR = ISP_CONTR | WaitTime; // 设置等待时间ISP_CONTR = ISP_CONTR | 0x80; //允许ISP/IAP操作}/**********关闭ISP/IAP功能**************/void ISP_IAP_Disable(void){ISP_CONTR = ISP_CONTR & 0x7f; //禁⽌ISP/IAP操作ISP_CMD = 0x00; //去除ISP/IAP命令ISP_TRIG = 0x00; //防⽌ISP/IAP命令⽆触发EA = 1; // 开中断}/**********触发ISP/IAP**************/void ISPTrig(void){ISP_TRIG = 0x46; //先送46h,再送B9h到ISP/IAP触发寄存器,每次都需如此ISP_TRIG = 0xb9; //送完B9h后,ISP/IAP命令⽴即被触发启动_nop_();}/**********字节读**************/unsigned char byte_read(unsigned int byte_addr){unsigned char dat = 0; //读EEPROM数据缓存EA = 0; //关中断ISP_ADDRH = (unsigned char)(byte_addr >> 8); //送地址⾼字节ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff); //送地址低字节ISP_IAP_Enable(); //打开ISP/IAP功能ISP_CMD = ISP_CMD & 0xf8; //清除ISP_CMD寄存器低3位ISP_CMD = ISP_CMD | RdCommand; //写⼊读数据命令ISPTrig(); //触发ISP/IAPdat = ISP_DATA; //将ISP_DATA寄存器中的数据保存起来ISP_IAP_Disable(); //关闭ISP/IAP功能EA = 1; //使能中断return dat; //返回读到的数据}/**********字节写**************/void byte_write(unsigned int byte_addr,unsigned char Orig_data){EA = 0; //关中断ISP_ADDRH = (unsigned char)(byte_addr >> 8); //送地址⾼字节ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff); //送地址低字节ISP_IAP_Enable(); //打开ISP/IAP功能ISP_CMD = ISP_CMD & 0xf8; //清除ISP_CMD寄存器低3位ISP_CMD = ISP_CMD | PrgCommand; //写⼊写数据命令ISP_DATA = Orig_data; //写⼊数据到ISP_DATA寄存器ISPTrig(); //触发ISP/IAPISP_IAP_Disable(); //关闭ISP/IAP功能EA =1; //使能中断}/**********扇区擦除**************/void SectorErase(unsigned int sector_addr){EA = 0;ISP_ADDRH = (unsigned char)(sector_addr >> 8); //送擦除地址⾼字节 ISP_ADDRL = (unsigned char)(sector_addr & 0x00ff); //送擦除地址低字节 ISP_IAP_Enable();ISP_CMD = ISP_CMD & 0xf8; //清除ISP_CMD寄存器低3位ISP_CMD = ISP_CMD | EraseCommand; //写⼊擦除数据命令ISPTrig(); //触发ISP/IAPISP_IAP_Disable(); //关闭ISP/IAP功能}ISP2.C/********************************************************************************* @file main.c* @author waitstory* @version V1.0* @date 2018-4-11* @brief STC89C52RC内部EEPROM的读写******************************************************************************* @attention** 实验平台:STC89C52RC芯⽚,晶振11.0592MHz*********************************************************************************/#include <eeprom.h>#include <absacc.h>void InitUART(uint baud); //串⼝初始化函数void UartTXData(uchar str[]); //串⼝发送函数void Delay_ms(uint z); //延时函数uchar TxStr[3] = {1};uchar dat[2] ={0x33,0x35};uint ma,mb;char id;char *MCUID;/********STC89C52扇区分布*******第⼀扇区:2000H--21FF第⼆扇区:2200H--23FF第三扇区:2400H--25FF第四扇区:2600H--27FF第五扇区:2800H--29FF第六扇区:2A00H--2BFF第七扇区:2C00H--2DFF第⼋扇区:2E00H--2FFF*******************************/void main(){//ma=0x2000;SectorErase(0x2000); //擦除第⼀扇区byte_write(0x2001,dat[0]); //在地址为0x2001的内存写⼊⼀个字节byte_write(0x2002,dat[1]); //在地址为0x2002的内存写⼊⼀个字节//byte_write(0x2001,'1'); //在地址为0x2001的内存写⼊⼀个字节//byte_write(0x2002,'2'); //在地址为0x2002的内存写⼊⼀个字节Delay_ms(1000); //延时1sInitUART(9600); //串⼝初始化函数ma=0x2e00;while(1){TxStr[0] = byte_read(0X2001); //从地址0x2001读取⼀个字节TxStr[1] = byte_read(0X2002); //从地址0x2002读取⼀个字节ma=ma+2;UartTXData(TxStr); //将读取的字节发送⾄串⼝Delay_ms(1000); //延时2s}}/* 串⼝配置函数,baud-通信波特率 */void InitUART(uint baud){EA = 1; //使能中断总开关SCON = 0x50; //配置串⼝为模式1TMOD &= 0x0F; //清零T1的控制位TMOD |= 0x20; //配置T1为模式2TH1 = 256 - (11059200/12/32)/baud; //计算T1重载值TL1 = TH1; //初值等于重载值ET1 = 0; //禁⽌T1中断ES = 1; //使能串⼝中断TR1 = 1; //启动T1}/*串⼝发送字符串函数*/void UartTXData(uchar str[]){uchar i = 0;while(str[i] != '\0'){SBUF= str[i];i++;while(!TI);TI=0;}}/*延时函数*/void Delay_ms(uint z){uint i,j;for(i=z;i>0;i--)for(j=110;j>0;j--);}结果:打开STC-ISP中的串⼝助⼿-打开串⼝,9600,单⽚机发送33 35,串⼝接收到33 35。

PIC单片机的EEPROM读写程序

PIC单片机的EEPROM读写程序

PIC单片机的EEPROM读写程序PIC16C74B单片机与AT24C64通讯;该程序实现的功能是:;将I2C_A,I2C_B.....I2C_K内容写入EEPROM中;同时在EEPROM中读出数据从新写入各个寄存器;=======================================LIST P=16C74B#include<p16c74.inc>ERRORLEVEL -302I2C_A EQU 0X20I2C_B EQU 0X21I2C_C EQU 0X22I2C_D EQU 0X23I2C_E EQU 0X24I2C_F EQU 0X25I2C_G EQU 0X26REG1 EQU 0X2BREG2 EQU 0X2CCOUNT EQU 0X71 ;I2CBCOUNT EQU 0X72 ;I2CTXBUF EQU 0X73 ;I2CRXBUF EQU 0X74 ;I2CBUSCON EQU 0X75 ;I2CBUSSTA EQU 0X76 ;I2CI2CBUF EQU 0X77 ;I2CSLA VEADDR EQU 0XA0 ;I2CDA TAADDRH EQU 0X01 ;I2CDA TAADDRL EQU 0X00 ;I2C;---------------------------------------;BUSCON;---------------------------------------SLA VE_RW EQU 7LAST_BYTE_RX EQU 6SLA VE_ACTIVE EQU 5TIME_OUT EQU 4;---------------------------------------;BUSSTA;---------------------------------------BUS_BUSY EQU 7TX_PROGRESS EQU 6RX_PROGRESS EQU 5TX_SUCCESS EQU 4RX_SUCCESS EQU 3FATAL_ERROR EQU 2 ;SLA VE EEPROM ABORT EQU 1ACK_ERROR EQU 0;---------------------------------------R_NOT_W EQU 0TRUE EQU 1FALSE EQU 0SDA EQU 0X04 ;I2CSCL EQU 0X03 ;I2C;=======================================ORG 0X00GOTO STARTORG 0X20START BCF STATUS,RP1BCF STATUS,RP0CLRF RACLRF RBCLRF RCCLRF RDCLRF REBSF STATUS,RP0CLRF TRISACLRF TRISBCLRF TRISCCLRF TRISDCLRF TRISEMOVLW 0X02MOVWF I2C_AMOVLW 0X04MOVWF I2C_BMOVLW 0X03MOVWF I2C_CMOVLW 0X03MOVWF I2C_DMOVLW 0X05MOVWF I2C_EMOVLW 0X06MOVWF I2C_FMOVLW 0X04MOVWF I2C_G;======================================= START1CALL I2CBUS_INITCALL REGTOI2CBUFCALL I2CWRITECALL CLRI2CBUFCALL D10CALL I2CREADCALL I2CBUFTOREGGOTO START1;======================================= ;CLRI2CBUF;---------------------------------------CLRI2CBUFBCF STA TUS,RP0MOVLW I2CBUFMOVWF FSRMOVLW 0X08MOVWF COUNTCLRLOOP CLRF INDFINCF FSR,FDECFSZ COUNT,FGOTO CLRLOOPRETURN;---------------------------------------;将各个REGSTER数据写入 I2CBUF 缓冲区;---------------------------------------REGTOI2CBUFBCF STA TUS,RP0MOVLW I2CBUFMOVWF FSRMOVF I2C_A,WMOVWF INDFINCF FSR,FMOVF I2C_B,WMOVWF INDFINCF FSR,FMOVF I2C_C,WMOVWF INDFINCF FSR,FMOVF I2C_D,WMOVWF INDFINCF FSR,FMOVF I2C_E,WMOVWF INDFINCF FSR,FMOVF I2C_F,WMOVWF INDFINCF FSR,FMOVF I2C_G,WMOVWF INDFRETURN;---------------------------------------;将 I2CBUF 缓冲区数据写入各个REGSTER;---------------------------------------I2CBUFTOREGBCF STA TUS,RP0MOVLW I2CBUFMOVWF FSRMOVF INDF,WMOVWF I2C_AINCF FSR,FMOVF INDF,WMOVWF I2C_BINCF FSR,FMOVF INDF,WMOVWF I2C_CINCF FSR,FMOVF INDF,WMOVWF I2C_DINCF FSR,FMOVF INDF,WMOVWF I2C_EINCF FSR,FMOVF INDF,WMOVWF I2C_FINCF FSR,FMOVF INDF,WMOVWF I2C_GRETURN;=======================================;将I2CBUF缓冲区内的数据写入EEPROM;=======================================I2CWRITECALL I2CSTARTBTFSS BUSSTA,BUS_BUSYGOTO TX_FAILBCF BUSCON,SLA VE_RWCALL TX_SLA VE_ADDRBTFSS BUSSTA,TX_SUCCESS ;SUCESSFULL? GOTO TX_FAILCALL TX_DA TA_ADDRBTFSS BUSSTA,TX_SUCCESSGOTO TX_FAILMOVLW I2CBUFMOVWF FSRMOVLW 07MOVWF COUNTT_BYTE_LOOPMOVF INDF,WMOVWF TXBUFCALL I2CTXBBTFSS BUSSTA,TX_SUCCESSGOTO TX_FAILINCF FSR,FDECFSZ COUNT,FGOTO T_BYTE_LOOPGOTO TX_PASSTX_FAIL CALL I2CSTOPBCF BUSSTA,TX_PROGRESSBCF BUSSTA,TX_SUCCESSRETLW FALSETX_PASSCALL I2CSTOPBCF BUSSTA,TX_PROGRESSRETLW TRUE;---------------------------------------;从 EEPROM 中读出数据到 I2CBUF 寄存器;---------------------------------------I2CREAD BCF STATUS,RP0BCF BUSSTA,RX_SUCCESSCALL I2CSTARTBTFSS BUSSTA,BUS_BUSYGOTO RX_FAILBCF BUSCON,SLA VE_RWCALL TX_SLA VE_ADDRBTFSS BUSSTA,TX_SUCCESS GOTO RX_FAILCALL TX_DA TA_ADDRBTFSS BUSSTA,TX_SUCCESSGOTO RX_FAILCALL I2CSTARTBSF BUSCON,SLA VE_RWCALL TX_SLA VE_ADDRBTFSS BUSSTA,TX_SUCCESSGOTO RX_FAILBCF BUSSTA,LAST_BYTE_RXMOVLW I2CBUFMOVWF FSRMOVLW 07MOVWF COUNTR_BYTE_LOOPMOVLW 0X01XORWF COUNT,WBTFSC STATUS,ZBSF BUSSTA,LAST_BYTE_RXCALL I2CRXBBTFSS BUSSTA,RX_SUCCESSGOTO RX_FAILMOVF RXBUF,WMOVWF INDFINCF FSR,FDECFSZ COUNT,FGOTO R_BYTE_LOOPGOTO RX_PASSRX_FAIL CALL I2CSTOPBCF BUSSTA,RX_PROGRESSBCF BUSSTA,RX_SUCCESSRETLW FALSERX_PASS CALL I2CSTOPBCF STA TUS,RP0BCF BUSSTA,TX_PROGRESSBCF BUSSTA,RX_PROGRESSBSF BUSSTA,RX_SUCCESSRETLW TRUE;======================================= ; I2C 初始化;=======================================I2CBUS_INITBCF STA TUS,RP0MOVF RC,WANDLW 0X18MOVWF RCCLRF BUSSTACLRF BUSCONRETURN;======================================= ; 传送设备地址;入口: BUSCON;出口: BUSSTA;======================================= TX_SLA VE_ADDRBCF STA TUS,RP0BCF BUSSTA,ACK_ERRORMOVLW SLA VEADDRMOVWF TXBUFBTFSC BUSCON,SLA VE_RWBSF TXBUF,R_NOT_WCALL I2CTXBBTFSC BUSSTA,TX_SUCCESSGOTO TXADDR_SUCCESSCLRWDTBTFSS BUSSTA,ACK_ERRORCALL I2CSTOPGOTO TXADDR_ENDTXADDR_SUCCESSCLRWDTTXADDR_ENDRETURN;======================================= ;TX_DATA_ADDR 发送写/读的地址;======================================= TX_DATA_ADDRBCF STA TUS,RP0MOVLW DATAADDRHMOVWF TXBUFCALL I2CTXBBCF STA TUS,RP0BTFSS BUSSTA,TX_SUCCESSGOTO TX_DATA_ADDR_ERRORMOVLW DATAADDRLMOVWF TXBUFCALL I2CTXBBCF STA TUS,RP0BTFSS BUSSTA,TX_SUCCESSGOTO TX_DATA_ADDR_ERRORGOTO TX_DATA_ENDTX_DATA_ADDR_ERRORBCF BUSSTA,TX_PROGRESSBCF BUSSTA,TX_SUCCESSBSF BUSSTA,ACK_ERRORTX_DATA_ENDRETURN;=======================================;向 EEPROM 输出一个8位数据,并检测EEPROM的ACK信号;入口: TXBUF 寄存器; BUSSTA 寄存器;出口: EEPROM 存储器; BUSSTA 寄存器;======================================I2CTXB BCF STATUS,RP0BSF BUSSTA,TX_PROGRESSBCF BUSSTA,TX_SUCCESSMOVLW 0X08MOVWF BCOUNTTXLOOP CLRWDTBSF STATUS,RP0BCF TRISC,SCLNOPBCF TRISC,SDABCF STA TUS,RP0RLF TXBUF,FBSF STATUS,RP0BTFSC STATUS,CBSF TRISC,SDANOPBSF TRISC,SCLNOPNOPBCF STA TUS,RP0DECFSZ BCOUNT,FGOTO TXLOOP;---------------------------------------;检测是EEPROM否有ACK信号产生,产生为正常;检测方法:; 1. 将RC口的SCL.SDA分别设置为输出和输入状态; 2. 延时2个指令周期,将SCL设置为高电平; 3. 延时2个指令周期,检测RC口SDA的状态; 4. 如果为高电平,设置错误状态,返回; 5. 如果为低电平,延时2个指令周期后,将RC口SCL设置为低电平,继续执行;---------------------------------------BSF STATUS,RP0BCF TRISC,SCLBSF TRISC,SDANOPNOPBSF TRISC,SCLNOPBCF STA TUS,RP0BTFSC RC,SDAGOTO TX_ERRBSF STATUS,RP0BCF TRISC,SCLBCF STA TUS,RP0BCF BUSSTA,TX_PROGRESSBSF BUSSTA,TX_SUCCESSBCF BUSSTA,ACK_ERRORGOTO TX_ENDTX_ERR BCF BUSSTA,TX_PROGRESSBCF BUSSTA,TX_SUCCESSBSF BUSSTA,ACK_ERRORTX_END RETURN;=======================================;从EEPROM中读出 8 位的数据,并发送发送ACK信号;入口: EEPROM 存储器; BUSCON 寄存器;出口: RXBUF 寄存器; BUSSTA 寄存器;=======================================I2CRXB BCF STA TUS,RP0BSF BUSSTA,RX_PROGRESSBCF BUSSTA,RX_SUCCESSMOVLW 0X08MOVWF BCOUNTRXLOOP CLRWDTBSF STATUS,RP0BCF TRISC,SCL ;定义TRISC<SCL>为输出BSF TRISC,SDA ;定义TRISC<SDA>为输入NOPNOPBSF TRISC,SCL ;TRISC<SCL>输出高电平NOPBCF STA TUS,RP0BCF STA TUS,CBTFSC RC,SDA ;原指令为BTFSC TRISC,SDA BSF STATUS,CRLF RXBUF,FDECFSZ BCOUNT,FGOTO RXLOOP;---------------------------------------;发送ACK信号到EEPROM;判断接收的是否为最后一个字节;LAST_BYTE_RX为1,是 SDA发送一个高电平,结束;LAST_BYTE_RX为0,不是 SDA发送一个低电平ACK,继续接收;---------------------------------------BSF STATUS,RP0BCF TRISC,SCLBCF TRISC,SDABTFSC BUSCON,LAST_BYTE_RX ;检测是否是最后一个字节 BSF TRISC,SDA ;是最后一个字节NOP ;发送ACK信号BSF TRISC,SCLNOPNOPNOPNOPBCF TRISC,SCLBCF STA TUS,RP0BCF BUSSTA,RX_PROGRESSBSF BUSSTA,RX_SUCCESSRETURN;=======================================;I2C 开始信号;输入: 无;输出: BUFSSTA<BUS_BUSY>;=======================================I2CSTARTBSF STATUS,RP0BSF TRISC,SDA ;1USNOP ;1USBSF TRISC,SCL ;1USNOPNOPBCF TRISC,SDANOPNOPBCF STATUS,RP0BSF BUSSTA,BUS_BUSYRETURN;=======================================;I2C 结束信号;输入: 无;输出: BUSSTA<BUS_BUSY>;=======================================I2CSTOPBSF STATUS,RP0BCF TRISC,SCLBCF TRISC,SDABSF TRISC,SCLNOPNOPBSF TRISC,SDANOPBCF STATUS,RP0BCF BUSSTA,BUS_BUSYRETURN;=======================================; D10 @; clock in 4Mhz; delay 10ms;=======================================D10 MOVLW 0X0DMOVWF REG1LOOP2 MOVLW 0XFFMOVWF REG2LOOP1 DECFSZ REG2,fGOTO LOOP1DECFSZ REG1,fGOTO LOOP2RETURN;=======================================I2CERR CLRWDTNOPNOPNOPRETURNEND硬件I2C的主模式,只能在具有MSSP模块的单片机里实现,如PIC16F87X,而PIC16C7X 的SSP只能启用I2C从模式。

PIC单片机对9346EEPROM数据的读写

PIC单片机对9346EEPROM数据的读写

PIC单片机对9346EEPROM数据的读写
实验目的:熟悉SPI总线以及9346EEPROM的读写
;RBO键按下时把DATA和DATA2写入到EEPROM中以EE—ADDR为地址的单元内,;完成后,单个数码观显示“9”做为完成标志
;RB1键按下时,读取EEPROM中以EE—ADDR为地址的单元,并送数码管显示
;硬件要求:S3、S5、S6拨码管置ON,S1第7、8位置ON。

LIST P=16F877A,R=DEC
include “P16F877A.inc”;包含头文件
__CONFIG _DEBUG_OFF">#DEFINE CS PORTC,2 ;片选信号
#DEFINE CLK PORTC,3 ;时钟信号输入
#DEFINE DI PORTC,5 ;数据输入脚
#DEFINE D0 PORTC,4 ;数据输出脚EE_ADDR EQU 05H ;待写EEPROM单元地址EE_DATA EQU 56H ;待写入的数据
EE_DATA2 EQU 78HTEMP1 EQU 30H ;读EEPROM结果存放单元
TEMP2 EQU 31H
DL1 EQU 77H ;延时用
DL2 EQU 78H ;延时用
;******************************************************
ORG 000H ;复位地址
NOP ;放置一条ICD必需的空操作指令
GOTO MAIN
ORG 0008H
TABLE
ADDWF PCL,1 ;PC值加上偏移地址
RETLW 0C0H ;0
RETLW 0F9H ;1的编码。

PIC单片机程序EEPROM

PIC单片机程序EEPROM

unsigned char const ZHI[12]={'0','1','2','3','4','5','6','7','8','9','\0'};
unsigned char PAGE[4];
int main()
{
TRISC4=1;
TRISC0=0;
TRISC1=0;
TRISC2=0;
void KEYPAD()
{
if(!KEY) //如果检测的低电平,说明按键按下
{
DelayMs(10); //延时去抖
if(!KEY) //再次判断是否低电平
{
while(!KEY); //如果确认按下按键等待按键释放,没有释放则一直等待
{
TRISC3=0;
InitLCD();
while(1)
{
//按键复位
if(!KEY) //如果检测的低电平,说明按键按下
{
DelayMs(10); //延时去抖
if(!KEY) //再次判断是否低电平
{
while(!KEY); //如果确认按下按键等待按键释放,没有释放则一直等待
unsigned char VALUE;
/***********函数定义******************/
unsigned char READ();
void WRITE(unsigned char DATA);
void KEYPAD();
#define KEY RC4

PIC24FV32A304单片机内部EEPROM读写测试

PIC24FV32A304单片机内部EEPROM读写测试

参考手册PIC24FV32KA304 Family Data Sheet (07-31-2013)第65-68页:修改参考手册中的代码,构建成读写函数如下://EEPROM读写测试int __attribute__ ((space(eedata))) eeData=0x0000;//擦除一个字void EEPROM_ERASE_WORD(unsigned intaddr){NVMCON = 0x4058;TBLPAG = __builtin_tblpage(&eeData);__builtin_tblwtl(__builtin_tbloffset(&eeData)+addr, 0); asm volatile ("disi #5");__builtin_write_NVM();while(NVMCONbits.WR==1);//擦除所有void EEPROM_ERASE_ALL(){NVMCON = 0x4050;asm volatile ("disi #5");__builtin_write_NVM();}//向地址addr写一个字int EEPROM_WRITE_WORD(unsigned intaddr,intnewData ){NVMCON = 0x4004;TBLPAG = __builtin_tblpage(&eeData);__builtin_tblwtl(__builtin_tbloffset(&eeData)+addr, newData);asm volatile ("disi #5");__builtin_write_NVM();while(NVMCONbits.WR==1);return 1;}//在地址addr读一个字int EEPROM_READ_WORD(unsigned intaddr){TBLPAG = __builtin_tblpage(&eeData);return __builtin_tblrdl(__builtin_tbloffset(&eeData)+addr);}int main(void){//数据以16bit对齐的方式访问EEPROM空间//共有512byte存储空间,地址以byte寻址,访问的地址256个(0 2 4 6 0..510偶数)//读写测试intI,Data[];//下面一段代码放入函数中调用,无法运行,不知是什么原因,只能直接在main 中运行…for(i=0;i<512;i+=2){EEPROM_WRITE_WORD(i,i/2);//先写入数据Data[i]=EEPROM_READ_WORD(i);//读出数据Send_byte(Data[i]%256);Send_byte(Data[i]/256);//发送数据}}调试信息:编译信息:2015-12-15测试。

EEPROM

EEPROM
EEPROM_write(4000,kk1);
EEPROM_write(4005,kk2);*/
}
}
if(PINF!=0XFF)
{
delayms(20);
if(PINF!=0xff)
AVR(ATMEGA128/16)内部EEPROM读写默认
下面这程序是128的
/****************************内部EEPROM头文件***************************/
#ifndef __eeprom_H__
#define __eeprom_H__
8、全局中断控制位GIE置1,放开总中断屏蔽位(如果打算利用EEIF中断功能)。
9、清除写操作允许位WREN,在本次写操作没有完毕之前禁止重开新的一次写操作。
10、当写操作完成时,控制位WR被硬件自动清零0,中断标志位EEIF被硬件自动置1。
如果本次写操作还没有完成,那么可以用软件查询EEIF位是否为1,或者查询WR位是否为0,来判定写操作是否结束。
/*EEPROM写子入程序*/
//写一个字节
void EEPROM_write(unsigned int Address, unsigned char Data)
{
while(EECR & (1<<EEWE)); /* 等待上一次写操作结束 */
EEAR = Address; /* 设置地址和数据寄存器*/
内部EEPROM读写操作步骤
从EEPROM中读取数据步骤:
1、把地址写入到地址寄存器EEADR中,注意该地址不能超过所用PIC1687X型号 单片机内部EEPROM实际容量。

使用PIC单片机的EEPROM

使用PIC单片机的EEPROM

使用PIC‎单片机的E‎E PROM‎P‎I C单片机‎中程序存储‎器是Fla‎s h结构,‎数据存储器‎有两种类型‎S RAM和‎E EPRO‎M 程序设计‎时,大部分‎变量特别是‎全局变量默‎认是存放在‎S RAM中‎,这些数据‎掉电后不能‎保存,复位‎后这些变量‎又变为默认‎值。

在某些‎情况下,希‎望单片机复‎位后能记忆‎复位前的数‎值,这就要‎用EEPR‎O M来存储‎这些数值。

‎PIC‎16F88‎6系列单片‎机的SRA‎M是368‎字节,EE‎P ROM是‎256字节‎。

通过对4‎个寄存器进‎行操作就可‎以实现EE‎P ROM的‎操作。

‎以下是对E‎E PROM‎的读和写程‎序代码:‎void‎EEPR‎O Mwri‎t e(uc‎h ar E‎E Addr‎,ucha‎r Cmd‎){‎E EADR‎= EE‎A ddr;‎ //‎E EPRO‎M的地址‎EEDA‎T A = ‎C md; ‎ //E‎E PROM‎的写数据‎E‎E PGD ‎= 0;‎//CF‎G S = ‎0; ‎//PI‎C18F中‎要用到‎G IE =‎0;‎W REN ‎= 1;‎EE‎C ON2 ‎= 0x5‎5; ‎‎ /‎/必须按这‎样的时序‎EECO‎N2 = ‎0xAA;‎WR ‎= 1;‎whil‎e(WR=‎=1); ‎ //等‎待写操作完‎成GI‎E = 1‎;‎}uc‎h ar E‎E PROM‎r ead(‎u char‎EEAd‎d r){‎uch‎a r Re‎E EPRO‎M read‎;EE‎A DR =‎EEAd‎d r;‎EEP‎G D = ‎0;/‎/CFGS‎= 0;‎ //‎P IC18‎F中要用到‎GIE‎= 0;‎RD ‎= 1;‎ReEE‎P ROMr‎e ad =‎EEDA‎T A; ‎//EEP‎R OM的读‎数据R‎D = 0‎;GI‎E = 1‎;re‎t urn ‎R eEEP‎R OMre‎a d;}‎‎。

PIC单片机片内EEPROM的读写程序

PIC单片机片内EEPROM的读写程序

PIC单片机片内EEPROM的读写程序因为也是摸索着学习PIC单片机,当要用到EEPROM存储部分系统参数,看单片机手册上的资料,觉得还是比较麻烦,然后还是不太会,然后就想找找看网上有没有现成的PIC单片机的片内EEPROM的读写程序,然后都没有找到想要的,而且对汇编语言的也不知道,所以搜索了下最后终于发现PICC编译器里面其实对内部的EEPROM的读写有头文件,可以直接来用,方法如下:PICC的安装目录下C:\Program Files\HI-TECH Software\PICC\9.81\include(这是我的电脑里目录)里面有一个eeprom_routines.h的文件这个就是关于EEPROM 中的读写程序,具体程序如下:// This header file should not be included directly// Inclusion of this file is provided indirectly by including htc.h/******************************************************************** ***//****** EEPROM memory read/write macros and function definitions *******//******************************************************************** ***//* NOTE WELL:The macro EEPROM_READ() is NOT safe to use immediately after anywrite to EEPROM, as it does NOT wait for WR to clear. This is bydesign, to allow minimal code size if a sequence of reads isdesired. To guarantee uncorrupted writes, use the functioneeprom_read() or insertwhile(WR)continue;before calling EEPROM_READ().*/#if EEPROM_SIZE > 0#ifdef __FLASHTYPE// macro versions of EEPROM write and read#define EEPROM_WRITE(addr, value) \do{ \while(WR)continue;EEADRL=(addr);EEDATA=(value); \EECON1&=0x3F;CARRY=0;if(GIE)CARRY=1;GIE=0; \WREN=1;EECON2=0x55;EECON2=0xAA;WR=1;WREN=0; \if(CARRY)GIE=1; \}while(0)#define EEPROM_READ(addr)((EEADRL=(addr)),(EECON1&=0x3F),(RD=1),EEDATA)#else // else doesn't write flash#define EEPROM_WRITE(addr, value) \do{ \while(WR)continue;EEADRL=(addr);EEDATA=(value); \CARRY=0;if(GIE)CARRY=1;GIE=0; \WREN=1;EECON2=0x55;EECON2=0xAA;WR=1;WREN=0; \if(CARRY)GIE=1; \}while(0)#define EEPROM_READ(addr) ((EEADRL=(addr)),(RD=1),EEDATA) #endif/* library function versions */extern void eeprom_write(unsigned char addr, unsigned char value); extern unsigned char eeprom_read(unsigned char addr);#endif // end EEPROM routines看到这里就知道了。

dsPIC30F6014内部EEPROM读写C程序设计及其应用

dsPIC30F6014内部EEPROM读写C程序设计及其应用

0x9000,0xA000, 0xB000, 0xC000, 0xD000, 0xE000,
· 设定 NVMCON 寄存器,以便确定是字,还是行
0xF000,};
擦除。
擦除 E E P R O M 中的数据
· 往寄存器 NVMKEY 里写 0x55 和 0xAA。
擦除的步骤如下:
·设定寄存器 N V M C O N 的 W R 位,开始擦除。
据地址
// 要擦除的地址。
asm volatile ("TBLWTL w4,[w5]"); //把数
NVMCON = NVMCON_Erase
据从起始地址写到目标地址
OneRowEEPROM; // 擦除一行。
dm_addr_lowБайду номын сангаас+; //地址自增,直至写完一行
· 检测寄存器 N V M C O N 的 W R 位,等待完成。 *dm_addr_low, unsigned int *sourceArray)
下面程序 eraseOneRowEEProm()擦除 EEPROM 中

一行数据。
unsigned int j;
#define NVMCON_EraseOneRowEEPROM 0x4045
·设定寄存器 NVMADR 和 N V M A D R U ,以便确定
·检测寄存器 N V M C O N 的 W R 位,等待完成。
擦除的地址和表头位置。
下面程序 writeOneRowEEProm()烧写一行数据到
· 设定 NVMCON 寄存器,以便确定是字,行还是 E E P R O M 中。
# d e f i n e _ E E D A T A ( N ) N V M C O N 的 W R 位,等待完成
  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 数据区进行读写的演示程序;。

相关文档
最新文档