1. 程式人生 > >STM32F103微控制器軟體模擬IIC並讀取TMP112數字溫度感測器

STM32F103微控制器軟體模擬IIC並讀取TMP112數字溫度感測器

本文利用STM32F103系列微控制器讀取TMP112數字溫度感測器的溫度資訊,TMP112數字感測器採用IIC匯流排協議通訊。STM32自身含有硬體IIC資源,分別是PB6-->SCL、PB7-->SDA,硬體IIC的操作在STM32開發板對應的資料上均有給出,在此不再贅述,本文使用軟體模擬IIC來完成與TMP112感測器之間的通訊。


圖1:TMP112的管腳定義圖

TMP112溫度感測器的電路連線如下,TMP112的IIC裝置地址由管腳ADD0決定,

裝置地址的值如下:

SCL和SDA管腳需要上拉電阻。ADD0管腳連線地,地址為7位,最後一位為讀寫操作位,0為寫,1為讀。即0x90和0x91。

進入正題模擬IIC的操作,STM32管腳定義。

 #define SCL GPIO_Pin_6
#define SDA GPIO_Pin_7

#define SCL_H GPIO_SetBits(GPIOB,GPIO_Pin_6 )
#define SCL_L GPIO_ResetBits(GPIOB,GPIO_Pin_6 )

#define SDA_H GPIO_SetBits(GPIOB,GPIO_Pin_7 )
#define SDA_L GPIO_ResetBits(GPIOB,GPIO_Pin_7)

#define SDAread GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_7)

IIC協議開始和停止條件

SCL時鐘電平為高:

SDA資料線由高 -> 低 為匯流排開始條件;SDA資料線由低 -> 高 為匯流排結束條件;

注意:開始之後將需要將SCL變為低電平;


SCL時鐘電平為低,可以改換SDA資料線的電平,在SCL升沿的過程將資料傳送出去。資料從高至低傳送,SCL_L--->SDA資料--->SCL_H。

時序:


應答訊號。STM32作為主機,TMP112為從機。主機讀,主機產生應答訊號。時序圖:



STM32向TMP112感測器寫資料的時序圖如下:

程式如下:

void I2C_WriteByte(void)
{
u16 i;
u8 j;
I2C_Start();
I2C_delay();
I2C_SendByte(0x90); //裝置地址--寫操作
I2C_Ack();
I2C_SendByte(0x01); //暫存器
I2C_Ack();
I2C_SendByte(0x00);//資料
I2C_Ack();
I2C_Stop();
for(j=30;j>0;j--)
I2C_delay();
}

STM接收TMP112傳送過來的資料時,I2C的讀一位元組函式,其實和“寫一位元組”類似,只是資料傳輸方向相反,應答的方向也是相反。
讀完一位元組(8位)之後,由主機產生應答(或非應答)位:若產生應答,表示可以繼續讀下一位元組操作(從裝置地址指向下一位元組);
若產生非應答,表示不可以繼續讀下一位元組操作;

時序:


程式:

u8 I2C_ReceiveByte(void)

    u8 i=8,j;
    u8 ReceiveByte=0;
    SDA_H;
    while(i--)
    {
      ReceiveByte<<=1;      
      SCL_H;
      I2C_delay(); 
      if(SDAread)
      {
       ReceiveByte|=0x01;
      }
for(j=30;j>0;j--)
//I2C_delay();
SCL_L;
    }
    return ReceiveByte;
}

STM32向TMP112讀取資料,時序圖如下:


程式:

u16 ReadTemp(void)
{
u8 TempH ,TempL;
I2C_Start();
I2C_SendByte(0x90);    //裝置地址--寫操作
I2C_Ack();
I2C_SendByte(0x00); //資料
I2C_Ack();

I2C_Start();
I2C_SendByte(0x91);  //裝置地址--讀操作
I2C_Ack();
TempH=I2C_ReceiveByte();
I2C_NoAck(); //無應答,接收低8位資料
TempL=I2C_ReceiveByte();
I2C_Stop();

return TempH*10+(int)(TempL*0.0625*0.0625*10);
}