奇怪的变量行为 - Arduino Uno rev 3

时间:2013-01-10 14:46:37

标签: c arduino buffer-overflow

我对int变量有一个非常奇怪的问题。有一个代码:

#include <EEPROM.h>
#define dht_dpin 14

byte bGlobalErr;
byte dht_dat[4];

int a;

void setup(){
    pinMode(13, OUTPUT);
    a = 0;
    InitDHT();
    Serial.begin(9600);
    delay(300);
    Serial.println("Humidity and temperature\n\n");
    delay(700);
} //end "setup()"

void loop()
{
    digitalWrite(13, HIGH);
    delay(300);
    digitalWrite(13, LOW);
    Serial.println(a);

    ReadDHT();

    switch (bGlobalErr) 
        {
            case 0:
                Serial.print("humdity = ");
                Serial.print(dht_dat[0], DEC);
                Serial.print(".");
                Serial.print(dht_dat[1], DEC);
                Serial.print("%  ");
                Serial.print("temperature = ");
                Serial.print(dht_dat[2], DEC);
                Serial.print(".");
                Serial.print(dht_dat[3], DEC);
                Serial.println("C  ");
                EEPROM.write(a, dht_dat[0]);
                EEPROM.write(a + 1, dht_dat[2]);

                break;
            case 1:
                Serial.println("Error 1: DHT start condition 1 not met.");
                break;
            case 2:
                Serial.println("Error 2: DHT start condition 2 not met.");
                break;
            case 3:
                Serial.println("Error 3: DHT checksum error.");
                break;
            default:
                Serial.println("Error: Unrecognized code encountered.");
                break;


    } //end "switch"

        a = a + 2;
        delay(10000);

} // end loop()

void InitDHT(){
    pinMode(dht_dpin,OUTPUT);
    digitalWrite(dht_dpin,HIGH);
} //end InitDHT

void ReadDHT(){
    bGlobalErr=0;
    byte dht_in;
    byte i;
    digitalWrite(dht_dpin,LOW);
    delay(18);
    delayMicroseconds(600);
    digitalWrite(dht_dpin,HIGH); 
    delayMicroseconds(40);
    pinMode(dht_dpin,INPUT);
    delayMicroseconds(40);

    dht_in=digitalRead(dht_dpin);

    if(dht_in) {
        bGlobalErr=1;
        return;
    } //end "if..."
    delayMicroseconds(80);

    dht_in=digitalRead(dht_dpin); //Was: dht_in = PINC & _BV(dht_PIN);

    if(!dht_in) {
        bGlobalErr=2;
        return;
    } //end "if..."

    delayMicroseconds(70);
    for (i=0; i<5; i++)
        dht_dat[i] = read_dht_dat();

    pinMode(dht_dpin,OUTPUT); //Was: DDRC |= _BV(dht_PIN);
    digitalWrite(dht_dpin,HIGH); //Was: PORTC |= _BV(dht_PIN);
    byte dht_check_sum =
            dht_dat[0]+dht_dat[1]+dht_dat[2]+dht_dat[3];
    if(dht_dat[4]!= dht_check_sum)
    {bGlobalErr=3; }
}; //end ReadDHT()

byte read_dht_dat(){
    byte i = 0;
    byte result=0;
    for(i=0; i< 8; i++) {
        while(digitalRead(dht_dpin)==LOW) ;
        delayMicroseconds(30);
        if (digitalRead(dht_dpin)==HIGH)
            result |=(1<<(7-i));
        while (digitalRead(dht_dpin)==HIGH) ;
    } //end of "for.."
    return result;
} //end of "read_dht_dat()"

输出是:

Humidity and temperature

0
humdity = 49.0%  temperature = 22.0C  
73
humdity = 49.0%  temperature = 22.0C  
73
humdity = 49.0%  temperature = 22.0C  
73
humdity = 49.0%  temperature = 22.0C

变量“a”在开头设置为“0”,然后它在开关部分内部的值为71,有时但非常罕见的70或72甚至更奇怪。我已经对a设置为0并递增的地方进行了不同的组合。 我在“a”旁边添加了变量“b”,“b”表现得应该如此。然后我在变量“b”的两个“EEPROM.write ...”命令中更改了变量“a”,程序运行良好。 当我删除变量“a”时,变量“b”开始表现与变量“a”完全相同。

任何想法的人?

由于

1 个答案:

答案 0 :(得分:3)

a之前声明的变量上有所有缓冲区溢出的迹象,特别是byte dht_dat[4]。尝试开始将其扩展到byte dht_dat[8]并查看问题是否消失。然后开始查找写入超过4个字节到dht_dat的位置。

另外,行

byte dht_check_sum =
        dht_dat[0]+dht_dat[1]+dht_dat[2]+dht_dat[3];
if(dht_dat[4]!= dht_check_sum)

应该被审核......你明确地引用了dht_dat这里的界限。

干杯,