关闭

用I2C总线传输数据控制继电器工作

标签: cdelaytableinput工作function
1308人阅读 评论(0) 收藏 举报
分类:

用I2C总线传输数据控制继电器工作

#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define dig_num P2
#define dig_seg P0
#define ADD_t1 0x10
#define ADD_t2 0x20
#define somenop();   _nop_();_nop_();_nop_();_nop_();_nop_();

bit ACK;             /*应答标志位*/
sbit jdq=P3^7;
sbit key=P3^3;
sbit led3=P1^2;
sbit led1=P1^0;
sbit sw1=P2^7;
sbit sw2=P2^6;
sbit sw3=P2^5;
sbit sw5=P2^3;
sbit sw6=P2^2;
sbit beep=P2^0;
bit f_run,f_run_t;
sbit SDA=P3^4;
sbit SCL=P3^2;

uchar code table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
uchar data count_1s;
uchar data buff_t1,buff_t2,t1,t2;
uchar data buff_led1,buff_led2,buff_led5,buff_led6,buff;
uchar dig_num0;
uchar data SLA _at_ 0x2e;
uchar data MTD _at_ 0x2f;
uchar data MRD _at_ 0x30;

void INT_0(void);
void delay(uint t);
void key_down(void);
void Input_I2C(uchar add,uchar add_t,uchar dat);
void Start_I2c();
void Stop_I2c();
void SendByte(uchar c);
void Ack_I2c(bit a);
uchar RcvByte(void);
//***********************************************************
void main(void)
{
 sw1=0;sw2=0;sw3=0;sw5=0;sw6=0;key=1;
 TMOD=0x01;
 TH0=0xf0;TL0=0x60;
 TCON=0x10;           //TR0=1,IE0=0;          
 IE=0x82;             //EA=1,EX0=1,ET0=1;

 Start_I2c();
 SLA=0xAE;
 SendByte(SLA);
 while(!ACK)SendByte(SLA);
 SendByte(ADD_t1);
 while(!ACK)SendByte(ADD_t1);
 Start_I2c();
 SLA=0xAF;
 SendByte(SLA);
 while(!ACK)SendByte(SLA);
 t1=RcvByte();
 Ack_I2c(ACK);
 Stop_I2c();
 buff_t1=t1;

 Start_I2c();
 SLA=0xAE;
 SendByte(SLA);
 while(!ACK)SendByte(SLA);
 SendByte(ADD_t2);
 while(!ACK)SendByte(ADD_t2);
 Start_I2c();
 SLA=0xAF;
 SendByte(SLA);
 while(!ACK)SendByte(SLA);
 t2=RcvByte();
 Ack_I2c(ACK);
 Stop_I2c();
 buff_t2=t2;
 
 while(1)
   {
    if(!key)key_down();            
    if(f_run_t==0){f_run=0;buff_t1=t1;buff_t2=t2;}
    }
 }
//***************************************************************
//***************************************************************
void key_down(void)
{
  if(sw1==0)     //
1
    {if(t1>=99){t1=0;
             beep=0;
    delay(30000);
    beep=1;}
        else{t1++;
             beep=0;
          delay(30000);
          beep=1;}
 buff_t1=t1;
 Input_I2C(0xae,ADD_t1,t1);
 delay(30000);
 }      
  else if(sw2==0)     //
1
         {if(t1==0){t1=99;
                 beep=0;
           delay(30000);
           beep=1;}
            else{t1--;
                 beep=0;
              delay(30000);
              beep=1;}
      buff_t1=t1;
      Input_I2C(0xae,ADD_t1,t1);
         }
        else if(sw3==0)
               {f_run=1;f_run_t=1;beep=0;delay(30000);beep=1;led1=0;}
 
             else if(sw5==0)
            {if(t2>=10){t2=0;         //
1
                              beep=0;
                        delay(30000);
                     beep=1;}
                          else{t2++;       //
1
                               beep=0;
                            delay(30000);
                            beep=1;}
                    buff_t2=t2;
                    Input_I2C(0xae,ADD_t2,t2);
                    }
                   else if(sw6==0)         
                          {if(t2==0){t2=10;
                                  beep=0;
                            delay(30000);
                            beep=1;}
                              else{t2--;
                                   beep=0;
                                delay(30000);
                                beep=1;}
                                   buff_t2=t2;
                         Input_I2C(0xae,ADD_t2,t2);
                         }
}   
//**************************************************************
void Input_I2C(uchar add,uchar add_t,uchar dat)
{
 Start_I2c();
 SLA=add;
 SendByte(SLA);
 while(!ACK)SendByte(SLA);
 SendByte(add_t);
 while(!ACK)SendByte(add_t);
 SendByte(dat);
 while(!ACK)SendByte(dat);
 Stop_I2c();
 }
/**********************************************************************************/
/**********************************************************************************/
 void INT_0(void)interrupt 1
 {TH0=0xf0;TL0=0x60;
  if(f_run){                          //
有按键3按下,灯1亮,t1秒后,灯3
?
            if(count_1s==250){count_1s=0;    //
三秒后全部灭掉,数码管显示变化的时间

                              if(buff_t1==0){led3=0;jdq=1;
                                             if(buff_t2==0){led1=1;led3=1;jdq=0;f_run_t=0;}
                                             else buff_t2--;
                                             }
                              else buff_t1--;                                                                                       
                              }
                         else count_1s++;
            buff_led1=buff_t1/10;buff_led2=buff_t1%10;
            buff_led5=buff_t2/10;buff_led6=buff_t2%10;
            dig_num0=count_1s%4;
            switch(dig_num0)
              {case 0:dig_num=0x7f;
             dig_seg=table[buff_led1];
       break;
               case 1:dig_num=0xbf;
             dig_seg=table[buff_led2];
       break;
               case 2:dig_num=0xf7;
             dig_seg=table[buff_led5];
       break;
               case 3:dig_num=0xfb;
             dig_seg=table[buff_led6];
       break;
               default:break;   
               }     
            }
  else {led3=1;led1=1;              //
未按键,灯不亮,数码管显示初始值1
        if(count_1s==250)count_1s=0;                                       
        else count_1s++;
        buff_led1=buff_t1/10;
  buff_led2=buff_t1%10;
        buff_led5=buff_t2/10;
  buff_led6=buff_t2%10;
        dig_num0=count_1s%4;
        switch(dig_num0)
          {case 0:dig_num=0x7f;
            dig_seg=table[buff_led1];
      break;
           case 1:dig_num=0xbf;
            dig_seg=table[buff_led2];
      break;
           case 2:dig_num=0xf7;
            dig_seg=table[buff_led5];
      break;
           case 3:dig_num=0xfb;
            dig_seg=table[buff_led6];
      break;
           default:break;
           }     
        }
  }

void delay(uint t)
{
  while(--t);
 }
/*************************I2C FUNCTION*******************************/
/*******************************************************************
                    
起动总线函数

函数原型: void  Start_I2c();
功能:       启动I2C总线,即发送I2C起始条件.

********************************************************************/
void Start_I2c()
{
  SDA=1;        /*
发送起始条件的数据信号
*/
  _nop_();
  SCL=1;
  somenop();    /*
起始条件建立时间大于4.7us,延时
*/
  SDA=0;        /*
发送起始信号
*/
  somenop();    /*
起始条件锁定时间大于
4μs*/
  SCL=0;        /*
钳住I2C总线,准备发送或接收数据
*/
  _nop_();
  _nop_();
}
/*******************************************************************
                     
结束总线函数

函数原型: void  Stop_I2c();
功能:       结束I2C总线,即发送I2C结束条件.

********************************************************************/
void Stop_I2c()
{
  SDA=0;       /*
发送结束条件的数据信号
*/
  _nop_();     /*
发送结束条件的时钟信号
*/
  SCL=1;       /*
结束条件建立时间大于
4μs*/
  somenop();
  SDA=1;       /*
发送I2C总线结束信号
*/
  somenop();
}
/*******************************************************************
                
字节数据传送函数

函数原型: void  SendByte(uchar c);
功能将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对

    
此状态位进行操作.(不应答或非应答都使ack=0 )
    
发送数据正常,ack=1; ack=0表示被控器无应答或损坏。

********************************************************************/
void  SendByte(uchar c)
{
 uchar BitCnt;
 for(BitCnt=0;BitCnt<8;BitCnt++)  /*
要传送的数据长度为8*/
    {
     if((c<<BitCnt)&0x80)SDA=1;   /*
判断发送位
*/
       else  SDA=0;
     _nop_();
     SCL=1;                       /*
置时钟线为高,通知被控器开始接收数据位
*/
     somenop();                   /*
保证时钟高电平周期大于
4μs*/
     SCL=0;
    }
    _nop_();
    _nop_();
    SDA=1;                         /*8
位发送完后释放数据线,准备接收应答位
*/
    _nop_();
    _nop_();
    SCL=1;
    _nop_();
    _nop_();
    _nop_();
    if(SDA==1)ACK=0;
         else ACK=1;                 /*
判断是否接收到应答信号
*/
    SCL=0;
    _nop_();
    _nop_();
}

 

/********************************************************************
                    
应答子函数

原型:  void Ack_I2c(bit a);

功能:主控器进行应答信号,(可以是应答或非应答信号)
********************************************************************/
void Ack_I2c(bit a)
{
  if(a==0)SDA=0;           /*
在此发出应答或非应答信号
*/
     else SDA=1;
  _nop_();
  _nop_();
  _nop_();
  SCL=1;
  somenop();               /*
时钟低电平周期大于
4μs*/
  SCL=0;                   /*
清时钟线,钳住I2C总线以便继续接收
*/
  _nop_();
  _nop_();
}
/*******************************************************************
                
字节数据传送函数

函数原型: uchar  RcvByte();
功能用来接收从器件传来的数据,并判断总线错误(不发应答信号)

    
发完后请用应答函数。
********************************************************************/
 uchar RcvByte(void)
{
  uchar BitCnt;
  uchar retc;
  retc=0;
  SDA=1;             /*
置数据线为输入方式*/
  _nop_();
  _nop_();
  for(BitCnt=0;BitCnt<8;BitCnt++)
      {
        _nop_();
        SCL=0;       /*
置时钟线为低,准备接收数据位
*/
        somenop();         /*
时钟低电平周期大于
4.7μs*/
        SCL=1;       /*
置时钟线为高使数据线上数据有效
*/
        _nop_();
        _nop_();
        retc=retc<<1;
        if(SDA==1)retc=retc+1; /*
读数据位,接收的数据位放入retc
*/
        _nop_();
        _nop_();
      }
  SCL=0;
  _nop_();
  _nop_();
  return (retc);
}
 
 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:59501次
    • 积分:1050
    • 等级:
    • 排名:千里之外
    • 原创:40篇
    • 转载:5篇
    • 译文:0篇
    • 评论:11条
    最新评论