GPIO アナログ タイミング制御ペリフェラル 2 - DHT11

序文

前回の記事では、GPIO を使用して WS2812B の制御シーケンスをシミュレートし、RGB ライトの制御を実現することを紹介しましたが、この記事では引き続き GPIO シミュレーションを使用して、MCU によって DHT11 温湿度センサーと通信し、温湿度情報を取得します。 。

モジュールの紹介

DHT11 は、温度と湿度を収集するために一般的に使用されるモジュールの 1 つであり、湿度と温度を検出するセンサーと、温度と湿度の情報を処理する 8 ビットのシングルチップ マイコンが統合されており、この 8 ビットの内蔵 MCU により、ユーザーはsave 温度と湿度のデータ処理ステップを省略し、タイミングチャートに従って直接温度と湿度を取得します。
ここに画像の説明を挿入

ハードウェアの紹介

一般的なモジュールは 2 つあり、1 つはアダプター ボードなしで上の図に示されている 4 つのピンです。この種のモジュールを使用する場合は、回路図の描画中に DATA ピンにプルアップ抵抗を追加する必要があります。通常の通信ではデータを取得できない可能性が高いです。
ここに画像の説明を挿入
3 ピンのモジュールもあり、通常はアダプター ボードにプルアップ抵抗が装備されています。収集データへの電源の影響を軽減するために、LDO電源を使用するようにしてください。また、下図のC1は電源フィルタリングの役割も果たします。
ここに画像の説明を挿入
ここで著者はアダプターボードを備えたモジュールを選択します。

ハードウェア接続

モジュールの概要を理解した後、実際の通信に使用される GPIO を見つけるために回路図を比較する必要があります。回路図から、使用されている GPIO は PA15 です。
ここに画像の説明を挿入

通信シーケンス

前回のシミュレーションの手順に従って、次のステップでは通信タイミングを確認し、GPIO を使用して機能を実現するタイミングをシミュレーションします。
DHT11 はシングルバス (1 線式) 通信プロトコルを採用しており、1 本のデータラインを使用して双方間のデータ交換を完了しますが、1 本のデータラインであるため、半二重通信方式である必要があります。 、MCU がデータを送信するか、DHT11 がデータを送信します。また、DHT11 は MCU に能動的にデータを送信することはできず、MCU が DHT11 に開始信号を送信した後、DHT11 は応答してデータを送信します。
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
なお、DHT11とMCU間でデータ交換を行う場合、信号線が順番に使用されます。
この説明によると、DHT11 の通信シーケンスを大まかにまとめると、
1. マスター (MCU) が DHT11 (スレーブ) に開始信号を送信する;
2. DHT11 (スレーブ) が開始信号を受信した後、応答と信号を返すデータ送信用;
3. 応答信号とデータ送信信号を受信後、ホスト(MCU)は40ビットデータの受信を開始; 4.
DHT11のデータ送信が完了し、終了信号が発生し、MCUはデータ受信を停止します。
ここに画像の説明を挿入

DHT11データフレームフォーマット

DHT11 は一度に 40 ビットのデータを送信します。各データは次のように定義されます。
データの最初の 8 ビットは湿度の整数ビット、2 番目の 8 ビットのデータは 10 進数の湿度、そして 3 番目の 8 ビットは湿度です。温度桁の整数、4 番目の 8 桁は温度の小数点以下の桁、最後の 8 桁のデータはチェック デジット、チェック デジット = 最初の 4 つの 8 桁の合計、その後下位 8 桁の値を取得します。
ここに画像の説明を挿入

マニュアルの例は次のとおりです。
ここに画像の説明を挿入
ロジック アナライザでキャプチャした実際の波形は次のとおりです。
ここに画像の説明を挿入

信号のタイミング

大まかな通信プロセスを明確にすると、プログラムの大枠はわかりますが、具体的な信号の表現方法についてはマニュアルでさらに確認する必要があります。

1. スタート信号

まずスタート信号ですが、スタート信号は MCU から DHT11 に送信され、このとき MCU の GPIO を出力端子として使用し、一定時間 High レベルと Low レベルを出力します。
スタート信号に対応する波形は下図の赤枠内の内容となります。
ここに画像の説明を挿入
拡大すると、以下の図に示されています。
ここに画像の説明を挿入
この説明と波形から、スタート信号では、MCU がまずデータ ピンを少なくとも 18ms ローにプルし、次にハイにプルしてデータ ピンを解放する必要があることがわかります。バス。
ここでのプルアップとリリースバスについてどのように理解すればよいでしょうか? 前述したように、DATA ピンには常にプルアップ抵抗が存在します。MCU も DHT11 も DATA ピンを制御する出力を出力していない場合、DATA ピンの電圧はは常にハイレベルに保たれます。つまり、DATA ラインがハイにプルされてアイドルになり、状態が解放されると言われます。ここで、MCU と DHT11 が DATA を制御しない限り、DATA のデフォルト状態はハイレベルであることに注意してください。
これから、開始信号の機能は次のように大まかに書くことができます。

/*********************************
函数名:DHT11_Start
函数功能:DHT11复位(起始信号开始转换)
形参:void
返回值:void
备注:
主机拉低至少18MS,再拉高20-40us,等待应答
**********************************/
void DHT11_Start(void)
{
    
    
	//DATA脚拉低18ms以上30ms以下
	DHT11_OUT_L;
	Systick_Delay_ms(20);
	//再拉高20-40us
	DHT11_OUT_H;
	Systick_Delay_us(30);
}

2. 応答信号(応答信号)

DHT11 の応答信号は下図の赤枠で示されており、ホストがスタート信号を送信した直後に DATA ラインを High にプルして解放します。 DHT11 が開始信号を受信すると、DATA データ ラインをプルダウンします。このプルダウンは応答信号と呼ばれます。応答後、データ受信の安定性のために、DHT11 もデータ ラインを再度プルアップし、データを解放します。行を作成し、ホストにデータの送信を開始する準備をするように指示します。
ここに画像の説明を挿入
次の図に示すように、タイミング図のこの部分を拡大します。DHT11 は
DATA ピンを約 80us プルダウンし、その後 DHT11 はデータ ピンをプルアップしてマスターにデータの受信を開始するように指示します。
ここで注意すべき点は、このときデータラインは DHT11 によって制御されており、DHT11 から送信された信号を取得するには、MCU はそれまでの出力モードから入力モードに切り替える必要があります。具体的な切り替え方法は2つありますが、詳しくは後述します。この時点で MCU が DATA ステータスを読み取ることがわかれば十分です。
ここに画像の説明を挿入
ここでは、まず応答信号を取得するコードを記述します。データ ビットが読み取られたときに、データの送信準備ができたことを示す信号も一緒に実装されます。

/*********************************
函数名:DHT11_Check
函数功能:DHT11应答检测
形参:void
返回值:u8 
备注:返回1:未检测到DHT11的存在
返回0:检测到DHT11
**********************************/
u8 DHT11_Check(void)
{
    
    
	u8 retry=0;	 	 
	//等待起始信号的高电平时间结束
   while (DHT11_IN && retry<100)
	{
    
    
		retry++;
		Systick_Delay_us(1);
	};	 
	if(retry>=100)return 1;//如果DATA脚空闲时间超过100us还没有被DHT11拉低,说明应答失败
	else retry=0;
	//检测DHT11应答拉低的时间是否正常
  while (!DHT11_IN && retry<100)//DHT11会拉低40~80us
	{
    
    
		retry++;
		Systick_Delay_us(1);
	};
	if(retry>=100)return 1;	//如果低电平时间超过了100us说明应答失败    
	return 0;//否则就应答成功
}	

3. データ0、1を受信

応答信号を取得した後、送信するデータのタイミングを処理し、DATAの状態に応じてデータビットが0か1かを判断する必要があります。前回のWS2812B通信と同様に、DHT11の「1」と「0」も一定期間のハイレベルとローレベルで構成されています。
論理「0」と論理「1」の具体的な表現は下図の通りで、最初に54usのレベルがあり、その後のハイレベルの持続時間によって論理「0」と論理「1」が区別されます。 。
ロジック「0」のハイレベル時間は 23 ~ 27us 継続し、ロジック「1」のハイレベル時間は 68=74us 継続します。
ここに画像の説明を挿入
では、ロジック「0」とロジック「1」を検出する方法、簡単な解決策は、ローレベルの時間が同じであるため、読み取り時にローレベルの終わりを待ってから40μs以上遅延してから読み取ります。 DATA の状態を考えます。この時点でまだ High であれば論理「1」を意味し、Low になったら論理「0」を意味します。
コードは以下のように表示されます。

/*********************************
函数名:DHT11_Read_Bit
函数功能:从DHT11获取1位数据
形参:void
返回值:u8  1/0
备注:
数据线低50us表示开始传输数据,数据变为高电平时开始记录高电平持续时间
如果高电平时间持续26-28us表示数据位为0
如果高电平时间持续70us表示数据位为1
**********************************/
u8  DHT11_Read_Bit(void)
{
    
    
	u8 retry=0;
	//等待准备接收数据的信号结束
	while(DHT11_IN && retry<100)//等待变为低电平(应答后会拉低拉高,所以在这里要等待80)
	{
    
    
		retry++;
		Systick_Delay_us(1);
	}
	retry=0;
	//0和1的低电平时间段不作判定,直接等待
	while(!DHT11_IN &&retry<100)//等待变高电平
	{
    
    
		retry++;
		Systick_Delay_us(1);
	}
	Systick_Delay_us(40);//等待40us
	if(DHT11_IN)return 1;//“1”的高电平时间持续68us以上,延时40us后还是高电平
	else return 0;		//“0”的高电平时间持续26-28us,经过上面的延时已经变回低电平了。
}

4. データを取得する

次に、上記のビット受信関数を呼び出して 40 ビットのデータ受信を実現します。上位ビットが最初で、次に対応するバイト受信関数をカプセル化し、5 バイトのデータを受信した後、前のデータ フレーム形式に従ってチェック デジットを判断します。希望の値を読み取ります。

/*********************************
函数名:DHT11_Read_Byte
函数功能:从DHT11获取1字节数据
形参:void
返回值:u8 
备注:

**********************************/
u8  DHT11_Read_Byte(void)
{
    
    
	u8 i,dat;
  dat=0;
	for (i=0;i<8;i++) 
	{
    
    
   		dat<<=1; 
	    dat|=DHT11_Read_Bit();
    }						    
    return dat;
}

/*********************************
函数名:DHT11_Read_Data
函数功能:从DHT11获取数据
形参:void
返回值:u8 0,正常;1,读取失败
备注:
8bit湿度整数数据+8bit湿度小数数据
+8bi温度整数数据+8bit温度小数数据
+8bit校验和
**********************************/
u8  DHT11_Read_Data(u8 *temp,u8 *humi)
{
    
    
	u8 buf[5];
	u8 i;
	DHT11_Start();
	if(DHT11_Check()==0)
	{
    
    
		for(i=0;i<5;i++)//读取40位数据
		{
    
    
			buf[i]=DHT11_Read_Byte();
		}
		if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])//校验位判断
		{
    
    
			*humi=buf[0];
			*temp=buf[2];
		}
	}else return 1;
	return 0;	    
}

5 終了信号

終了信号については、DHT11 によって生成されるため、通常は処理する必要はなく、MCU は 40 ビットのデータを受信するだけで済みます。
ここに画像の説明を挿入

入力と出力の切り替え

通信処理全体のコードはおおよそ上記の内容ですが、まだ問題があり、GPIOA15は通信処理全体で開始信号を出力として提供するだけでなく、DHT11のデータを入力として取得します。前述したように、解決策は 2 つあり、そのうちの 1 つは、筆者のお気に入りでもあり、GPIOA15 をオープン ドレイン モードに直接初期化し、このとき、ODR に 1 を書き込むと、ハイ レベル出力を担当する PMOS がシールドされます。 , GPIOA15 はもはや出力ハイレベルではありません, つまり、MCU はもはや DATA ピンを占有していません. このとき、DATA ラインは外部プルアップ抵抗と DHT11 によって制御されます. このとき、ライブラリを直接呼び出します実際の DATA 状態である GPIOA15 の High および Low レベルを取得する関数。

/*********************************
函数名:DHT11_Init
函数功能:DHT11初始化
形参:void
返回值:void
备注:既要输入又要输出
DHT11_DATA-----PA15-------开漏输出//jtag脚需要关闭
**********************************/
u8 DHT11_Init(void)//初始化DHT11
{
    
    
	GPIO_InitTypeDef  GPIO_InitStructure;//定义一个结构体的变量
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//初始化GPIOA端口的时钟
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_Out_OD;//通用开漏输出
	GPIO_Init(GPIOA,&GPIO_InitStructure );
	DHT11_Start();  //复位DHT11
	return DHT11_Check();//等待DHT11的回应
}

別の解決策は、プッシュプル出力モードを使用し、GPIO ステータスを取得するときに切り替えて、GPIOA15 を入力モードに戻すことです。プッシュプル モードを使用するときにモードを切り替える必要があるのはなぜですか? プッシュプル出力モードでは、GPIOA15 が 0 を出力するか 1 を出力するためであり、GPIO の入力モードと出力モードを連続的に切り替えることしかできないためです。プロセス中。
このメソッドの初期化コードは次のとおりです。

//PA11
#define DHT11_IO_IN()  {
    
    GPIOA->CRH&=0XFFFF0FFF;GPIOA->CRH|=8<<15;}//切换为输入模式
#define DHT11_IO_OUT() {
    
    GPIOA->CRH&=0XFFFF0FFF;GPIOA->CRH|=3<<15;} //切换为输出模式
//初始化DHT11的IO口 DQ 同时检测DHT11的存在
//返回1:不存在
//返回0:存在    	 
u8 DHT11_Init(void)
{
    
    	 
 	GPIO_InitTypeDef  GPIO_InitStructure;	
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	 //使能PA端口时钟
 	GPIO_InitStructure.GPIO_Pin = DT;				 //PA15端口配置
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);				 //初始化IO口
 	GPIO_SetBits(GPIOA,DT);						 //PG11 输出高
			    
	DHT11_Rst();  //复位DHT11
	return DHT11_Check();//等待DHT11的回应
} 
//需要注意,使用此法时,上面的通讯流程代码都要稍作修改,代码太多了,这里就不贴出来了。

実際の効果

main関数呼び出しの初期化後は、正常に温度と湿度が取得できるようになります。
ここに画像の説明を挿入
市場の DHT11 のサンプリング レートはメーカーによって異なることに注意してください。一部のモジュールは 1 秒あたり 100 回収集できますが、一部のモジュールは 1 秒あたり 2 回しか収集できません。1 回の収集の時間間隔は、この時点で文字化けが発生します。

要約する

この論文では、一般的に使用されている DHT11 温湿度取得モジュールのタイミング シミュレーションを作成します。記事に不備がある場合は、どなたでも批判・修正していただけます。

おすすめ

転載: blog.csdn.net/qq_41954556/article/details/131355197