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);
}