c - 在 AVR 微 Controller 上使用结构

标签 c pointers struct microcontroller

我正在尝试将 uint8_t 和 uint16_t 成员的结构从 ATMega32 微 Controller 保存到外部 EEPROM 中。因此,我编写了一个函数来保存该结构,并编写了另一个函数来再次读取它。 在读取函数中,地址作为指针传入。在函数内部,该值通过 RS232 打印,但我得到了错误的数据和错误的地址(下面的终端输出)。但我不改变地址(如你所见),我不知道为什么输出是“600”。 保存单个字节的函数工作正常,我已经单独测试了它们。

这是我尝试准备结构、保存并最后再次读取的主程序。主程序下

    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

最佳答案

我认为,当您在 saveDataSet 中生成字符串时,您可能会通过溢出 text 缓冲区来覆盖 testLoadAddr 变量的内容。您只允许使用 20 个字符,但您有 2 位数字,因此有一串 24 个字符,包括终止 NUL。这肯定是一个问题,尽管具体哪些变量受到影响将取决于编译器创建的堆栈布局。

关于c - 在 AVR 微 Controller 上使用结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33607578/

相关文章:

c - 虚拟文件系统内存块创建

c - Linux 中 C 中的递归文件删除

c++ - 通过指针访问 std::vector 元素与 end()

c++ - 从文本文件中读取创建的结构类型时遇到问题

c - 如何在 LLVM 中定义全局变量并在 C 中使用它?

c - 读一个C文件,多读一行,为什么?

我的反向链接列表代码可以进一步增强吗

c - 如何复制结构体指针

c++ - C++将结构传递给函数以访问嵌套结构

创建一个简单的二叉搜索树