历史上的今天
返回首页

历史上的今天

今天是:2025年01月17日(星期五)

正在发生

2018年01月17日 | 24LCxx读写EEPROM的实例(C语言)

2018-01-17 来源:eefocus

//************************************************************************ 
//* 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  
#include    // Load I2C Header file from defult direct 
#include  
#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; 
}


推荐阅读

史海拾趣

EG & G Inc公司的发展小趣事

为了进一步扩大市场份额,EG & G Inc公司积极开展市场拓展和国际合作。公司在中国、欧洲等多个国家和地区设立了分支机构,与当地企业建立了紧密的合作关系。同时,公司还积极参与国际展览和交流活动,展示了其先进的技术和产品。这些努力使得EG & G Inc公司在国际市场上获得了更多的机会和认可。

Elite公司的发展小趣事

随着公司规模的不断扩大和市场的不断拓展,Elite开始实施全球化战略。公司积极开拓国际市场,与全球知名企业建立合作关系,共同推动行业发展。同时,Elite还注重品牌塑造和企业文化建设,通过举办各类公益活动、提升员工福利待遇等方式,增强企业凝聚力和社会影响力。

DAICO公司的发展小趣事

随着技术的不断进步,DAICO公司成功研发出一系列高可靠性的定制产品。这些产品以其卓越的性能和稳定性,赢得了客户的广泛认可。DAICO开始将业务扩展到商用飞机和其他高端商业行业,为卫星、雷达、导航、通信、电子战和导弹系统提供复杂操作不可或缺的一部分。

Dawn Electronics Inc公司的发展小趣事

在快速发展的同时,Dawn Electronics Inc公司始终关注社会责任。公司积极参与公益活动,支持教育、环保等事业。同时,公司还注重环保和可持续发展,采用环保材料和生产工艺,减少对环境的影响。这些举措不仅提升了公司的社会形象,也为公司的长期发展奠定了坚实的基础。

GE (General Electric)公司的发展小趣事
如急停按钮SB1,用于在紧急情况下迅速切断电源,保障操作安全。
广州基安彼(GMB)公司的发展小趣事
包括机床指示灯和照明灯,用于指示机床的工作状态和提供工作照明。

问答坊 | AI 解惑

晶闸管在电力稳压器中的应用

摘要:在所研制的新型无触点电力稳压器中,采用晶闸管作为开关器件。文中介绍该系统基本工作原理,详细分析晶闸管在使用过程中存在的一些问题及解决方法。目前流行的电力稳压器大多采用伺服电机带动炭刷移动调整电压。它具有整机效率高、输出波形好 ...…

查看全部问答>

自学成才-电子工程师-找工作 General Electronics Engineer

我从小就有很强的好奇心和动手能力,想知道每一件东西是如何工作的,对自然科学非常着迷。我还记得,小学时因为在课堂上用钉子和电线做电磁铁被批评;初中因为画电路图做收音机被取笑;高中被禁止做一种能开所有教室门锁的万能钥匙。我父亲是一名中 ...…

查看全部问答>

tcpmp 的问题.

tcpmp 好不好用,下了一个, 在EVC下怎么编译不了?请高手介绍一下经验.…

查看全部问答>

闹钟的问题

用IAppointment设定一个闹钟,时间到了没有\"日程提醒\" 再去设定另一个闹钟,上一个已过时间的闹钟就马上蹦出\"日程提醒\"来,这是怎么回事? “日程提醒”界面好好象是poom画的,我想显示自己的闹钟界面该怎么做? 我的poom组件还需要其它设置 ...…

查看全部问答>

wince下用GDI加载bmp图片的方法(能提供下可用的代码吗?)跪求

wince下用GDI加载bmp图片的方法(能提供下可用的代码吗?)跪求…

查看全部问答>

arm9 开发板

想自己学一下嵌入式方面的东西,在网上看了一下arm9 的板子,但不知道哪一块比较合适 2410或是2440的,请大家推荐一块,价格合理,性能比较好,适合初学者的。支持linux和wince。…

查看全部问答>

wince 连接sql server解决方案

我现在使用c++在pda下需要访问sql server,使用RDA.现在有个问题就是需要实时的和sql server通讯,使用RDA速度总是有2秒左右的延时。 不知道是RDA固有的问题,还是sql server设置的问题? 在PDA上真的没有好的解决方案?不能直接连接sql server?不 ...…

查看全部问答>

飞思卡尔单片机MC9RS08KA8的C程序的例子

高手求助一下,哪位有MC9RS08KA8的C程序例子呢?急用!小女子新学,好歹不知道从何下手!谢谢各位的帮忙!…

查看全部问答>

讨论下mma7455的一些参数含义

最近在看mma7444的资料,看到里面有俩个中断脚,init1和init2,还看到里面讲到脉冲测试,水平测试。不知道脉冲测试和水平测试指的是什么东西?还有为啥有俩个中断引脚?这俩个引脚如何使用?还有大家怎么处理x,y,z轴的校准,以及如何处理得到的数据 ...…

查看全部问答>

很全面的传感器应用电路

文档一共讲述14章的内容,基本涉及了现有常用传感器的电路,分享给大家····…

查看全部问答>