2015-11-09 55 views
0

我試圖從ATMega32微控制器中將uint8_t和uint16_t成員的結構保存到外部EEPROM中。出於這個原因,我寫了一個函數來保存這個結構,另一個函數再次讀取它。 在讀取函數中,地址作爲指針傳入。在函數內部,通過RS232打印值,但是我得到了錯誤的數據以及錯誤的地址(下面的終端輸出)。但我不改變地址(屁股你可以看到),我不知道爲什麼輸出它'600'。 保存單個字節的功能正常工作,我已經單獨測試了它們。在AVR微控制器上使用Structs

這是我嘗試準備結構的主程序,保存並最終再次讀取。在主程序

uint16_t testSaveAddr = 20; 
    uint16_t testLoadAddr = 20; 
    dataEntry testData; 
    dataEntry loadData; 


    testData.airPressure = 1023; 
    testData.batteryCharge = 140; 
    testData.dayOfMonth = 20; 
    testData.hours24 = 11; 
    testData.humidityInside = 63; 
    testData.humidityOutside = 80; 
    testData.lightVal = 123; 
    testData.minutes = 30; 
    testData.month = 11; 
    testData.rain = 0; 
    testData.temperatureInside = 240; 
    testData.temperatureOutside = 130; 
    testData.windDirection = 4; 
    testData.windVelocity = 300; 
    testData.yearS70 = 35; 

    saveDataSet(EEPROM_1_ADDR,testData,&testSaveAddr); 
    _delay_ms(200); 
    readDataSet(EEPROM_1_ADDR,&testLoadAddr,&loadData); 
    _delay_ms(200); 

uint8_t saveDataSet (char address_device, dataEntry dS, uint16_t *firstAvailableAddr) 
{ 
    uart_puts("*** SAVING NOW ****\n"); 
    //hum -> timeStamp, LOW -> HIGH 
    uint16_t addr = *firstAvailableAddr; 
    char text[20]; 

    sprintf(text,"1.| addr: %d\t data: %d\n",addr,dS.humidityOutside); 
    uart_puts(text); 

    save_byte_to_eeprom(address_device, addr++, dS.humidityOutside); 

    sprintf(text,"1.| addr: %d\t data: %d\n",addr,dS.humidityInside); 
    uart_puts(text); 

    save_byte_to_eeprom(address_device, addr++, dS.humidityInside); 
    save_byte_to_eeprom(address_device, addr++, (dS.temperatureOutside)&0xFF); 
    save_byte_to_eeprom(address_device, addr++, ((dS.temperatureOutside)>>8)&0xFF); 
    save_byte_to_eeprom(address_device, addr++, (dS.temperatureInside)&0x0FF); 
    save_byte_to_eeprom(address_device, addr++, ((dS.temperatureInside)>>8)&0xFF); 
    save_byte_to_eeprom(address_device, addr++, (dS.airPressure)&0xFF); 
    save_byte_to_eeprom(address_device, addr++, ((dS.airPressure)>>8)&0xFF); 
    save_byte_to_eeprom(address_device, addr++, (dS.windVelocity)&0xFF); 
    save_byte_to_eeprom(address_device, addr++, ((dS.windVelocity)>>8)&0xFF); 
    save_byte_to_eeprom(address_device, addr++, dS.windDirection); 
    save_byte_to_eeprom(address_device, addr++, dS.lightVal); 
    save_byte_to_eeprom(address_device, addr++, dS.rain); 
    save_byte_to_eeprom(address_device, addr++, dS.batteryCharge); 

    //timeStamp 
    save_byte_to_eeprom(address_device, addr++, dS.minutes); 
    save_byte_to_eeprom(address_device, addr++, dS.hours24); 
    save_byte_to_eeprom(address_device, addr++, dS.dayOfMonth); 
    save_byte_to_eeprom(address_device, addr++, dS.month); 
    save_byte_to_eeprom(address_device, addr++, dS.yearS70); 

    //update, when dataset is fully stored, in case of an error 
    *firstAvailableAddr = addr; 
    return 1; 
} 

uint8_t readDataSet (char address_device, uint16_t *nextDSaddr, dataEntry dS) 
{ 
    uint16_t addr = *nextDSaddr; 
    char text[20]; 
    uart_puts("**** READING NOW ****"); 

    dS->humidityOutside = read_byte_from_eeprom(address_device,addr); 
    sprintf(text,"1.| addr: %d\t data: %d\n",addr,dS->humidityOutside); 
    uart_puts(text); 
    addr++; 

    dS->humidityInside = read_byte_from_eeprom(address_device,addr++); 

    uint8_t tempOutLow = read_byte_from_eeprom(address_device,addr++); 
    uint8_t tempOutHigh = read_byte_from_eeprom(address_device,addr++); 
    dS->temperatureOutside = (tempOutHigh<<8)+tempOutLow; 


    uint8_t tempInLow = read_byte_from_eeprom(address_device,addr++); 
    uint8_t tempInHigh = read_byte_from_eeprom(address_device,addr++); 
    dS->temperatureInside = (tempInHigh<<8)+tempInLow; 

    uint8_t airPressLow = read_byte_from_eeprom(address_device,addr++); 
    uint8_t airPressHigh = read_byte_from_eeprom(address_device,addr++); 
    dS->airPressure = (airPressHigh<<8)+airPressLow; 

    uint8_t windVelLow = read_byte_from_eeprom(address_device,addr++); 
    uint8_t windVelHigh = read_byte_from_eeprom(address_device,addr++); 
    dS->airPressure = (windVelHigh<<8)+windVelLow; 

    dS->windDirection = read_byte_from_eeprom(address_device,addr++); 
    dS->lightVal = read_byte_from_eeprom(address_device,addr++); 
    dS->rain = read_byte_from_eeprom(address_device,addr++); 
    dS->batteryCharge = read_byte_from_eeprom(address_device,addr++); 

    //timestamp 
    dS->minutes = read_byte_from_eeprom(address_device,addr++); 
    dS->hours24 = read_byte_from_eeprom(address_device,addr++); 
    dS->dayOfMonth = read_byte_from_eeprom(address_device,addr++); 
    dS->month = read_byte_from_eeprom(address_device,addr++); 
    dS->yearS70 = read_byte_from_eeprom(address_device,addr++); 

    *nextDSaddr = addr; 
    return 1; 
} 

端子輸出:

*** SAVING NOW **** 
1.| addr: 20  data: 80 
1.| addr: 21  data: 63 
**** READING NOW ****** 
1.| addr: 600 data: 255 

回答

1

我想你可以通過溢出text緩衝區覆蓋testLoadAddr變量的內容,當你在saveDataSet生成的字符串。你只允許20個字符,但你有2位數字,所以有24個字符串,包括終止NUL。這確實是一個問題,但確切地說受影響的變量將取決於編譯器創建的堆棧佈局。