zoukankan      html  css  js  c++  java
  • I2C总线驱动程序

      1  /*************************此部分为I2C总线的驱动程序*************************************/
      2 
      3 #include<reg52.h>
      4 #include <intrins.h>
      5 
      6 //#define  NOP()   _nop_()   /* 定义空指令 */
      7 #define  _Nop()  _nop_()   /*定义空指令*/
      8 
      9  
     10 sbit     SCL=P2^1;     //I2C  时钟 
     11 sbit     SDA=P2^0;     //I2C  数据 
     12 
     13 bit ack;                 /*应答标志位*/
     14    
     15 
     16 //起动总线函数
     17 extern void Start_I2c();
     18 
     19 //结束总线函数  
     20 extern void Stop_I2c();
     21 
     22 //应答子函数
     23 extern void Ack_I2c(bit a);
     24 
     25 //字节数据发送函数
     26 extern void  SendByte(unsigned char  c);
     27 
     28 /*******************************************************************
     29                      起动总线函数               
     30 函数原型: void  Start_I2c();  
     31 功能:     启动I2C总线,即发送I2C起始条件.  
     32 ********************************************************************/
     33 void Start_I2c()
     34 {
     35   SDA=1;         /*发送起始条件的数据信号*/
     36   _Nop();
     37   SCL=1;
     38   _Nop();        /*起始条件建立时间大于4.7us,延时*/
     39   _Nop();
     40   _Nop();
     41   _Nop();
     42   _Nop();    
     43   SDA=0;         /*发送起始信号*/
     44   _Nop();        /* 起始条件锁定时间大于4μs*/
     45   _Nop();
     46   _Nop();
     47   _Nop();
     48   _Nop();       
     49   SCL=0;       /*钳住I2C总线,准备发送或接收数据 */
     50   _Nop();
     51   _Nop();
     52 }
     53 
     54 /*******************************************************************
     55                       结束总线函数               
     56 函数原型: void  Stop_I2c();  
     57 功能:     结束I2C总线,即发送I2C结束条件.  
     58 ********************************************************************/
     59 void Stop_I2c()
     60 {
     61   SDA=0;      /*发送结束条件的数据信号*/
     62   _Nop();       /*发送结束条件的时钟信号*/
     63   SCL=1;      /*结束条件建立时间大于4μs*/
     64   _Nop();
     65   _Nop();
     66   _Nop();
     67   _Nop();
     68   _Nop();
     69   SDA=1;      /*发送I2C总线结束信号*/
     70   _Nop();
     71   _Nop();
     72   _Nop();
     73   _Nop();
     74 }
     75 
     76 /*******************************************************************
     77                  字节数据发送函数               
     78 函数原型: void  SendByte(UCHAR c);
     79 功能:     将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
     80           此状态位进行操作.(不应答或非应答都使ack=0)     
     81            发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
     82 ********************************************************************/
     83 void  SendByte(unsigned char  c)
     84 {
     85  unsigned char  BitCnt;
     86  
     87  for(BitCnt=0;BitCnt<8;BitCnt++)  /*要传送的数据长度为8位*/
     88     {
     89      if((c<<BitCnt)&0x80)SDA=1;   /*判断发送位*/
     90        else  SDA=0;                
     91      _Nop();
     92      SCL=1;               /*置时钟线为高,通知被控器开始接收数据位*/
     93       _Nop(); 
     94       _Nop();             /*保证时钟高电平周期大于4μs*/
     95       _Nop();
     96       _Nop();
     97       _Nop();         
     98      SCL=0; 
     99     }
    100     
    101     _Nop();
    102     _Nop();
    103     SDA=1;                /*8位发送完后释放数据线,准备接收应答位*/
    104     _Nop();
    105     _Nop();   
    106     SCL=1;
    107     _Nop();
    108     _Nop();
    109     _Nop();
    110     if(SDA==1)ack=0;     
    111        else ack=1;        /*判断是否接收到应答信号*/
    112     SCL=0;
    113     _Nop();
    114     _Nop();
    115 }
    116 
    117 /*******************************************************************
    118                  字节数据接收函数               
    119 函数原型: UCHAR  RcvByte();
    120 功能:        用来接收从器件传来的数据,并判断总线错误(不发应答信号),
    121           发完后请用应答函数应答从机。  
    122 ********************************************************************/    
    123 unsigned char   RcvByte()
    124 {
    125   unsigned char  retc;
    126   unsigned char  BitCnt;
    127   
    128   retc=0; 
    129   SDA=1;                       /*置数据线为输入方式*/
    130   for(BitCnt=0;BitCnt<8;BitCnt++)
    131       {
    132         _Nop();           
    133         SCL=0;                  /*置时钟线为低,准备接收数据位*/
    134         _Nop();
    135         _Nop();                 /*时钟低电平周期大于4.7μs*/
    136         _Nop();
    137         _Nop();
    138         _Nop();
    139         SCL=1;                  /*置时钟线为高使数据线上数据有效*/
    140         _Nop();
    141         _Nop();
    142         retc=retc<<1;
    143         if(SDA==1)retc=retc+1;  /*读数据位,接收的数据位放入retc中 */
    144         _Nop();
    145         _Nop(); 
    146       }
    147   SCL=0;    
    148   _Nop();
    149   _Nop();
    150   return(retc);
    151 }
    152 
    153 /********************************************************************
    154                      应答子函数
    155 函数原型:  void Ack_I2c(bit a);
    156 功能:      主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
    157 ********************************************************************/
    158 void Ack_I2c(bit a)
    159 {
    160   
    161   if(a==0)SDA=0;              /*在此发出应答或非应答信号 */
    162   else SDA=1;
    163   _Nop();
    164   _Nop();
    165   _Nop();      
    166   SCL=1;
    167   _Nop();
    168   _Nop();                    /*时钟低电平周期大于4μs*/
    169   _Nop();
    170   _Nop();
    171   _Nop();  
    172   SCL=0;                     /*清时钟线,钳住I2C总线以便继续接收*/
    173   _Nop();
    174   _Nop();    
    175 }
  • 相关阅读:
    浅谈隔板法
    最短路spaf及dijkstra模板
    P1219 最优贸易
    P1211 街道赛跑
    图结构模板
    P1218 过路费
    使用Asp.net Identity 创建用户 、登录代码
    asp.net identity 介绍
    响应式图像
    glyphicon 图标的使用
  • 原文地址:https://www.cnblogs.com/sky1991/p/2573630.html
Copyright © 2011-2022 走看看