⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iic.c

📁 iic通讯程序
💻 C
字号:
#include <reg52.h>
#define uchar  unsigned char
#define uint unsigned int
sbit SCL=P3^5;//I2C时钟线
sbit SDA=P3^6;//I2C数据线
sbit PROM_CS=P3^4;//片选
sbit WP=P3^7;

bit receive;//接收标志
bit re_finish;//接收一串字符完成标志
sbit LED = P0^0;//LED指示灯

uchar  i,buffer[8];//串口缓冲区
uchar  sbuffer,number;//发送字符个数
//uchar  sendFINS ;//发送完成标志
uchar  copyOK , cmd_numb ;//发送缓冲区填充完成

extern void Start_I2c();
extern void Stop_I2c();
extern uchar RcvB();
void   send(void);
void   vGet_Send(void);
extern void Ack_I2c(bit a);
extern void SendB(uchar c);
extern void  delay(unsigned int loop);

/*******************************系统初始化***********************/
void initial()
{  unsigned char j;
  
   SCON=0x50;           //串口工作方式1,允许接收
   PCON=0x80;           //波特率翻倍
   TCON=0;              
   TMOD=0x26;           //T1用于串口波特率控制
   TL1=0xfa;            //初始化T1,波特率为9600(晶振11.0592M)
   TH1=0xfa;                    
   TR1=1;               //开定时器
   EA=1;                //开总中断
   ES=1;                //开串口中断
   copyOK = 0;         //缓冲区准备好标志清零
   receive = 0;        //接收标志清零
   re_finish = 0;      //接受完成标志清零
   cmd_numb = 0;       //接受计数器清零
   PROM_CS=0;
   WP=0;

  for(j=0; j<8; j++)   //串口缓冲区清空
      buffer[i] = 0xff;  //table[18]为空显示    
 }                        

/******************************主函数**************************/

main()
{ 
  initial();
  while(1){
    if(re_finish){//接收一串字符完成
      re_finish = 0;  
      vGet_Send(); 
       }
    }
 }

/*****************************保存和串口发送**************************/
void  vGet_Send(void)
{ uchar i;       
   
   Start_I2c();
   SendB(0xa0);
   SendB(6);           //数据存放初始地址为0x06
   for(i=0;i<6;i++)
     {SendB(buffer[i]); //向24C02写6个数据
      delay(2); }
   Stop_I2c();

   delay(1000); //非常关键!!! 

   for(i=0;i<8;i++)
      buffer[i] = 0xff; //用0xff填充发送缓冲区

   for(i=0;i<6;i++){
     Start_I2c();  
     SendB(0xa0);        //从24C02读取刚才写入的数据
     SendB(6+i);         //数据存放地址为0x06+i
     Start_I2c();        
     SendB(0xa1);           
     buffer[i]=RcvB();   //读取的值送串口缓冲区
     Ack_I2c(1);     
     Stop_I2c();
     } 
   copyOK = 1;           //置准备好标志
   send();               //向串口发送
}

/*****************************串口发送***************************/

void  send(void)//向串口发送字符串
 { 
   
   if(copyOK)  //串口准备好且缓冲区准备好
    { 
     i = 0;                 
     REN = 0;               //发送过程中禁止接收数据
     copyOK = 0;            //清缓冲区准备好标志
     SBUF = buffer[i++];      //发送字符串首字符
     number = 7;            //置发送计数器
      }
   else
       return;              //没准备好则返回
  }


/***************************串口中断响应*************************/

void serial(void) interrupt 4//串口中断响应
{  
  if(RI)//为接收中断
     {      
      RI=0;                                         //清接收中断标志
      LED = ~LED;                                   //闪串口指示LED
      sbuffer = SBUF;                               //读取串口缓冲区数据

      if((sbuffer == 's') && (receive == 0))       //判断是否为数据头 ,是数据头则准备接收
       {     
           receive = 1;     //开始接收标志                         
           cmd_numb = 0;    //清接收计数器
           re_finish = 0;   //清接收完成标志
          }
      else if(sbuffer == 'e')   //判断数据尾     
        { 
          re_finish = 1;         //置接收完成标志      
          receive =0;            //清接收标志
          }
      else if(receive){     //判断当前是否处于接收状态
                   
          buffer[cmd_numb++] = sbuffer-'0';  //当前字符送缓冲区
         }      
      else                    //无效命令则返回
         return;
       }
    else{ 
     TI=0;                   //为单个字符发送完中断
     if(!number)             //字符串发送完
      { REN = 1;             //允许接收
       }
     else{                  //字符串未发送完
        SBUF =  buffer[i++];   //发送下一字符
		number--;           //发送字符数减一
       }             
     }
   }

/*****************************延时函数**************************/
void  delay(unsigned int loop) 
{  unsigned int i ;          //loop 为执行空指令的次数,改变它可一改变延时时长
  for(i=0;i<loop;i++);//循环执行空指令loop次,达到延时目的
 }


/*******************************I2C开始*****************************/
void Start_I2c()
{
    SDA=1;
    delay(1);
    SCL=1;
    delay(3);
    SDA=0;
    delay(3);
    SCL=0;
    delay(1);
}



/*********************************I2C结束*****************************/
void Stop_I2c()
{ 
    SDA=0;
    delay(1);
    SCL=1;
    delay(3);
    SDA=1;
    delay(1);

}


/*********************************I2C写一个字节************************/
void SendB(uchar c)
{
    uchar BitCnt;//,ack ;
    for(BitCnt=0;BitCnt<8;BitCnt++)
    {
      if((c<<BitCnt)&0x80)SDA=1;
      else SDA=0;
      delay(2);
      SCL=1;
      delay(5);
      SCL=0;
      delay(2);

    }
      delay(1);
      SDA=1;
      delay(5);  
      SCL=1;
      delay(1);
     // if(SDA==1)ack=0;
      //else ack=1;
      SCL=0;
      delay(1);

}

/******************************I2C读取一个字节****************************/   
uchar RcvB()
{
     uchar retc;
     uchar BitCnt;
     retc=0;
     SDA=1;
     for(BitCnt=0;BitCnt<8;BitCnt++)
     {
        delay(1);
        SCL=0;
        delay(5);
        SCL=1;
        delay(2);
        retc=retc<<1;
        if(SDA==1)retc=retc+1;
        delay(1);
     }
     SCL=0;
        delay(1);  
     return(retc);
}

/*********************************I2C应答*********************************/  
void Ack_I2c(bit a)
{
    if(a==0)SDA=0;
    else SDA=1;
        delay(1);
    SCL=1;    
        delay(2);
    SCL=0;
        delay(1);
 
}

/**********************************结束***********************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -