stm32寄存器版学习笔记 IIC

一:IIC简介

  I²C(Inter-Integrated Circuit)总线是一种两线式串行总线,用于连接微控制器及其外设,是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。

  IIC总线在传送数据过程中共有3种类型信号,分别是开始信号结束信号应答信号

 

 

SCL

SDA

开始信号

高电平

由高电平向低电平跳变,开始传送数据

结束信号

高电平

由低电平向高电平跳变,结束传送数据

 

应答信号

      接收数据的IC在接收到8bit数据后向发送数据的IC发出特定的低电平脉冲,表示已经收到数据;CPU向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU接收到应答信号后,根据实际情况作出是否继续传递信号的判断;若未收到应答信号,则判断为受控单元出现故障。

二:IIC的初始化

 

 

三:时序图

 

起始信号

SCL:高

SDA:高--低

停止信号

SCL:高

SDA:低--高

 

 

 

 

 

 

两个应答ACK信号的区别在于SDA数据线的高低电平

应答:SDA电平为低

非应答:SDA电平为高

 

四:示例程序

 //IO方向设置

 #define SDA_IN()  {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;}

 #define SDA_OUT() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=3<<12;}

 

 //IO操作函数     

 #define IIC_SCL    PCout(12) //SCL                 pc12

 #define IIC_SDA    PCout(11) //SDA                 pc11

 #define READ_SDA   PCin(11)  //输入SDA    pc11

 

 //产生IIC起始信号 

起始信号

SCL:高

SDA:高--低

 void IIC_Start(void) 

 { 

     SDA_OUT();     //sda线输出 

     IIC_SDA=1;             

     IIC_SCL=1; 

     delay_us(4);

      IIC_SDA=0;//START:when CLK is high,DATA change form high to low  

     delay_us(4);

     IIC_SCL=0;

 }    

 

 //产生IIC停止信号

停止信号

 

SCL:高

 

SDA:低--高

 

 void IIC_Stop(void)

 {

     SDA_OUT();//sda线输出

     IIC_SCL=0;

     IIC_SDA=0;

      delay_us(4);

     IIC_SCL=1;//STOP:when CLK is high DATA change form low to high

      delay_us(4);

      IIC_SDA=1;//发送I2C总线结束信号                                

 }

 

 //等待应答信号到来

 //返回值:1,接收应答失败

 //        0,接收应答成功

 u8 IIC_Wait_Ack(void)

 {

     u8 ucErrTime=0;

     SDA_IN();      //SDA设置为输入  

    IIC_SDA=1;delay_us(1);       

    IIC_SCL=1;delay_us(1);     

     while(READ_SDA)

    {

        ucErrTime++;

        if(ucErrTime>250)

         {

             IIC_Stop();

             return 1;

        }

    }

     IIC_SCL=0;//时钟输出0        

     return 0;  

 }

 

//产生ACK应答

 void IIC_Ack(void)

 {

     IIC_SCL=0;

     SDA_OUT();

     IIC_SDA=0;

     delay_us(2);

     IIC_SCL=1;

     delay_us(2);

     IIC_SCL=0;

 }

 

 //不产生ACK应答           

 void IIC_NAck(void)

 {

     IIC_SCL=0;

    SDA_OUT();

    IIC_SDA=1;

    delay_us(2);

    IIC_SCL=1;

    delay_us(2);

    IIC_SCL=0;

 }

两个应答ACK信号的区别在于SDA数据线的高低电平

 

 //IIC发送一个字节 

 //返回从机有无应答 

 //1,有应答 

 //0,无应答               

 void IIC_Send_Byte(u8 txd) 

 {                         

     u8 t;    

     SDA_OUT();          

     IIC_SCL=0;//拉低时钟开始数据传输

     for(t=0;t<8;t++)

     {              

         IIC_SDA=(txd&0x80)>>7;

         txd<<=1;       

         delay_us(2);   //TEA5767这三个延时都是必须的

         IIC_SCL=1;

         delay_us(2);

         IIC_SCL=0;    

         delay_us(2);

     }     

 }    

 

 

 

 //1个字节,ack=1时,发送ACKack=0,发送nACK   

 u8 IIC_Read_Byte(unsigned char ack)

 {

     unsigned char i,receive=0;

     SDA_IN();//SDA设置为输入

     for(i=0;i<8;i++ )

     {

         IIC_SCL=0;

         delay_us(2);

         IIC_SCL=1;

         receive<<=1;

         if(READ_SDA)receive++;   

         delay_us(1);

     }                     

     if (!ack)

         IIC_NAck();//发送nACK

     else

         IIC_Ack(); //发送ACK   

     return receive;

 }

  

 

posted @ 2021-04-13 17:27  一个爱搬运的球  阅读(543)  评论(0)    收藏  举报