久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 7856|回復(fù): 3
打印 上一主題 下一主題
收起左側(cè)

IIC通信協(xié)議分析--STM32F4驅(qū)動(dòng)溫濕度傳感器SHT20為例

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:237239 發(fā)表于 2018-10-27 10:49 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
IIC總線
1       IIC總線概述(文檔有圖)
I2C總線兩線制包括:串行數(shù)據(jù)SDA(Serial Data)、串行時(shí)鐘SCL(Serial Clock)。總線必須由主機(jī)(通常為微控制器)控制,主機(jī)產(chǎn)生串行時(shí)鐘(SCL)控制總線的傳輸方向,并產(chǎn)生起始和停止條件。
IIC總線特征:同步串行半雙工(同一時(shí)刻只能是一種身份)
2       IIC總線拓?fù)鋱D
                              
SDA:雙向串行數(shù)據(jù)線,數(shù)據(jù)是一位一位傳輸,既可以從主機(jī)發(fā)送到從機(jī),也可以從從機(jī)發(fā)送到主機(jī)
SCL:時(shí)鐘線(單向),驅(qū)動(dòng)數(shù)據(jù)線SDA的信號(hào)由時(shí)鐘線SCL提供,只能由主機(jī)發(fā)送,從機(jī)接收
主機(jī):主機(jī)產(chǎn)生串行時(shí)鐘(SCL)控制總線的傳輸方向,并產(chǎn)生起始條件(占用總線)和停止條件(釋放總線)
從機(jī):從機(jī)也能發(fā)送數(shù)據(jù)給主機(jī),但是從機(jī)永遠(yuǎn)不會(huì)主動(dòng)給主機(jī)發(fā)送數(shù)據(jù)。
主機(jī)是主宰
主機(jī)是如何找到從機(jī)來進(jìn)行通信的呢?
2.1   主從設(shè)備通信
主機(jī)如何能找到對(duì)應(yīng)的從機(jī)與其進(jìn)行通信?
每個(gè)從機(jī)都有一個(gè)唯一的器件地址,主機(jī)就是通過這個(gè)器件地址去找到對(duì)應(yīng)的從機(jī)與其通信。
器件地址誰分配?如何分配?(具體查看模塊手冊(cè))
在IIC總線上,從機(jī)的器件地址可以為7位或者10位,一般情況下都是7位器件地址。
在器件地址中包含了固定地址(在高位,不可變)和可編程地址(在低位,可變)
器件地址的位數(shù)是由廠家決定
固定地址的位數(shù)和內(nèi)容也是由廠家決定
可編程地址的位數(shù)由廠家決定
可編程地址的內(nèi)容由使用者決定
3       IIC數(shù)據(jù)幀
UART數(shù)據(jù)幀格式:起始位+數(shù)據(jù)位(5~8)+校驗(yàn)位+停止位。
IC數(shù)據(jù)幀格式:起始條件+數(shù)據(jù)位(8位)+應(yīng)答位+停止條件
起始條件:一次通信的開始(主機(jī)占用總線)
數(shù)據(jù)位:從發(fā)送器到接收器,連續(xù)的8位數(shù)據(jù)
應(yīng)答位:當(dāng)接收器成功接收到發(fā)送器的8位數(shù)據(jù)后,必須應(yīng)答。0代表應(yīng)答,1代表非應(yīng)答。
停止條件:一次通信的結(jié)束(主機(jī)釋放總線,雙線電平拉高)
4       標(biāo)準(zhǔn)IIC協(xié)議
空閑狀態(tài)
開始信號(hào)
停止信號(hào)
應(yīng)答信號(hào)
數(shù)據(jù)的有效性
數(shù)據(jù)傳輸
4.1   空閑狀態(tài)(都拉高,數(shù)據(jù)比時(shí)鐘快)
空閑狀態(tài):此時(shí)各個(gè)器件的輸出級(jí)場(chǎng)效應(yīng)管均處在截止?fàn)顟B(tài),即釋放總線,由兩條信號(hào)線各自的上拉電阻把電平拉高。




4.2   起始條件(CD變低)和停止信號(hào)(CD變高、都高)
  
起始信號(hào):當(dāng)SCL為高期間,SDA由高到低的跳變;啟動(dòng)信號(hào)是一種電平跳變時(shí)序信號(hào),而不是一個(gè)電平信號(hào)。
停止信號(hào):當(dāng)SCL為高期間,SDA由低到高的跳變;停止信號(hào)也是一種電平跳變時(shí)序信號(hào),而不是一個(gè)電平信號(hào)。
起始條件偽代碼
  
SCL=1
  
SDA=1    //起始前都是高電平
  
//延時(shí),起始條件建立時(shí)間
  
SDA=0//SDA變低,產(chǎn)生起始條件
  
//延時(shí),起始條件的保持時(shí)間
  
SCL=0//一個(gè)周期的結(jié)束
  
停止條件偽代碼
  
SCL=1
  
SDA=0//低
  
//延時(shí),停止條件建立時(shí)間
  
SDA=1//SDA變高 產(chǎn)生停止條件
  
//延時(shí),本次停止條件到下一個(gè)起始條件的時(shí)間間隔
  
4.3   位傳輸(CD準(zhǔn)備數(shù)據(jù),C拉高讀取D)
SCL串行時(shí)鐘的配合下,在SDA上逐位地串行傳送每一位數(shù)據(jù)。數(shù)據(jù)的準(zhǔn)備是在SCL的低電平,數(shù)據(jù)位的傳輸是上邊沿觸發(fā)。
拉低準(zhǔn)備數(shù)據(jù),拉高采集數(shù)據(jù)
主機(jī)發(fā)送一位數(shù)據(jù)給從機(jī):(主機(jī)輸出)
  
SCL=0//主機(jī)拉低時(shí)鐘線
  
SDA=0/1//主機(jī)在總線上準(zhǔn)備數(shù)據(jù)
  
//延時(shí),讓數(shù)據(jù)穩(wěn)定在數(shù)據(jù)線上
  
SCL=1//主機(jī)拉高時(shí)鐘線
  
從機(jī)在時(shí)鐘上升沿從總線上采集數(shù)據(jù)
  
//延時(shí),給時(shí)間從機(jī)采集數(shù)據(jù)
  
  
主機(jī)讀取從機(jī)發(fā)送的一位數(shù)據(jù):(主機(jī)輸入)
  
SCL=0//主機(jī)拉低時(shí)鐘線
  
從機(jī)在總線上準(zhǔn)備數(shù)據(jù)(從機(jī)自動(dòng)進(jìn)行,主機(jī)不動(dòng)作)
  
//延時(shí),讓數(shù)據(jù)穩(wěn)定在數(shù)據(jù)線上
  
SCL=1//主機(jī)拉高時(shí)鐘線
  
主機(jī)讀取SDA//主機(jī)在時(shí)鐘上升沿從總線上采集數(shù)據(jù)
  
//延時(shí),給時(shí)間主機(jī)機(jī)采集數(shù)據(jù)
  
  
4.4   應(yīng)答位(第九位發(fā)送高(不應(yīng)答)低(應(yīng)答))
發(fā)送器每發(fā)送一個(gè)字節(jié),就在時(shí)鐘脈沖9期間釋放數(shù)據(jù)線,由接收器反饋一個(gè)應(yīng)答信號(hào)。
應(yīng)答信號(hào)為低電平時(shí),規(guī)定為有效應(yīng)答位(ACK簡(jiǎn)稱應(yīng)答位),表示接收器已經(jīng)成功地接收了該字節(jié);
應(yīng)答信號(hào)為高電平時(shí),規(guī)定為非應(yīng)答位(NACK),一般表示接收器接收該字節(jié)沒有成功
主機(jī)讀取從機(jī)的應(yīng)答:(主機(jī)讀取一位數(shù)據(jù))
主機(jī)每發(fā)送1個(gè)字節(jié)給從機(jī)后,都必須通過這個(gè)應(yīng)答位查看從機(jī)是否能正常收到,如果一旦讀到的是非應(yīng)答信號(hào)(‘1’),表明沒有正常接收到當(dāng)前字節(jié)數(shù)據(jù),通信就要終止(主機(jī)發(fā)送停止信號(hào))
  
SCL=0//主機(jī)拉低時(shí)鐘線            (還是拉低給數(shù)據(jù),拉高采集數(shù)據(jù))
  
從機(jī)根據(jù)自己接受的情況,給不給主機(jī)應(yīng)答信號(hào)
  
//延時(shí),讓數(shù)據(jù)穩(wěn)定在數(shù)據(jù)線上
  
SCL=1//主機(jī)拉高時(shí)鐘線
  
主機(jī)讀取SDA//主機(jī)在時(shí)鐘上升沿從總線上采集應(yīng)答信號(hào)
  
//延時(shí),給時(shí)間主機(jī)機(jī)采集數(shù)據(jù)
  
如果采集到的0,表示有應(yīng)答,如果采集到的是1,表示非應(yīng)答
  
  
主機(jī)發(fā)送一個(gè)應(yīng)答給從機(jī):(主機(jī)發(fā)送一位數(shù)據(jù))
主機(jī)每讀取完從機(jī)發(fā)送過來的一個(gè)字節(jié)數(shù)據(jù)后,都必須給從機(jī)一個(gè)應(yīng)答信號(hào)。如果主機(jī)讀取完當(dāng)前字節(jié)后還想從機(jī)繼續(xù)給它發(fā)下一個(gè)字節(jié)數(shù)據(jù),就要給從機(jī)應(yīng)答(‘0’),如果主機(jī)讀取完當(dāng)前字節(jié)后不想從機(jī)再給它發(fā)數(shù)據(jù),那么主機(jī)發(fā)送非應(yīng)答信號(hào)(‘1’)給從機(jī)。
  
SCL=0//主機(jī)拉低時(shí)鐘線
  
SDA=0/1//主機(jī)根據(jù)自己的情況,決定給不給應(yīng)答從機(jī)
  
//延時(shí),讓數(shù)據(jù)穩(wěn)定在數(shù)據(jù)線上
  
SCL=1//主機(jī)拉高時(shí)鐘線
  
從機(jī)在時(shí)鐘上升沿從總線上采集應(yīng)答位
  
//延時(shí),給時(shí)間從機(jī)采集數(shù)據(jù)
  
5       IIC的尋址方式  
器件地址(8位)組成:7位從設(shè)備地址+1位方向位
從設(shè)備地址包含了固定地址和可編程地址
方向位決定有效數(shù)據(jù)位的傳輸方向,主機(jī)---》從機(jī)(主機(jī)寫) 還是 從機(jī)----》主機(jī)(主機(jī)讀)
5.1   IIC一次完整通信
1.      主機(jī)發(fā)送起始條件(主機(jī)占用總線,喚醒總線所有的從機(jī))
2.      主機(jī)發(fā)送器件地址(總線上所有的從機(jī)就會(huì)拿這個(gè)器件跟自身進(jìn)行比較,匹配成功的那個(gè)從機(jī)就會(huì)回復(fù)                 一個(gè)應(yīng)答信號(hào)給主機(jī),并根據(jù)方向位來決定數(shù)據(jù)傳輸方向)
3.      進(jìn)行有效數(shù)據(jù)交流(每傳輸完一個(gè)直接數(shù)據(jù)都要給應(yīng)答)
4.      主機(jī)發(fā)送停止信號(hào)(釋放總線,結(jié)束本次通信)
5.2   IIC三種通信方式
只讀主機(jī)只讀取數(shù)據(jù)
只寫:主機(jī)僅發(fā)送數(shù)據(jù)
有讀有寫
6       GPIO口模擬IIC通信協(xié)議
GPIO初始化
作為SCL的GPIO口:時(shí)鐘線SCL只能由主機(jī)(MCU)發(fā)出,SCL既有低電平也有高電平,所以這個(gè)GPIO口可以配置成推挽輸出,另外總線結(jié)構(gòu)本來就有上拉電阻,所以也可以配置成開漏輸出。
作為SDA的GPIO口:數(shù)據(jù)線SDA是雙向的,有時(shí)候需要從MCU發(fā)送,有時(shí)候又要輸入到MCU里。剛好,在M4里面,當(dāng)GPIO口配置成輸出模式時(shí),輸入電路并沒有被關(guān)閉。但是,當(dāng)在采集輸入信號(hào)的時(shí)候,IO口的輸出電路就很有可能會(huì)影響到輸入信號(hào)的采集,所以必須要配置成開漏輸出,在讀取輸入信號(hào)前輸出‘1’,目的是讓輸出電路從IO口中斷開。
準(zhǔn)備數(shù)據(jù)要延時(shí),讀取數(shù)據(jù)也要延時(shí)
起始條件
  
void IIC_Start(void)
  
{
  
         IIC_SCL=1;
  
         IIC_SDA_OUT=1;
  
         Systick_Delay_us(1);//延時(shí),起始條件建立時(shí)間
  
         IIC_SDA_OUT=0;//產(chǎn)生起始條件
  
         Systick_Delay_us(2);//延時(shí),起始條件的保持時(shí)間
  
         
  
         IIC_SCL=0;//一個(gè)周期的結(jié)束
  
}
  
停止條件
  
void IIC_Stop(void)
  
{
  
         IIC_SCL=1;
  
         IIC_SDA_OUT=0;
  
         Systick_Delay_us(1);//延時(shí),停止條件建立時(shí)間
  
         IIC_SDA_OUT=1;//產(chǎn)生停止條件
  
  
         Systick_Delay_us(1);//延時(shí),本次停止條件到下一個(gè)起始條件的時(shí)間間隔
  
}
  
主機(jī)發(fā)送應(yīng)答
  
void IIC_Send_ACK(u8 ack)
  
{
  
         IIC_SCL=0;//主機(jī)拉低時(shí)鐘線
  
         if(ack)//主機(jī)根據(jù)自己的情況,決定給不給應(yīng)答從機(jī)
  
         {
  
                  IIC_SDA_OUT=1;
  
         }
  
         else
  
         {
  
                  IIC_SDA_OUT=0;
  
         }
  
         Systick_Delay_us(2);//延時(shí),讓數(shù)據(jù)穩(wěn)定在數(shù)據(jù)線上
  
         IIC_SCL=1;//主機(jī)拉高時(shí)鐘線,從機(jī)在時(shí)鐘上升沿從總線上采集應(yīng)答位
  
         Systick_Delay_us(1);//延時(shí),給時(shí)間從機(jī)采集數(shù)據(jù)
  
         
  
}
  
主機(jī)讀取應(yīng)答
  
u8 IIC_Revice_Ack(void)
  
{
  
         u8 ack=0;
  
         
  
         IIC_SCL=0;//主機(jī)拉低時(shí)鐘線
  
         IIC_SDA_OUT=1;//切換成讀模式---讓輸出電路從IO口斷開*************************
  
         //從機(jī)根據(jù)自己接受的情況,給不給主機(jī)應(yīng)答信號(hào)
  
         Systick_Delay_us(2);//延時(shí),讓數(shù)據(jù)穩(wěn)定在數(shù)據(jù)線上
  
         IIC_SCL=1;//主機(jī)拉高時(shí)鐘線
  
         if(IIC_SDA_IN)//主機(jī)在時(shí)鐘上升沿從總線上采集應(yīng)答信號(hào)
  
         {
  
                  ack=1;
  
         }
  
         Systick_Delay_us(1);//延時(shí),給時(shí)間主機(jī)機(jī)采集數(shù)據(jù)
  
         
  
         IIC_SCL=0;//完整周期   
  
         return ack;
  
  
}
  
主機(jī)發(fā)送一個(gè)字節(jié)數(shù)據(jù)給從機(jī)
  
u8 IIC_Send_Byte(u8 data)  
  
{
  
         u8 i;
  
         
  
         for(i=0;i<8;i++)
  
         {
  
                  IIC_SCL=0;//主機(jī)拉低時(shí)鐘線
  
                  //主機(jī)在總線上準(zhǔn)備數(shù)據(jù)
  
                  if(data&0x80)  IIC_SDA_OUT=1;
  
                  else  IIC_SDA_OUT=0;
  
                  Systick_Delay_us(2);//延時(shí),讓數(shù)據(jù)穩(wěn)定在數(shù)據(jù)線上
  
                  IIC_SCL=1;//主機(jī)拉高時(shí)鐘線
  
                  //從機(jī)在時(shí)鐘上升沿從總線上采集數(shù)據(jù)
  
                  Systick_Delay_us(1);//延時(shí),給時(shí)間從機(jī)采集數(shù)據(jù)
  
                  
  
                  data<<=1;//讓次高位成為最高位
  
         }
  
         
  
         return IIC_Revice_Ack(  );
  
}
  
主機(jī)讀取從機(jī)的一個(gè)字節(jié)數(shù)據(jù)
  
u8 IIC_Revice_Byte(u8 ack)
  
{
  
         u8 i;
  
         u8 data=0;
  
         
  
         for(i=0;i<8;i++)
  
         {
  
                  IIC_SCL=0;//主機(jī)拉低時(shí)鐘線
  
                  IIC_SDA_OUT=1;//切換成讀模式---讓輸出電路從IO口中斷開***************************
  
                  //從機(jī)在總線上準(zhǔn)備數(shù)據(jù)
  
                  Systick_Delay_us(2);//延時(shí),讓數(shù)據(jù)穩(wěn)定在數(shù)據(jù)線上
  
                  IIC_SCL=1;//主機(jī)拉高時(shí)鐘線
  
                  data<<=1;//空出最低位來接受數(shù)據(jù)
  
                  //主機(jī)在時(shí)鐘上升沿從總線上采集數(shù)據(jù)   
  
                  if(IIC_SDA_IN)
  
                  {
  
                          data  |=1;
  
                  }                        
  
                  Systick_Delay_us(1);//延時(shí),給時(shí)間主機(jī)機(jī)采集數(shù)據(jù)
  
                  
  
         }
  
         
  
         IIC_Send_ACK(ack);
  
         
  
         return data;
  
}
  
7       IIC驅(qū)動(dòng)溫濕度傳感器
7.1   SHT20命令
7.2   SHT20測(cè)量時(shí)序
7.3   示例代碼
  
float Read_SHT20_Data(u8 cmd)
  
{
  
         u8 ack;
  
         u16 data=0;
  
         float DATA;
  
         IIC_Start( );//起始信號(hào)
  
         ack =  IIC_Send_Byte(SHT20_ADDR&0XFE);//發(fā)送器件地址+寫方向
  
         
  
         if(ack)//沒有應(yīng)答
  
         {
  
                  IIC_Stop(  );
  
                  return -1;
  
         }      
  
         ack =  IIC_Send_Byte(cmd);//發(fā)送測(cè)量命令
  
         if(ack)//沒有應(yīng)答,等待從機(jī)應(yīng)答
  
         {
  
                  IIC_Stop(  );
  
                  return -1;
  
         }      
  
         do
  
         {
  
                  Delay_ms(10);//給時(shí)間測(cè)量
  
                  IIC_Start(  ); //開始信號(hào),測(cè)量中
  
                  ack =  IIC_Send_Byte(SHT20_ADDR | 0x01);//發(fā)送器件地址+讀方向
  
         }while(ack);//沒有應(yīng)答則繼續(xù)詢問,知道有應(yīng)答,表明測(cè)量結(jié)束
  
         
  
         data |=  IIC_Revice_Byte(0) <<8;//高位結(jié)果
  
         data |=  IIC_Revice_Byte(1) ;   //低位結(jié)果
  
         
  
         IIC_Stop( );
  
         
  
         //------數(shù)字信號(hào)轉(zhuǎn)換成模擬信號(hào)
  
         data &=0xFFFC;//清除兩位狀態(tài)位
  
         
  
         if(cmd==T_MEASURE)
  
         {
  
                  DATA=-46.85+175.72*data/65536.0;
  
         }
  
         else  if(cmd==RH_MEASURE)
  
         {
  
                  DATA=-6.0+125.0*data/65536.0;
  
         }
  
         
  
         return DATA;
  
}
  

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏5 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:237239 發(fā)表于 2018-10-27 10:51 | 只看該作者
PDF文檔密碼:20171027

拓?fù)鋱D.png (55.77 KB, 下載次數(shù): 79)

拓?fù)鋱D.png

IIC總線.pdf

966.81 KB, 下載次數(shù): 45, 下載積分: 黑幣 -5

密碼:20181027

回復(fù)

使用道具 舉報(bào)

板凳
ID:441532 發(fā)表于 2020-2-28 18:18 | 只看該作者
樓主,這個(gè)有stm32F4的完成代碼嗎?我用F103的代碼移植到407上,不好使了,不知道啥問題。
回復(fù)

使用道具 舉報(bào)

地板
ID:286233 發(fā)表于 2020-6-29 22:59 | 只看該作者
非常感謝,最近在做一個(gè)相關(guān)的項(xiàng)目,遇到問題,能不能冒昧請(qǐng)教下??
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 亚洲三区在线观看 | 黄色免费在线观看网址 | 一区二区在线观看av | 欧美五月婷婷 | 亚洲国产精品99久久久久久久久 | 午夜理伦三级理论三级在线观看 | 一级在线观看 | 亚洲一区二区三 | 久久久精品一区二区三区四季av | 福利视频亚洲 | 中文字幕视频在线观看 | 欧美一区二区久久 | 伊人久久综合影院 | 国产一区二区 | 精品欧美一区二区精品久久 | 国产精品视频一区二区三区 | aaa综合国产 | 美女视频三区 | 久久99精品久久久久久国产越南 | 欧美激情在线播放 | 亚洲精品电影在线观看 | 亚洲手机视频在线 | 欧美高清视频一区 | 欧美视频二区 | 一本色道久久综合亚洲精品高清 | 日韩免费高清视频 | 毛片a级毛片免费播放100 | 免费同性女女aaa免费网站 | 色欧美片视频在线观看 | 中文字幕二区三区 | 国产区在线免费观看 | 国产激情在线播放 | 国精产品一区二区三区 | 欧美一级免费片 | 久久久激情 | 欧美乱操| 欧美国产精品一区二区 | 午夜国产精品视频 | 免费中文字幕日韩欧美 | www.天天操.com | 精品久久99|