STM32 IIC协议

IIC有两条线 时钟线SCL/数据线SDA

※ 速率: 普通模式:100k bit/s

快速模式:400k bit/s

高速模式:3.4M bit/s

※ 一个主机 n个从机

※ 发送到SDA数据线上每个字节为8位 高位在前

8位数据后跟着一个答应位ACK

-----------------------------------------------------------------------------------------发送和读取响应信号------------------------------------------------------------------------------------------

 

 1 /*
 2 函数功能:主机发送应答信号
 3 参数说明:待发送的应答信号 0有应答 1非应答
 4 */
 5 void IICSendAck(u8 ack)
 6 {
 7     IIC_SCL=0;
 8     if(ack)//主机准备数据
 9         IIC_SDA_OUT=1;
10     else
11         IIC_SDA_OUT=0;
12     Delayus(2);//延时(数据稳定在数据线上)
13     IIC_SCL=1;//(从机在时钟线上升沿从SDA上采集数据)
14     Delayus(1);//延时(给时间从机读取数据)
15 }
 1 /*
 2 函数功能:主机读取从机的应答信号
 3 返回值:读取到的应答信号  0有应答  1非应答
 4 */
 5 u8 IICReadAck(void)
 6 {
 7     u8 ack=0;
 8     
 9     IIC_SCL=0;//(从机准备数据)
10     IIC_SDA_OUT=1;//读模式,为了是IO口的输出电路给引脚断开!!!!!!!!!
11     Delayus(2);//延时(给时间从机准备数据并且数据稳定在数据线上)
12     IIC_SCL=1;
13     Delayus(1);//延时 (给时间主机读取数据)
14     if(IIC_SDA_IN)//主机读取SDA线上的数据
15         ack=1;
16     
17     IIC_SCL=0;//为了方便后续操作,防止意外出现停止条件
18     
19     return ack;
20 }

-----------------------------------------------------------------------------------------起始位和停止位发送------------------------------------------------------------------------------------------

 

 

 1 /*
 2 起始条件
 3 */
 4 void IICStart(void)
 5 {    
 6     IIC_SCL=1;
 7     IIC_SDA_OUT=1;
 8     Delayus(2);//延时--起始条件建立时间
 9     IIC_SDA_OUT=0;
10     Delayus(1);//延时--起始条件保持时间
11     IIC_SCL=0; //---一个完整的周期
12 }
13 
14 
15 /*
16 停止条件
17 */
18 void IICStop(void)
19 {
20     IIC_SCL=0;
21     IIC_SDA_OUT=0;
22     IIC_SCL=1;
23     Delayus(1);//延时--停止条件的建立时间
24     IIC_SDA_OUT=1;
25     Delayus(2);//延时--本次停止到下一开始的时间
26 }

----------------------------------------------------------------------写一个字节/写入某地址某寄存器一个字节-----------------------------------------------------------------------------

 

 1 /*
 2 函数功能:主机给从机发送一个字节数据并且读取从机应答
 3 参数说明:待发送的一个字节数据
 4 返回值:应答信号
 5 */
 6 u8 IICSendByte(u8 data) 
 7 {
 8     u8 i;
 9     
10     for(i=0;i<8;i++)
11     {
12         IIC_SCL=0;
13         if((data<<i)&0x80)//主机准备数据
14             IIC_SDA_OUT=1;
15         else
16             IIC_SDA_OUT=0;
17         Delayus(2);//延时(数据稳定在数据线上)
18         IIC_SCL=1;//(从机在时钟线上升沿从SDA上采集数据)
19         Delayus(1);//延时(给时间从机读取数据)
20     }
21     
22     IIC_SCL=0;//为了方便后续操作,防止意外出现停止条件
23     
24     return IICReadAck( );
25 }

 

 1 /*
 2 函数功能:写寄存器
 3 参数说明:regaddr寄存器地址    data写入的值 
 4 */
 5 u8 MPR121WriteDate(u8 regaddr,u8 data)
 6 {
 7     
 8     IICStart( );
 9     
10     if( IICSendByte(MPR121ADDR_W) )
11     {
12         IICStop();
13         printf("1111111111111\r\n");
14         return 0xFF;
15     }
16     
17     if( IICSendByte(regaddr) )
18     {
19         IICStop();
20         printf("222222222222\r\n");
21         return 0xFF;
22     }
23     
24     if( IICSendByte(data) )
25     {
26         IICStop();
27         printf("3333333333333\r\n");
28         return 0xFF;
29     }
30     
31     IICStop();
32     
33     return 0;
34 }

----------------------------------------------------------------------读取个字节/读取某地址某寄存器一个字节-----------------------------------------------------------------------------

 

 

 1 /*
 2 函数功能:主机读取从机一个字节数据并且发送应答信号
 3 参数说明:待发送的应答信号
 4 返回值:读取到的一个字节数据
 5 */
 6 u8 IICReadByte(u8 ack) 
 7 {
 8     u8 i;
 9     u8 data=0;
10     
11     for(i=0;i<8;i++)
12     {
13         IIC_SCL=0;//(从机准备数据)
14         IIC_SDA_OUT=1;//读模式,为了是IO口的输出电路给引脚断开!!!!!!!!!
15         Delayus(2);//延时(给时间从机准备数据并且数据稳定在数据线上)
16         IIC_SCL=1;
17         Delayus(1);//延时 (给时间主机读取数据)
18         data<<=1;//空出最低位
19         if(IIC_SDA_IN)//主机读取SDA线上的数据
20             data |=1;
21     }
22     
23     IIC_SCL=0;//为了方便后续操作,防止意外出现停止条件
24     
25     IICSendAck(ack);
26     
27     return data;
28 }
 1 /*
 2 函数功能:读寄存器
 3 参数说明:regaddr寄存器地址  
 4 返回值:读到的值
 5 */
 6 u8 MPR121ReadDate(u8 regaddr)
 7 {
 8     IICStart( );
 9     
10     if( IICSendByte(MPR121ADDR_W) )
11     {
12         IICStop();
13         return 0;
14     }
15     
16     if( IICSendByte(regaddr) )
17     {
18         IICStop();
19         return 0;
20     }
21     
22     IICStart( );
23     if( IICSendByte(MPR121ADDR_R) )
24     {
25         IICStop();
26         return 0;
27     }
28     
29     return IICReadByte(1) ;
30     
31 }

猜你喜欢

转载自www.cnblogs.com/qifeng1024/p/11615095.html