PWM调光中断加上DHT11程序直接跑飞

利用52单片机制作一个PWM调光台灯,但同时加上一个DHT11温湿度传感器,结果加上DHT11程序直接跑飞,怀疑是PWM的中断问题,该如何解决


```c
//主函数
#include "REG52.H"
#include "INTRINS.H"
#include "SYSTEM.H"
#include "DHT11.H"
#include "KEY.H"
#include "LCD1602.H"
#include "ADC0832.H"

//---------------------------------------------------------------------------------------//
int INTENSITY;
uchar m;
uchar SCALE;
//---------------------------------------------------------------------------------------//
void main(void)
{
    //-------------------------------------------------------------------------------------//
    LCD_INITIAL();
    LCD_OUTPUT(1,0,"TEMP&HUM&INT:",13);
    //DHT_delay_ms(100);
    
    MOD_STATE = 0;
    HUM_STATE = 0;
    m = 0;
    SCALE = 20;
    
    TIME0_INITIAL();
    while(1)   
    {
        //-----------------------------------------------------------------------------------//
        DHT_OUTPUT();
        PHO_OUTPUT();
        DATA_UNITE();
        LCD_OUTPUT(2,0,INPUT_LCD_DATA,15);
        //-----------------------------------------------------------------------------------//
        CHECK_MODE_STATE();
        CHECK_HUM_STATE();
        HUM_CTRL();
        SCALE_CTRL();
    }
}
//---------------------------------------------------------------------------------------//
void TIME0() interrupt 1
{
    TR0 = 0;
    TH0 = 0xEC;
    TL0 = 0x78;
    m++;
    if(m < SCALE)
    {
        PWM = 0;
    }
    else if(m >= SCALE)
    {
        PWM = 1;
    }
    if(m == 40)
    {
        m = 0;
    }
    TR0 = 1;
}

//DHT11
#include "REG52.H"
#include "INTRINS.H"
#include "SYSTEM.H"
#include "DHT11.H"

uchar DHT_OUTPUT_DATA[8];
uchar RH,RL,TH,TL;

//---------------------------------------------------------------------------------------//
void DHT_delay_us(uchar us)
{
    while(--us);
}

//---------------------------------------------------------------------------------------//
void DHT_delay_ms(int ms)
{
    int i;
    for(; ms>0; ms--)
    {
        for(i=125;i>0;i--)
        {;}
    }
}

//---------------------------------------------------------------------------------------//
void DHT_START(void)
{
    DHT_IO = 1;
  DHT_delay_us(2);

  DHT_IO = 0;
  DHT_delay_ms(30);

  DHT_IO = 1;
  DHT_delay_us(30);
}

//---------------------------------------------------------------------------------------//
uchar DHT_BYTE(void)
{
    uchar i,DATA = 0;
  for(i=0; i<8; i++)                                    //´Ó¸ßµ½µÍÒÀ´Î½ÓÊÕ8λÊý¾Ý
  {
        while(!DHT_IO);                                        //µÈ´ý50usµÍµçƽ¹ýÈ¥

    DHT_delay_us(8);                                 //ÑÓʱ60us£¬Èç¹û»¹Îª¸ßÔòÊý¾ÝΪ1£¬·ñÔòΪ0

    DATA<<=1;                                       //ÒÆÎ»Ê¹ÕýÈ·½ÓÊÕ8λÊý¾Ý£¬Êý¾ÝΪ0ʱֱ½ÓÒÆÎ»

    if(DHT_IO == 1)                                   //Êý¾ÝΪ1ʱ£¬Ê¹DATA¼Ó1À´½ÓÊÕÊý¾Ý1
    {
            DATA += 1;
        }

        while(DHT_IO);                                      //µÈ´ýÊý¾ÝÏßÀ­µÍ
    }
    return DATA;
}

//---------------------------------------------------------------------------------------//
void DHT_OUTPUT(void)                                  //½ÓÊÕ40λµÄÊý¾Ý
{
    uchar R_H,R_L,T_H,T_L,REVISE;
    
  DHT_START();
    
  if(DHT_IO == 0)
  {
        while(DHT_IO == 0);                           //µÈ´ýÀ­¸ß
        
    DHT_delay_us(40);                                  //À­¸ßºóÑÓʱ80us
        
    R_H = DHT_BYTE();                                //½ÓÊÕʪ¶È¸ß°Ëλ  
    R_L = DHT_BYTE();                                //½ÓÊÕʪ¶ÈµÍ°Ëλ  
    T_H = DHT_BYTE();                                //½ÓÊÕζȸ߰Ëλ  
    T_L = DHT_BYTE();                                //½ÓÊÕζȵͰËλ
        
    REVISE = DHT_BYTE();                             //½ÓÊÕУÕýλ

    DHT_delay_us(25);                                //½áÊø

    if((R_H+R_L+T_H+T_L) == REVISE)   //УÕý
    {
            RH=R_H;
      RL=R_L;
      TH=T_H;
      TL=T_L;
    }
    //Êý¾Ý´¦Àí
    DHT_OUTPUT_DATA[0]='0'+(RH/10);
    DHT_OUTPUT_DATA[1]='0'+(RH%10);
    DHT_OUTPUT_DATA[2]='R';
    DHT_OUTPUT_DATA[3]='H';
    DHT_OUTPUT_DATA[4]='0'+(TH/10);
    DHT_OUTPUT_DATA[5]='0'+(TH%10);
    DHT_OUTPUT_DATA[6]=0xDF;
        DHT_OUTPUT_DATA[7]=0x43;
    }
}


//LCD1602
#include "REG52.H"
#include "INTRINS.H"
#include "LCD1602.H"
#include "SYSTEM.H"

//---------------------------------------------------------------------------------------//
void CHECK_BUZY(void)
{
    uchar sym;
    
    do
    {
        sym = 0xFF;
        LCD_EN = 0;
        LCD_RS = 0;
        LCD_RW = 1;
        LCD_EN = 1;
        sym = LCD_IO;
    }
    while(sym & 0x80);
    
    LCD_EN = 0;
}

//---------------------------------------------------------------------------------------//
void WRITE_COMMAND(uchar COM)
{
    CHECK_BUZY();
    
    LCD_EN = 0;
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_IO = COM;
    LCD_EN = 1;
    _nop_();
    LCD_EN = 0;
    delay(1);
}

//---------------------------------------------------------------------------------------//
void WRITE_DATA(uchar DATA)
{
    CHECK_BUZY();
    
    LCD_EN = 0;
    LCD_RS = 1;
    LCD_RW = 0;    
    LCD_IO = DATA;
    LCD_EN = 1;
    _nop_();
    LCD_EN = 0;
    delay(1);
}

//---------------------------------------------------------------------------------------//
void LCD_INITIAL(void)
{
    WRITE_COMMAND(0x38);
    WRITE_COMMAND(0x0C);
    WRITE_COMMAND(0x06);
    WRITE_COMMAND(0x01);
    delay(1);
}

//---------------------------------------------------------------------------------------//
void LCD_OUTPUT(uchar ROW, uchar COLUMN, uchar INPUT_LCD_DATA[], uchar N)
{
    uchar i;
    if(ROW == 1)
    {
        WRITE_COMMAND(0x80+COLUMN);
    }
    else
    {
        WRITE_COMMAND(0x80+0x40+COLUMN);
    }
    for(i=0;i<N;i++)
    {
        WRITE_DATA(INPUT_LCD_DATA[i]);
        delay(10);
    }
}

```

你说的程序直接跑飞是开机就跑飞还是运行到某功能时跑飞?固件和dht11的程序和原来的代码资源冲突,堆栈溢出相关,可以单步走一下,看看到具体哪里开始跑飞的

以下回答参考GPT,并由JoseKe整理完成,希望您能采纳:
这是一段不完整的代码,无法确定具体问题。在加入DHT11程序后,可能会出现中断优先级冲突导致程序跑飞的情况。您可以尝试将DHT11的读取放在定时器中断外部执行,或者调整PWM中断和DHT11读取的优先级。另外,如果您能提供更完整的代码,问题可能更容易得到解决。

从你提供的代码来看,似乎没有涉及到PWM调光台灯的部分,因此很难进行具体的说明。

但是,针对你怀疑是PWM中断问题导致程序跑飞的问题,我可以给出一些思路和建议:

检查中断服务程序是否正确。如果你使用了定时器产生PWM信号,那么你需要编写一个中断服务程序,在定时器溢出时改变输出引脚的电平来生成PWM信号。在编写中断服务程序时,需要注意保存寄存器现场和清除中断标志等操作,否则会导致程序异常。

检查中断优先级设置是否合理。如果你同时使用了多个中断,并且它们的优先级不同,就需要设置合理的中断优先级,以避免低优先级中断被高优先级中断打断而导致程序异常。

检查是否存在资源竞争的情况。如果在中断服务程序中访问了共享资源,例如全局变量,那么需要考虑多个中断同时访问该资源的情况。为了避免资源竞争,可以使用信号量等机制来保证只有一个中断能够访问该资源。

检查硬件连接是否正确。如果PWM信号无法正常输出,可能是因为硬件连接不正确,例如输出引脚接错等。在这种情况下,可以使用示波器等工具来检查信号是否正常输出。

这段代码不完整,没法分析的。有一种可能是你初始化了定时器,开启了中断,但没有对应的中断服务程序,不过这也只是猜测,毕竟这不是完整代码

引用chatGPT作答,在没有看到PWM和DHT11程序代码的情况下,很难确定确切的问题。然而,可能的一个原因是PWM和DHT11的中断处理发生了冲突。

一般来说,在处理中断时,确保中断程序尽可能地简短,且不会相互干扰非常重要。这意味着要避免在中断程序中使用延迟或串行通信等较长的操作。

解决这个问题的一种方法是使用基于定时器的PWM,而不是基于中断的PWM。在基于定时器的PWM中,定时器以固定频率生成脉冲,占空比由改变定时器读取的寄存器的值控制。这种方法不需要中断处理,通常更加可靠。

另一种方法是,如果必须使用基于中断的PWM,可以尝试调整中断处理程序的优先级或修改中断程序,以尽量减少冲突的可能性。如果您的微控制器上有硬件PWM模块,也可以考虑使用它,因为这可以简化实现并降低冲突的风险。

最终的最佳方法将取决于您的项目的具体要求和微控制器的约束条件。

你好,你的怀疑是有一定的道理的,有怀疑的方向可以尝试去调试,加入一些led灯翻转等代码来进行调试,或者直接使用lcd1602来进行调试,看看代码跑到哪里去了,针对性的去解决。