简体   繁体   English

在AVR微控制器上使用Structs

[英]Working with Structs on a AVR microcontroller

I am trying to save a structure of uint8_t and uint16_t members from an ATMega32 microcontroller into an external EEPROM. 我正在尝试将ATMega32微控制器中uint8_t和uint16_t成员的结构保存到外部EEPROM中。 For this reason I wrote a function to save this struct and another to read it again. 因此,我编写了一个函数来保存该结构,并编写另一个函数以再次读取它。 In the read function the address is passed in as pointer. 在读取功能中,地址作为指针传递。 Inside the function the value is printed via RS232, but I get the wrong data as well as a wrong adress (terminal output below). 在函数内部,该值是通过RS232打印的,但是我得到了错误的数据和错误的地址(下面的端子输出)。 But I don't change the adress (ass you can see), I have no idea why the output it '600'. 但是我不更改地址(您可以看到),我也不知道为什么输出为“ 600”。 The functions to save a single byte work fine, I have tested them separately. 保存单个字节的功能可以正常工作,我已经分别测试了它们。

This is the main program where I am trying to prepare the struct, save it and finally read it again. 这是我尝试准备结构,保存并最终再次读取的主程序。 Under the main program 在主程序下

    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;
}

Terminal output: 终端输出:

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

I think you may be overwriting the contents of the testLoadAddr variable by overflowing the text buffer when you generate the strings in saveDataSet . 我认为您可能会在saveDataSet生成字符串时,通过溢出text缓冲区来覆盖testLoadAddr变量的内容。 You have only allowed for 20 chars but you have 2 digit numbers so have a string of 24 chars including the terminating NUL. 您只允许输入20个字符,但是您有2位数字,因此必须包含24个字符的字符串,包括终止NUL。 This is certainly a problem though exactly which variables get affected will depend on the stack layout created by the compiler. 尽管确切地影响哪个变量将取决于编译器创建的堆栈布局,但这肯定是一个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM