<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          8051模擬IIC操作EEPROM

          作者: 時間:2016-12-03 來源:網(wǎng)絡(luò) 收藏
          注:
          本篇內(nèi)容和STM32模擬IIC操作EEPROM思路是一樣的,是一個程序到不同平臺的移植。

          首先是EEPROM.h文件內(nèi)容:

          #ifndef _eeprom_h_
          #define _eeprom_h_

          #include //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
          #include

          #define EEPROM_ADDRESS 0x57

          sbit SDA = P1^2; //EEPROM的數(shù)據(jù)線
          sbit SCL = P1^1; //EEPROM的時鐘線
          sbit WP = P1^0; //EEPROM的寫保護,給低電平表示讀寫均允許,也就是標(biāo)準(zhǔn)的模式。

          extern void EEPROM_Init();

          extern unsigned char eeprom_continue_write(unsigned char c_slave_address7bit,unsigned char c_reg_address,
          unsigned char c_continue_write_arr[],unsigned int len);

          extern unsigned char read_eeprom_status(unsigned char c_slave_address7bit);

          extern unsigned char eeprom_continue_read(unsigned char c_slave_address7bit,unsigned char c_reg_address,
          unsigned char c_continue_read_arr[],unsigned int len);

          extern unsigned char EEPROM_Read(unsigned char c_slave_address7bit,unsigned char c_reg_address);

          extern unsigned char EEPROM_Write(unsigned char c_slave_address7bit,unsigned char c_reg_address,unsigned char u_data);

          #endif

          本文引用地址:http://www.ex-cimer.com/article/201612/325194.htm
          再個就是EEPROM.c文件的內(nèi)容:

          #include "eeprom.h"
          #include //頭文件的包含
          #include

          #include "usart.h"


          #define _Nop() _nop_() //定義空指令

          static void EEPROM_Stop( void );

          static void Delay_us(unsigned int i_delay_count)
          {
          int j = 0,i;
          for(j = 0 ; j < 5; j ++)
          for(i = 0 ; i < i_delay_count ; i ++)
          ;
          }

          /*******************************************************************************
          * I2C電路:
          * 單片機 EEPROM
          * P10--------->WP
          * P11--------->SCL
          * P12--------->SDA
          *
          * A0,A1,A2均通過硬件拉高電平
          *
          * 我這里將EEPROM的地址按照如下方式規(guī)劃:
          * 0101 0(A2)(A1)(A0)
          * 因此EEPROM的地址為0x57.
          *
          * copyright by wit_yuan 2016-09-15 at 龍興園北區(qū)
          -------------------------------------------------------------------------------*/
          void EEPROM_Init()
          {
          //將WP設(shè)置為低電平即可
          WP = 0;
          //將IIC總線置高即可
          SCL = 1;
          SDA = 1;
          }

          /*
          *
          * EEPROM_Start():
          * 內(nèi)部函數(shù)
          *
          */
          static void EEPROM_Start()
          {
          SDA=1; //由于上一個SCL狀態(tài)是0或者是1,要讓SDA穩(wěn)定輸出,都可以設(shè)置為1
          Delay_us(2);

          SCL=1; //讓SCL發(fā)生變化,為0不變,為1則變化,表明數(shù)據(jù)可以變動了。
          Delay_us(2);

          SDA=0; //SDA線數(shù)據(jù)變化,從而可以保證發(fā)出的是start信號。
          Delay_us(2);

          SCL=0; //將I2C總線鉗住,下一個時間SDA可以輸出高低電平。
          Delay_us(4);
          }

          /*
          *
          * EEPROM_Send_Byte():
          * 內(nèi)部函數(shù)
          *
          */
          static void EEPROM_Send_Byte( unsigned char txd)
          {
          unsigned char t;
          // SDA_OUT();
          SCL=0;//拉低時鐘開始數(shù)據(jù)傳輸
          Delay_us(2);
          for(t=0;t<8;t++)
          {
          if((txd&0x80)>>7)
          SDA=1;
          else
          SDA=0;
          txd<<=1;
          Delay_us(2);
          SCL=1;
          Delay_us(2);
          SCL=0;
          Delay_us(2);
          }
          }

          /*
          *
          * EEPROM_Read_Byte():
          * 內(nèi)部函數(shù)
          *
          */
          static unsigned char EEPROM_Read_Byte()
          {
          unsigned char i,u_receive=0;
          // SDA_IN();//SDA設(shè)置為輸入
          for(i=0;i<8;i++ )
          {
          SCL=0;
          Delay_us(4);
          SCL=1;
          Delay_us(1);
          u_receive<<=1;
          if(SDA)
          u_receive++;
          }

          return u_receive;
          }


          /*
          *
          * EEPROM_Ack():
          * 內(nèi)部函數(shù)
          * 2016-09-16 edited for 8051. by wit_yuan
          */
          static void EEPROM_Ack()
          {
          SCL=0;
          Delay_us(2);

          //////add 2016-09-16 by wit_yuan///////////
          SDA = 1;
          Delay_us(1);


          SDA=0;
          Delay_us(1);

          SCL=1;
          Delay_us(1);

          SCL=0;
          Delay_us(4);

          //////add 2016-09-16 by wit_yuan///////////
          SDA = 1;
          Delay_us(1);

          }


          /*
          *
          * EEPROM_Wait_Ack():
          * 內(nèi)部函數(shù)
          *
          */
          static unsigned char EEPROM_Wait_Ack()
          {
          unsigned char ucErrTime=0;

          SCL=0;
          Delay_us(1);

          while(SDA)
          {
          ucErrTime++;
          if(ucErrTime>250)
          {
          EEPROM_Stop();
          return 1; //超時,表明數(shù)據(jù)傳輸有問題
          }
          }
          SCL=1;
          Delay_us(1);


          SCL=0;//時鐘輸出0
          Delay_us(2);

          return 0;
          }

          /*
          *
          * EEPROM_No_Ack():
          * 內(nèi)部函數(shù)
          *
          */
          static void EEPROM_No_Ack()
          {

          SCL=0;
          Delay_us(2);

          SDA=1;
          Delay_us(1);

          SCL=1;
          Delay_us(1);

          SCL=0;
          Delay_us(4);
          }

          /*
          *
          * EEPROM_Stop():
          * 內(nèi)部函數(shù)
          *
          */
          static void EEPROM_Stop()
          {
          SDA=0; //上一個狀態(tài)的SCL=0,這個狀態(tài)設(shè)置SDA=0,目的是讓狀態(tài)能反轉(zhuǎn)
          Delay_us(2);

          SCL=1; //該時刻設(shè)置SCL=1,然后就可以讓數(shù)據(jù)穩(wěn)定在改狀態(tài)下。
          Delay_us(2);

          SDA=1;
          Delay_us(4);
          }


          unsigned char EEPROM_Write(unsigned char c_slave_address7bit,unsigned char c_reg_address,unsigned char u_data)
          {
          unsigned char u_wait_err = 0;

          EEPROM_Start();
          EEPROM_Send_Byte(c_slave_address7bit << 1);
          u_wait_err |= EEPROM_Wait_Ack();

          EEPROM_Send_Byte(c_reg_address);
          u_wait_err |= EEPROM_Wait_Ack();

          EEPROM_Send_Byte(u_data);
          u_wait_err |= EEPROM_Wait_Ack();

          EEPROM_Stop();

          if( u_wait_err == 0)
          return 0;
          return 1;

          }

          unsigned char EEPROM_Read(unsigned char c_slave_address7bit,unsigned char c_reg_address)
          {
          unsigned char u_temp;
          unsigned char u_wait_err = 0;

          EEPROM_Start();
          EEPROM_Send_Byte(c_slave_address7bit << 1);
          u_wait_err |= EEPROM_Wait_Ack();

          EEPROM_Send_Byte(c_reg_address);
          u_wait_err |= EEPROM_Wait_Ack();

          EEPROM_Start();
          EEPROM_Send_Byte((c_slave_address7bit << 1)+1);
          u_wait_err |= EEPROM_Wait_Ack();

          u_temp = EEPROM_Read_Byte( );
          EEPROM_No_Ack();//不需要響應(yīng)

          EEPROM_Stop();

          return u_temp;

          }


          unsigned char eeprom_continue_read(unsigned char c_slave_address7bit,unsigned char c_reg_address,
          unsigned char c_continue_read_arr[],unsigned int len)
          {
          unsigned char u_wait_err = 0;
          int i = 0;

          EEPROM_Start();
          EEPROM_Send_Byte(c_slave_address7bit << 1);
          u_wait_err |= EEPROM_Wait_Ack();

          EEPROM_Send_Byte(c_reg_address);
          u_wait_err |= EEPROM_Wait_Ack();

          EEPROM_Start();
          EEPROM_Send_Byte((c_slave_address7bit << 1)+1);
          u_wait_err |= EEPROM_Wait_Ack();


          for(i = 0 ; i < len - 1 ; i ++)
          {
          c_continue_read_arr[i] = EEPROM_Read_Byte( );

          EEPROM_Ack();
          }

          c_continue_read_arr[len-1] = EEPROM_Read_Byte( );
          //u_wait_err |= EEPROM_Wait_Ack();
          EEPROM_No_Ack();//不需要響應(yīng)


          EEPROM_Stop();

          if(u_wait_err == 0)
          return 0;
          return 1;
          }


          unsigned char eeprom_continue_write(unsigned char c_slave_address7bit,unsigned char c_reg_address,
          unsigned char c_continue_write_arr[],unsigned int len)
          {
          unsigned int i;
          unsigned int i_err = 0;

          EEPROM_Start();
          EEPROM_Send_Byte(c_slave_address7bit << 1);
          i_err |= EEPROM_Wait_Ack();

          EEPROM_Send_Byte(c_reg_address);
          i_err |= EEPROM_Wait_Ack();

          for( i = 0 ; i < len ; i ++ )
          {
          EEPROM_Send_Byte(c_continue_write_arr[i]);

          i_err |= EEPROM_Wait_Ack();
          }

          EEPROM_Stop();

          if(i_err == 0)
          return 0;

          return 1;
          }




          unsigned char read_eeprom_status(unsigned char c_slave_address7bit)
          {
          unsigned int i = 0;
          int i_ret = 0;

          do
          {
          EEPROM_Start();
          EEPROM_Send_Byte(c_slave_address7bit << 1);

          i_ret = EEPROM_Wait_Ack();

          i ++;
          if(i >= 10000)
          {
          EEPROM_Stop();
          return 1;//表示無響應(yīng)
          }
          }while(i_ret);


          EEPROM_Stop();

          return 0;//表示操作序列結(jié)束
          }

          貼上usart.h文件的內(nèi)容:

          #ifndef _usart_h_
          #define _usart_h_

          #include //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
          #include


          extern void UART_Init(void);

          extern void Send_String(unsigned char *u_string);

          extern void Send_UHex(unsigned char u_tx);

          #endif

          然后是usart.c文件的內(nèi)容:

          #include "usart.h"

          /*------------------------------------------------
          串口通訊初始化
          ------------------------------------------------*/
          void UART_Init(void)
          {
          SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
          TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重裝
          TH1 = 0xFD; // TH1: 重裝值 9600 波特率 晶振 11.0592MHz
          TR1 = 1; // TR1: timer 1 打開
          TI = 1;
          }

          /*
          * Send_UChar:
          * 發(fā)送單個字符
          *
          *
          */
          void Send_UChar(unsigned char u_tx)
          {
          SBUF = u_tx;
          while(!TI);
          TI = 0;
          }

          /*
          * Send_String:
          * 發(fā)送字符串
          *
          *
          */
          void Send_String(unsigned char *u_string)
          {
          while(*u_string)
          {
          Send_UChar(*u_string);
          u_string++;
          }
          }

          void Send_UHex(unsigned char u_tx)
          {
          unsigned char u_high;
          unsigned char u_low;

          u_high = u_tx/16 ;
          u_low = u_tx%16 ;

          if((u_high >= 10) && (u_high <= 15))
          {
          u_high = (u_high - 10) + A;
          }
          else
          {
          u_high = u_high + 0;
          }
          if((u_low >= 10) && (u_low <= 15))
          {
          u_low = (u_low - 10) + A;
          }
          else
          {
          u_low = u_low + 0;
          }
          Send_UChar(u_high);
          Send_UChar(u_low);
          Send_UChar( );
          }


          最后就是main.c文件的內(nèi)容:

          /*-------------------------------------------------------------------------------
          * 名稱:51單片機控制EEPROM
          * 晶振使用11.0592M
          *
          * I2C電路:
          * 單片機 EEPROM
          * P10--------->WP
          * P11--------->SCL
          * P12--------->SDA
          *
          * A0,A1,A2均通過硬件拉高電平
          *
          * copyright by wit_yuan 2016-09-15 at 龍興園北區(qū)
          -------------------------------------------------------------------------------*/
          #include //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
          #include
          #include
          #include "usart.h"

          unsigned char g_c_continue_write[16];
          unsigned char g_c_continue_read_array[16];

          /*------------------------------------------------
          主函數(shù)
          ------------------------------------------------*/
          void main (void)
          {
          unsigned char value,i;



          UART_Init();

          EEPROM_Init();

          Send_String("--------------------app run-----------------n");

          #if 0
          EEPROM_Write(EEPROM_ADDRESS,0,0x02);

          for(i = 0 ; i < 100 ; i ++);
          for(i = 0 ; i < 100 ; i ++);
          for(i = 0 ; i < 100 ; i ++);

          value = EEPROM_Read(EEPROM_ADDRESS,0);

          Send_String("n value :");
          Send_UHex(value);
          Send_String("n ");
          #else

          #if 1
          Send_String("array :n");

          for(i = 0 ; i < 16 ; i ++)
          {
          g_c_continue_write[i] = i + 1;
          Send_UHex(g_c_continue_write[i]);
          }
          Send_String("n");


          Send_String("write array : n");
          value = eeprom_continue_write(EEPROM_ADDRESS,0,g_c_continue_write,16);


          Send_String("read write status : n");
          #if 1
          value = read_eeprom_status(EEPROM_ADDRESS);

          Send_String("n status :");
          Send_UHex(value);
          Send_String("n ");
          #endif
          #endif

          #if 1
          Send_String("read array : n");

          eeprom_continue_read(EEPROM_ADDRESS,0,g_c_continue_read_array,16);

          Send_String("read:n");
          for(i = 0 ; i < 16 ; i ++)
          {
          Send_UHex(g_c_continue_read_array[i]);
          }
          Send_String("n");


          value = EEPROM_Read(EEPROM_ADDRESS,0x0D);

          Send_String("n value :");
          Send_UHex(value);
          Send_String("n ");
          #endif
          #endif

          Send_String("n ----------app end----------------n");
          while (1) //主循環(huán)
          {



          }
          }

          更多的具體講解,就參考stm32模擬IIC操作EEPROM那篇文章吧。



          關(guān)鍵詞: 8051模擬IIC操作EEPRO

          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();