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

QQ登錄

只需一步,快速開(kāi)始

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

DHT11這類(lèi)需要大量延時(shí)操作的傳感器讀取問(wèn)題

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
現(xiàn)在是100毫秒讀取一次傳感器的值,但是在讀取期間,大量的延時(shí)操作會(huì)阻塞中斷函數(shù)的Key_slow_down按鍵消抖計(jì)時(shí)操作
能設(shè)置中斷優(yōu)先級(jí)解決嗎,或者是設(shè)置兩個(gè)定時(shí)器、兩個(gè)中斷,在觸發(fā)中斷時(shí)會(huì)互相影響嗎
void TIM3_IRQHandler(void)
{
        if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)
                {
                        if(++Key_slow_down==10) Key_slow_down=0;
                        if(++DHT11_slow_down==100) DHT11_slow_down=0;
                        TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
                }
}
void DHT11_Start(void)
{
        Delay_s(1);//傳感器上電后,要等待 1s 以越過(guò)不穩(wěn)定狀態(tài)在此期間無(wú)需發(fā)送任何指令
        DHT11_DataPin_Init(MCU_Output);//IO口輸出模式
        GPIO_SetBits(GPIOA,GPIO_Pin_10);
        GPIO_ResetBits(GPIOA,GPIO_Pin_10);
        Delay_ms(20);//拉低總線(xiàn)必須大于18毫秒,保證DHT11能檢測(cè)到起始信號(hào)
        GPIO_SetBits(GPIOA,GPIO_Pin_10);
        Delay_us(30);//延時(shí)等待20-40us后,讀取DHT11的響應(yīng)信號(hào)
        DHT11_DataPin_Init(MCU_Input);//IO口輸入模式
        if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_10)==0)
        {
                DHT11_exist_Plag=1;
                while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_10)==0);
                while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_10)==1);
        }
}
/****
        *@brief DHT11溫濕度測(cè)量
        *@parameter 無(wú)
        *@ReturnValue 無(wú)
        */
void DHT11_GetData(void)
{
        int8_t i,j,Temp=0x00;
        if(DHT11_exist_Plag==1)// 檢測(cè)DHT11是否存在,若DHT11不存在,則不必進(jìn)行下面步驟
        {
                for(j=0;j<5;j++)//一次完整的數(shù)據(jù)傳輸為40bit,高位先出
                {
                       
                        for(i=0;i<8;i++)
                        {
                                while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_10)==0);
                                Delay_us(30);
                                if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_10)==1)
                                {
                                        Temp=Temp|(0x80>>i);// 從高位開(kāi)始接收
                                        while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_10)==1);
                                }
                        }
                        Hum_Tem_Data[j]=Temp;
                        Temp=0x00;
                }
                if(Hum_Tem_Data[0]+Hum_Tem_Data[1]+Hum_Tem_Data[2]+Hum_Tem_Data[3]!=Hum_Tem_Data[4])// 校驗(yàn)數(shù)據(jù)是否正確,若不正確則數(shù)組全部寫(xiě)1
                {
                        Hum_Tem_Data[0]=0xff;
                        Hum_Tem_Data[1]=0xff;
                        Hum_Tem_Data[2]=0xff;
                        Hum_Tem_Data[3]=0xff;
                       
                }
        }else
        {
                DHT11_Start();
        }
}

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

使用道具 舉報(bào)

沙發(fā)
ID:1085441 發(fā)表于 2023-7-10 23:56 | 只看該作者
是的,延時(shí)時(shí)間比較長(zhǎng),好像有400uS,受一些中斷間隔時(shí)間短(小于400uS)的程序影響。我后來(lái)?yè)Q了I2C接口的芯片避免了這個(gè)問(wèn)題,型號(hào)好像是SHT30
回復(fù)

使用道具 舉報(bào)

板凳
ID:420836 發(fā)表于 2023-7-11 06:52 | 只看該作者
請(qǐng)注意,讀取傳感器的時(shí)間間隔與讀取寄存器的時(shí)間不同。 讀取寄存器并不需要花費(fèi)太多時(shí)間。
回復(fù)

使用道具 舉報(bào)

地板
ID:584195 發(fā)表于 2023-7-11 07:12 | 只看該作者
100ms 好象DH11都沒(méi)有轉(zhuǎn)換完成。別讀太快了,太快了也沒(méi)有意義。
回復(fù)

使用道具 舉報(bào)

5#
ID:213173 發(fā)表于 2023-7-11 07:21 | 只看該作者
對(duì)于DHT11這類(lèi)外設(shè),一個(gè)完整的工作周期比較長(zhǎng),長(zhǎng)時(shí)間的阻滯延時(shí)操作會(huì)影響其它需要及時(shí)響應(yīng)的程序的正常運(yùn)行。這種情況并不是使用中斷就能夠完美避免。這就需要換一種編程思路,使用輪詢(xún)法。假設(shè)你這個(gè)設(shè)備使用了DHT11溫濕度測(cè)量,時(shí)鐘芯片1302,按鍵掃描,8位數(shù)碼管動(dòng)態(tài)顯示等。那么使用定時(shí)器將主函數(shù)循環(huán)周期以最小時(shí)間單位要求的外設(shè)來(lái)設(shè)置。例如8位數(shù)碼管動(dòng)態(tài)顯示為參考取2~2.5ms,2*8=16ms,時(shí)間再長(zhǎng)碼管就要閃爍了。我們用switch-case-break分支語(yǔ)句編寫(xiě)(如有必要)上述各外設(shè)的子程序,每次主循環(huán)只執(zhí)行各子函數(shù)的一部分代碼,這就把各子函數(shù)中需要長(zhǎng)延時(shí)的時(shí)間用于執(zhí)行其它程序,提高運(yùn)行效率,避免互相干擾。
回復(fù)

使用道具 舉報(bào)

6#
ID:1057946 發(fā)表于 2023-7-11 08:54 | 只看該作者
zyluglugl 發(fā)表于 2023-7-11 07:12
100ms 好象DH11都沒(méi)有轉(zhuǎn)換完成。別讀太快了,太快了也沒(méi)有意義。

確實(shí),但是怎么解決讀取傳感器期間按鍵不能用的問(wèn)題呢
回復(fù)

使用道具 舉報(bào)

7#
ID:1057946 發(fā)表于 2023-7-11 08:55 | 只看該作者
TTQ001 發(fā)表于 2023-7-11 06:52
請(qǐng)注意,讀取傳感器的時(shí)間間隔與讀取寄存器的時(shí)間不同。 讀取寄存器并不需要花費(fèi)太多時(shí)間。

什么意思,能具體說(shuō)一下嗎,新手求指教
回復(fù)

使用道具 舉報(bào)

8#
ID:1057946 發(fā)表于 2023-7-11 09:04 | 只看該作者
wulin 發(fā)表于 2023-7-11 07:21
對(duì)于DHT11這類(lèi)外設(shè),一個(gè)完整的工作周期比較長(zhǎng),長(zhǎng)時(shí)間的阻滯延時(shí)操作會(huì)影響其它需要及時(shí)響應(yīng)的程序的正常 ...

但是這樣會(huì)出現(xiàn)一個(gè)問(wèn)題,假如該詩(shī)序要求在固定時(shí)間段內(nèi)發(fā)送一個(gè)字節(jié),那么輪詢(xún)的方法就會(huì)打亂這個(gè)時(shí)序
回復(fù)

使用道具 舉報(bào)

9#
ID:161164 發(fā)表于 2023-7-11 09:10 | 只看該作者
1. 代碼開(kāi)頭那1s delay是不必要的
2. 18ms的低電平是最少時(shí)間,即是說(shuō),你可以先拉低電平,然后去干其他事,超過(guò)18ms后再回來(lái)繼續(xù)剩下的動(dòng)作
3. 40bit x (50us + 70us(max)) = 4.8ms, 如果4.8ms的耗時(shí)也不能接受,可以改為用定時(shí)器捕獲下降沿時(shí)間差
回復(fù)

使用道具 舉報(bào)

10#
ID:69038 發(fā)表于 2023-7-11 10:00 | 只看該作者
溫濕傳感器100ms讀一次值毫無(wú)意義!1分鐘讀一次就夠了。
回復(fù)

使用道具 舉報(bào)

11#
ID:123289 發(fā)表于 2023-7-11 11:10 | 只看該作者
1、合理規(guī)劃時(shí)序。這與你對(duì)邏輯的的架構(gòu)方案有關(guān)。
2、禁用DELAY函數(shù),因?yàn)镈ELAY期間,其它程序被迫等待,誤事。改用中斷實(shí)現(xiàn)延時(shí)(希望你會(huì)這一著)。
3、如果調(diào)用的函數(shù)庫(kù)中有用到DELAY,請(qǐng)改之,自己寫(xiě)函數(shù)。
4、不要在中斷服務(wù)程序中進(jìn)行復(fù)雜運(yùn)算等耗時(shí)大的程序運(yùn)行。因?yàn)橹袛嘤袃?yōu)先執(zhí)行的權(quán)利,會(huì)占用其它程序的時(shí)間。這些程序移至MAIN中運(yùn)行(也希望你會(huì)這一著)。
以上,需要你對(duì)單片機(jī)有較深的理解。沒(méi)有一定的功底,是解決不了你提出的問(wèn)題的。
例如:
不會(huì)用中斷實(shí)現(xiàn)延時(shí)。只會(huì)用DELAY。
不會(huì)將中斷服務(wù)程序中的非緊要程序分離出來(lái)。
死等硬件(溫度傳感器)的返回信息。未預(yù)計(jì)等不到怎么辦。
對(duì)他人的函數(shù)缺點(diǎn),無(wú)法改動(dòng)。
……
回復(fù)

使用道具 舉報(bào)

12#
ID:155507 發(fā)表于 2023-7-11 11:41 | 只看該作者
讀取DHT11這類(lèi)需要大量延時(shí)操作的傳感器時(shí),可以結(jié)合定時(shí)器和中斷來(lái)解決問(wèn)題。以下是一種可能的解決方案:

1.配置一個(gè)定時(shí)器,讓它以較高的頻率觸發(fā)中斷,例如每隔1毫秒觸發(fā)一次中斷。

2.在中斷服務(wù)函數(shù)中,進(jìn)行按鍵消抖計(jì)時(shí)操作。

3.在主循環(huán)中使用輪詢(xún)法讀取DHT11傳感器的值。每次主循環(huán)迭代中,只讀取傳感器值的一部分,并確保不會(huì)阻塞太長(zhǎng)時(shí)間。

4.如果需要在固定時(shí)間段內(nèi)發(fā)送一個(gè)字節(jié),可以利用定時(shí)器的輸出比較功能生成一個(gè)精確的時(shí)序?梢詫⒁l(fā)送的字節(jié)數(shù)據(jù)預(yù)先存儲(chǔ)在一個(gè)緩沖區(qū)中,并在定時(shí)器的比較中斷中逐個(gè)發(fā)送字節(jié)。通過(guò)設(shè)置合適的定時(shí)器頻率和比較值,可以滿(mǎn)足時(shí)序要求。

下面是一個(gè)偽代碼示例,演示了上述思路:


// 定時(shí)器中斷服務(wù)函數(shù)
void TIM_IRQHandler() {
    if (TIM_GetITStatus(TIMx, TIM_IT_Update) != RESET) {
        // 按鍵消抖計(jì)時(shí)操作

        // 清除中斷標(biāo)志位
        TIM_ClearITPendingBit(TIMx, TIM_IT_Update);
    }
}

// 主循環(huán)
while (1) {
    // 讀取DHT11傳感器的值的一部分
    // 不要阻塞太長(zhǎng)時(shí)間

    // 執(zhí)行其他任務(wù)

    // 如果需要發(fā)送字節(jié)
    if (isSendByteRequired) {
        // 通過(guò)定時(shí)器的輸出比較來(lái)生成時(shí)序
        // 逐個(gè)發(fā)送字節(jié)
    }
}
通過(guò)結(jié)合定時(shí)器中斷和主循環(huán)的輪詢(xún),可以實(shí)現(xiàn)同時(shí)進(jìn)行傳感器讀取、按鍵消抖和其他任務(wù)的處理。同時(shí),通過(guò)合理設(shè)置定時(shí)器的頻率和比較值,可以滿(mǎn)足發(fā)送字節(jié)的精確時(shí)序要求。

請(qǐng)注意,以上示例代碼為偽代碼,實(shí)際的實(shí)現(xiàn)可能會(huì)因具體的STM32系列和使用的開(kāi)發(fā)環(huán)境而有所不同。您需要根據(jù)實(shí)際情況進(jìn)行相應(yīng)的配置和編程。
回復(fù)

使用道具 舉報(bào)

13#
ID:213173 發(fā)表于 2023-7-13 16:41 | 只看該作者
ZZZZZ134679 發(fā)表于 2023-7-11 09:04
但是這樣會(huì)出現(xiàn)一個(gè)問(wèn)題,假如該詩(shī)序要求在固定時(shí)間段內(nèi)發(fā)送一個(gè)字節(jié),那么輪詢(xún)的方法就會(huì)打亂這個(gè)時(shí)序

微妙級(jí)的阻滯延時(shí)一般不影響其它程序運(yùn)行,毫秒級(jí)阻滯延時(shí)就要考慮用其它方法避免。給你一個(gè)示例參考。

DHT11溫濕度上下限報(bào)警 仿真.rar (146.88 KB, 下載次數(shù): 6)


回復(fù)

使用道具 舉報(bào)

14#
ID:1054554 發(fā)表于 2023-7-13 17:39 | 只看該作者
上述各外設(shè)的子程序,每次主循環(huán)只執(zhí)行各子函數(shù)的一部分代碼,這就把各子函數(shù)中需要長(zhǎng)延時(shí)的時(shí)間用于執(zhí)行其它程序,提高運(yùn)行效率,避免互相干擾。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表