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
原文地址:https://www.cnblogs.com/kuotian/p/5670035.html