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

📄 i2c.c

📁 用IO口模拟的IIC通信方式。可用于较慢的通信中
💻 C
字号:
#include "p18f66j10.h"
#include "POWER_HardH.H"
//TRISE=0xb3输入,TRISE=0xa3输出  
#define  uchar unsigned char //*宏定义*/
#define  uint  unsigned int                                                 //*端口位定义*/
#define SDA RE4            //*模拟I2C数据传送位*/
#define SCL RE3            //*模拟I2C时钟控制位*/

volatile extern union
{struct
{unsigned D0:1;
 unsigned D1:1;
 unsigned D2:1;
 unsigned D3:1;
 unsigned D4:1;
 unsigned D5:1;
 unsigned D6:1;
 unsigned D7:1;
};
unsigned char t;
}BIT7bits;
#define i2c_byte   BIT7bits.t
#define ack     BIT7bits.D0 //应答标志
#define ready_w BIT7bits.D1 //写容许标志
#define s_a    BIT7bits.D2
#define s_sub    BIT7bits.D3
#define s_by1    BIT7bits.D4
#define r_a    BIT7bits.D5
#define r_sub    BIT7bits.D6
#define r_by1    BIT7bits.D7  


extern void delayn(uchar n)//延时程序
{ while(n)n--;}





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

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

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

	
uchar  RcvByte(void)
{
  uchar retc;
  uchar BitCnt;
  
  retc=0; 
  SDA=1;             //*置数据线为输入方式*/
  TRISE=0xb3;
  for(BitCnt=0;BitCnt<8;BitCnt++)
      {
        delayn(2);           
        SCL=0;       //*置时钟线为低,准备接收数据位*/
        delayn(2);         //*时钟低电平周期大于4.7μs*/
        SCL=1;       //*置时钟线为高使数据线上数据有效*/
        delayn(2);
        retc=retc<<1;
        if(SDA==1)retc=retc+1; //*读数据位,接收的数据位放入retc中 */
        delayn(2);
      }
  SCL=0;    
  delayn(2);
  TRISE=0xa3;  
  return(retc);
}


void Ack_I2c(unsigned char a)
{
  if(a==0)SDA=0;     //*在此发出应答或非应答信号 */
        else SDA=1;
  delayn(2);    
  SCL=1;
    delayn(2);              //*时钟低电平周期大于4μs*/ 
 SCL=0;                //*清时钟线,钳住I2C总线以便继续接收*/
    delayn(2); 
}


uchar ISendByte(uchar sla,uchar c)
{
   Start_I2c();              //*启动总线*/
   SendByte(sla);            //*发送器件地址*/
     if(ack==0)return(0);
   SendByte(c);               //*发送数据*/
     if(ack==0)return(0);
  Stop_I2c();                 //*结束总线*/ 
  return(1);
}


 
uchar ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
{
   uchar i;
   Start_I2c();               //*启动总线*/
   SendByte(sla);            //*发送器件地址*/
     if(ack==0)return(0);
    
   SendByte(suba);            //*发送器件子地址*/
     if(ack==0)return(0);
    
   for(i=0;i<no;i++)
    {   
     SendByte(*s);              //*发送数据*/
     if(ack==0)return(0);
   
     s++;
    } 
 Stop_I2c();                 //*结束总线*/ 
 return(1);
}

 
uchar IRcvByte(uchar sla,uchar *c)
{
   Start_I2c();                //*启动总线*/
   SendByte(sla+1);           //*发送器件地址*/
     if(ack==0)return(0);
   *c=RcvByte();               //*读取数据*/
     Ack_I2c(1);               //*发送非就答位*/
  Stop_I2c();                  //*结束总线*/ 
  return(1);
}

 
uchar IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
{
   uchar i;

   Start_I2c();               //*启动总线*/
   SendByte(sla);            //*发送器件地址*/
     if(ack==0)return(0);
   SendByte(suba);            //*发送器件子地址*/
     if(ack==0)return(0);

   Start_I2c();
   SendByte(sla+1);
      if(ack==0)return(0);
       
   for(i=0;i<no-1;i++)
    {   
     *s=RcvByte();               //*发送数据*/
      Ack_I2c(0);       //*发送就答位*/  
     s++;
    } 
   *s=RcvByte();
    Ack_I2c(1);                 //*发送非应位*/
 Stop_I2c();                    //*结束总线*/ 
  return(1);
}

⌨️ 快捷键说明

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