• stm32寄存器版学习笔记09 IIC


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

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

     

    SCL

    SDA

    开始信号

    高电平

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

    结束信号

    高电平

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

     

    应答信号

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

    1.初始化IIC

    1 //初始化IIC
    2 void IIC_Init(void)
    3 {                         
    4      RCC->APB2ENR|=1<<4;//先使能外设IO PORTC时钟                              
    5     GPIOC->CRH&=0XFFF00FFF;//PC11/12 推挽输出
    6     GPIOC->CRH|=0X00033000;       
    7     GPIOC->ODR|=3<<11;     //PC11,12 输出高
    8 }
    IIC_Init

    2.IIC

     1 //产生IIC起始信号
     2 void IIC_Start(void)
     3 {
     4     SDA_OUT();     //sda线输出
     5     IIC_SDA=1;            
     6     IIC_SCL=1;
     7     delay_us(4);
     8      IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
     9     delay_us(4);
    10     IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
    11 }      
    12 //产生IIC停止信号
    13 void IIC_Stop(void)
    14 {
    15     SDA_OUT();//sda线输出
    16     IIC_SCL=0;
    17     IIC_SDA=0;
    18      delay_us(4); 
    19     IIC_SCL=1;//STOP:when CLK is high DATA change form low to high
    20      delay_us(4); 
    21     IIC_SDA=1;//发送I2C总线结束信号                                
    22 }
    23 //等待应答信号到来
    24 //返回值:1,接收应答失败
    25 //        0,接收应答成功
    26 u8 IIC_Wait_Ack(void)
    27 {
    28     u8 ucErrTime=0;
    29     SDA_IN();      //SDA设置为输入  
    30     IIC_SDA=1;delay_us(1);       
    31     IIC_SCL=1;delay_us(1);     
    32     while(READ_SDA)
    33     {
    34         ucErrTime++;
    35         if(ucErrTime>250)
    36         {
    37             IIC_Stop();
    38             return 1;
    39         }
    40     }
    41     IIC_SCL=0;//时钟输出0        
    42     return 0;  
    43 } 
    44 //产生ACK应答
    45 void IIC_Ack(void)
    46 {
    47     IIC_SCL=0;
    48     SDA_OUT();
    49     IIC_SDA=0;
    50     delay_us(2);
    51     IIC_SCL=1;
    52     delay_us(2);
    53     IIC_SCL=0;
    54 }
    55 //不产生ACK应答            
    56 void IIC_NAck(void)
    57 {
    58     IIC_SCL=0;
    59     SDA_OUT();
    60     IIC_SDA=1;
    61     delay_us(2);
    62     IIC_SCL=1;
    63     delay_us(2);
    64     IIC_SCL=0;
    65 }
    IIC信号
     1 //IIC发送一个字节
     2 //返回从机有无应答
     3 //1,有应答
     4 //0,无应答              
     5 void IIC_Send_Byte(u8 txd)
     6 {                        
     7     u8 t;   
     8     SDA_OUT();         
     9     IIC_SCL=0;//拉低时钟开始数据传输
    10     for(t=0;t<8;t++)
    11     {              
    12         IIC_SDA=(txd&0x80)>>7;
    13         txd<<=1;       
    14         delay_us(2);   //对TEA5767这三个延时都是必须的
    15         IIC_SCL=1;
    16         delay_us(2); 
    17         IIC_SCL=0;    
    18         delay_us(2);
    19     }     
    20 }         
    21 //读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
    22 u8 IIC_Read_Byte(unsigned char ack)
    23 {
    24     unsigned char i,receive=0;
    25     SDA_IN();//SDA设置为输入
    26     for(i=0;i<8;i++ )
    27     {
    28         IIC_SCL=0; 
    29         delay_us(2);
    30         IIC_SCL=1;
    31         receive<<=1;
    32         if(READ_SDA)receive++;   
    33         delay_us(1); 
    34     }                     
    35     if (!ack)
    36         IIC_NAck();//发送nACK
    37     else
    38         IIC_Ack(); //发送ACK   
    39     return receive;
    40 }
    Send Read
    1 //IO方向设置
    2 #define SDA_IN()  {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;}
    3 #define SDA_OUT() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=3<<12;}
    4 
    5 //IO操作函数     
    6 #define IIC_SCL    PCout(12) //SCL
    7 #define IIC_SDA    PCout(11) //SDA     
    8 #define READ_SDA   PCin(11)  //输入SDA 
    IIC.h
  • 相关阅读:
    ERROR 000732:Output Geodatabase:Dataset Database ConnectionsConnection to localhost.sdeSDE.Dataset does not exist or is not supported
    【转】通过 INotifyPropertyChanged 实现观察者模式
    Fatal NI connect error 6413的解决办法 http://www.itpub.net/thread-107518-1-1.html
    Oracle impdp的ignore及 fromuser / touser 功能
    进度条插件使用demo
    两个div并列居中显示——当display:inline-block;时,两个div无法对齐即一高一矮
    两个div并列居中显示——当display:inline;时,div的宽高不起作用即两个div重叠显示
    轮播插件unslider.min.js使用demo
    WEB网页如何让背景图片跟随可视窗口自适应大小
    火狐浏览器不支持location.reload()(以改变页面大小时重新刷新页面为例)
  • 原文地址:https://www.cnblogs.com/kuotian/p/5670035.html
Copyright © 2020-2023  润新知