原创 拟I2C通信协议C程序

2008-7-8 23:08 4210 8 8 分类: 通信

/*********************************************************************************
****Micocontroller:   AT89C51 at 12MHz      ** * * * **        *       ********     **      
************Device:   24aa512, 2            **        **       * *      **     **     **
*Programming Model:   Virtual I2C           ** * *    **      *    *      ***   ********    
************Author:   ***                   **        **     * *** *      *** **     **
**************Date:   2006.11.08            **        ** * *        *******   **     **   
*********************************************************************************/
#include<string.h>
           #include<at89x51.h>
           #include<intrins.h>
           #define DELAY_TIME 60 /*经实验,不要小于50!否则可能造成时序混乱*/
           #define TRUE 1
           #define FALSE 0
     #define FLASH_PAGE   7 /*存储器页面大小*/
           sbit SCL="P1"^7;/*假设由P1.7和P1.6控制*/
           sbit SDA="P1"^6;
       /********** Function Definition 函数定义 ************/
           void DELAY(unsigned int t) /*延时函数*/
           {
               while(t!=0)
                   t--;
           }
           void I2C_Start(void)
           {
               /*启动I2C总线的函数,当SCL为高电平时使SDA产生一个负跳变*/
               SDA="1";
               SCL="1";
               DELAY(DELAY_TIME);
               SDA="0";
               DELAY(DELAY_TIME);
               SCL="0";
               DELAY(DELAY_TIME);
           }
           void I2C_Stop(void)
           {
               /*终止I2C总线,当SCL为高电平时使SDA产生一个正跳变*/
               SDA="0";
               SCL="1";
               DELAY(DELAY_TIME);
               SDA="1";
               DELAY(DELAY_TIME);
               SCL="0";
               DELAY(DELAY_TIME);
           }
           void SEND_0(void)    /* SEND ACK */
           {
               /*发送0,在SCL为高电平时使SDA信号为低*/
               SDA="0";
               SCL="1";
               DELAY(DELAY_TIME);
               SCL="0";
               DELAY(DELAY_TIME);
           }
           void SEND_1(void)
           {
               /*发送1,在SCL为高电平时使SDA信号为高*/
               SDA="1";
               SCL="1";
               DELAY(DELAY_TIME);
               SCL="0";
               DELAY(DELAY_TIME);
           }
           bit Check_Acknowledge(void)
           {
               /*发送完一个字节后检验设备的应答信号*/
               SDA="1";
               SCL="1";
               DELAY(DELAY_TIME/2);
               F0=SDA;
               DELAY(DELAY_TIME/2);
               SCL="0";
               DELAY(DELAY_TIME);
               if(F0==1)
                   return FALSE;
               return TRUE;
           }
           void WriteI2CByte(char b)reentrant
           {
               /*向I2C总线写一个字节*/
               char i;
               for(i=0;i<8;i++)
                   if((b<<i)&0x80)
                       SEND_1();
                   else
                       SEND_0();
           }
      
           char ReadI2CByte(void)reentrant
           {
               /*从I2C总线读一个字节*/
               char b="0",i;
               for(i=0;i<8;i++)
               {
                   SDA="1";     /*释放总线*/
                   SCL="1";     /*接受数据*/
                   DELAY(10);
                   F0=SDA;    /*psw for user flag*/
                   DELAY(10);
                   SCL="0";
                   if(F0==1)
                       {
                           b="b"<<1;
                           b="b|0x01";
                       }
                   else
                       b="b"<<1;
               }
               return b;
           }


       /**********以下为读写24aa512的函数**********/
       void Write_One_Byte(char id, char addrh,char addrl, char thedata)
       {
                 bit acktemp="1";
                 /*write a byte to mem*/
                 I2C_Start();
                 WriteI2CByte(id);
                 acktemp="Check"_Acknowledge();
                 WriteI2CByte(addrh);/*address high byte*/
                 acktemp="Check"_Acknowledge();
                 WriteI2CByte(addrl);/*address low   byte*/
                 acktemp="Check"_Acknowledge();
                 WriteI2CByte(thedata);/*thedata*/
                 acktemp="Check"_Acknowledge();
                 I2C_Stop();
       }
       void Write_A_Page( char id, char *buffer,char addrh,char addrl) /*page data number is different*/
       {
                 bit acktemp="1";
                 bit wrtmp;
                 int i;
                 /*write a page to at24c02*/
                 I2C_Start();
                 WriteI2CByte(id);
                 acktemp="Check"_Acknowledge();
                 WriteI2CByte(addrh);/*address high byte*/
                 acktemp="Check"_Acknowledge();
                 WriteI2CByte(addrl);/*address low   byte*/
                 acktemp="Check"_Acknowledge();
                 for(i=0;i<FLASH_PAGE;i++)
                 {
                   WriteI2CByte(buffer);
                   if(!Check_Acknowledge())
                       {
                           I2C_Stop();
                       }
                  }


                 I2C_Stop();
      


       }
       char Read_One_Byte(char id ,char addrh,char addrl)
       {          bit acktemp="1";
                 char mydata;
                  /*read a byte from mem*/
                 I2C_Start();
                 WriteI2CByte(id);
                 acktemp="Check"_Acknowledge();
                 WriteI2CByte(addrh);/*address high byte*/
                 acktemp="Check"_Acknowledge();
                 WriteI2CByte(addrl);/*address low   byte*/
                 acktemp="Check"_Acknowledge();
                 I2C_Start();
                 WriteI2CByte(id+1);
                 acktemp="Check"_Acknowledge();


                 mydata="ReadI2CByte"();
                 acktemp="Check"_Acknowledge();
                 return mydata;
                 I2C_Stop();
       }
       void Read_N_Bytes(char id ,char *buffer,char n,char addrh,char addrl)
       {
                 bit acktemp="1";
                 int i="0";
                  /*read 8 bytes from mem*/
                 I2C_Start();
                 WriteI2CByte(id);
                 acktemp="Check"_Acknowledge();
                 WriteI2CByte(addrh);/*address high byte*/
                 acktemp="Check"_Acknowledge();
                 WriteI2CByte(addrl);/*address low   byte*/
                 acktemp="Check"_Acknowledge();
                 I2C_Start();
                 WriteI2CByte(id+1);
                 acktemp="Check"_Acknowledge();
      


                 for(i=0;i<n;i++)
                 {
                       buffer=ReadI2CByte();
                       if(i!=n-1)
                           SEND_0();     /*发送应答*/
                       else
                           SEND_1();     /*发送非应答*/
                 }
          I2C_Stop();
       }


       void main()
       {
                 int i;
                 char mybyte;
                 char myarray[8];
                 char myarray2[8];
                 char rdarray1[16];
                 char rdarray2[16];
               
                 for(i=0;i<8;i++)
                 {
                       myarray=i;
                       myarray2=i*16;    
        rdarray1=0;     /*clr*/
        rdarray1[i+8]=0;   /*clr*/
         rdarray2=0;     /*clr*/
        rdarray2[i+8]=0;   /*clr*/
                 }
                 Write_One_Byte(0xa0,0x00,0x20,0x28);
                 Write_A_Page( 0xa0, myarray,0x00,0x10);
                 Write_A_Page(0xa0, myarray2,0x00,0x18);
                 mybyte="Read"_One_Byte(0xa0,0x00,0x20);
                 Read_N_Bytes(0xa0,rdarray1,6,0x00,0x10);


                // Write_A_Page(0xa2, myarray, 0x00,0x10);   /*the second 24aa512*/
                // Write_A_Page(0xa2, myarray2,0x00,0x18);
                  Read_N_Bytes(0xa2,rdarray2,10,0x00,0x17);


     while (1)
     {
              for (i=0;i<6;i++)
           {
              P2=rdarray1;
        DELAY(1000);
           }
                      
         for (i=0;i<10;i++)
           {
              P3=rdarray2;
      
        DELAY(1000);
           }


     }      


     }

文章评论0条评论)

登录后参与讨论
我要评论
0
8
关闭 站长推荐上一条 /2 下一条