我有一个程序,读取温度和压力传感器,并对它们进行内部ADC转换,然后将数据保存到EEPROM,然后转换回原始值并显示在LCD上。问题是,当我在Atmel中调试程序时,它似乎工作得很好。但是,代码实际上并不在我的电路上。它似乎只正确地写入和读取前2个字节,然后一遍又一遍地写入相同的字节。
下面是我写数据的代码。我正在使用包含的eeprom.h库,并通过拆分为低位和高位字节来写入一个16位的值。
void WriteToEEPROM(uint16_t value, int address){
uint8_t low_value = value;
uint8_t high_value = (value & 0xFF00) >> 8;
if ((address == 0) || (address == 100)){}
else {address++;}
while(!eeprom_is_ready()){}
eeprom_write_byte((uint8_t*)address, low_value);
while(!eeprom_is_ready()){}
address++;
eeprom_write_byte((uint8_t*)address, high_value);
while(!eeprom_is_ready()){}
}这是写完值后EEPROM的内容。注意,这个值不应该改变,因为我保持它不变。正确的值应为'0x0000‘处的0x134和0x0064处的0x0073。我不明白为什么这不起作用。
如有任何帮助,我们不胜感激!

完整代码
#define __DELAY_BACKWARD_COMPATIBLE__
#define F_CPU 8000000UL
#define eeprom_is_ready()
#include <avr/io.h>
#include <avr/delay.h>
#include <stdint.h>
#include <avr/eeprom.h>
#include <stdio.h>
//******************LCD PROGRAM STARTS*********************//
#define LCD_DATA PORTD // port D is selected as LCD data port
#define ctrl PORTC // port C is selected as LCD command port
#define en PC2 // enable signal is connected to port D pin 7
#define rw PC1 // read/write signal is connected to port D pin 6
#define rs PC0 // register select signal is connected to port D pin 5
void LCD_cmd(unsigned char cmd);
void init_LCD(void);
void LCD_write(unsigned char data);
void LCD_write_string(char*str);
void WriteToEEPROM(uint16_t value, int address);
void scaled_delay(int delay){
_delay_ms(delay * 1000);
}
void setup(void){
DDRA = 0x00; //PORTA is set as an input
DDRD = 0xFF; //PORTD is set as an output
DDRC = 0xFF;
}
//Temperature sensor output connected to PA0
void ReadTemp(int address){
ADCSRA = ADCSRA | 0b10000111; //enable ADC, CLK/128 conversion speed
ADMUX = ADMUX | 0b01000000; //Use internal 2.56V Vref and PA0 as input, right-hand justified
ADCSRA |= (1 << ADSC); //start conversion
while(!(ADCSRA & (1 << ADIF))) {}
WriteToEEPROM(ADC, address);
}
//Temperature sensor output connected to PA1
void ReadPressure(int address){
ADCSRA = ADCSRA | 0b10000111; //enable ADC, CLK/128 conversion speed
ADMUX = ADMUX | 0b01000001; //Use AVCC and PA0 as input, right-hand justified
ADCSRA |= (1 << ADSC); //start conversion
while(!(ADCSRA & (1 << ADIF))){} // wait until process is finished
address = address + 100;
WriteToEEPROM(ADC, address);
}
void WriteToEEPROM(uint16_t value, int address){
uint8_t low_value = value;
uint8_t high_value = (value & 0xFF00) >> 8;
if ((address == 0) || (address == 100)){}
else {address++;}
while(!eeprom_is_ready()){}
eeprom_write_byte((uint8_t*)address, low_value);
while(!eeprom_is_ready()){}
address++;
eeprom_write_byte((uint8_t*)address, high_value);
while(!eeprom_is_ready()){}
}
void ReadEEPROM_Temp(uint8_t address){
uint8_t temp_value_low;
uint8_t temp_value_high;
char value_buffer_temp[100] = "";
if(address != 0) {address++;}
temp_value_low = eeprom_read_byte((uint8_t*)address);
address++;
temp_value_high = eeprom_read_byte((uint8_t*)address);
uint16_t temp_value = (temp_value_high << 8) | temp_value_low;
int temperature = (temp_value * 4.88) / 10;
sprintf(value_buffer_temp,"%s %d %s ", "Temp ", temperature, "C");
init_LCD();
LCD_cmd(0x0C);
_delay_ms(100);
LCD_write_string(value_buffer_temp);
}
void ReadEEPROM_Pres(uint8_t address){
uint8_t pres_value_low;
uint8_t pres_value_high;
char value_buffer_pres[100] = "";
if(address != 100) {address++;}
pres_value_low = eeprom_read_byte((uint8_t*)address);
address++;
pres_value_high = eeprom_read_byte((uint8_t*)address);
uint16_t pres_value = (pres_value_high << 8) | pres_value_low;
int v_out = (pres_value * 4.88)/1000;
int pressure = ((v_out/5.1) + 0.095) / 0.009;
sprintf(value_buffer_pres,"%s %d %s ", "Pres ", pressure, "kPa");
LCD_cmd(0xC0);
_delay_ms(100);
LCD_write_string(value_buffer_pres);
}
void init_LCD(void){
LCD_cmd(0x38);
// initialization in 8bit mode of 16X2 LCD
_delay_ms(1);
LCD_cmd(0x01);
// make clear LCD
_delay_ms(1);
LCD_cmd(0x02);
// return home
_delay_ms(1);
LCD_cmd(0x06);
// make increment in cursor
_delay_ms(1);
LCD_cmd(0x80);
// “8” go to first line and “0” is for 0th position
_delay_ms(1);
return;
}
//**************sending command on LCD***************//
void LCD_cmd(unsigned char cmd){
LCD_DATA = cmd; // data lines are set to send command
PORTC &= ~(1<<rs); // RS sets 0
PORTC &= ~(1<<rw); // RW sets 0
PORTC |= (1<<en); // make enable from high to low
_delay_ms(100);
PORTC &= ~(1<<en);
return;
}
//*****************write data on LCD*****************//
void LCD_write(unsigned char data){
LCD_DATA= data; // data lines are set to send command
PORTC |= (1<<rs); // RS sets 1
PORTC &= ~(1<<rw); // RW sets 0
PORTC |= (1<<en); // make enable from high to low
_delay_ms(100);
PORTC &= ~(1<<en);
return ;
}
//store address value of the string in pointer *str
void LCD_write_string(char *str) {
int i=0;
for(i; str[i]!=0; i++){
// loop will go on till the NULL character in the string
LCD_write(str[i]); // sending data on LCD byte by byte i++;
}
return;
}
int main(void)
{
setup();
int counter = 0;
while (1)
{
scaled_delay(1); //delay 1 hour
ReadTemp(counter); //get temperature reading
ReadPressure(counter); //get pressure reading
counter++; //keep track of number of conversions
//get reading 24 times
if(counter == 23){
counter = 0;
while (counter != 24)
{
ReadEEPROM_Temp(counter);
ReadEEPROM_Pres(counter + 100);
counter++;
}
counter = 0;
}
}
}发布于 2020-08-03 00:56:37
address变量中似乎有一个错误。它的类型为int,但应为unsigned int类型(地址不能为负数)。你能试试下面的代码吗:
void WriteToEEPROM(unsigned int value, unsigned int address)
{
unsigned char low_value = (unsigned char)value;
unsigned char high_value = (unsigned char)(value>>8);
eeprom_write_word((unsigned char*)address ,value);
address++;
address++;
}请同时将delay.h路径更改为
#include <util/delay.h>read函数可能还包含一些不必要的内容:
void ReadEEPROM_Temp(unsigned int address)
{
char buffer[100];
unsigned int temp = eeprom_read_word((unsigned char*)address) * 4.88 / 10UL;
address++;
address++;
sprintf(buffer,"Temp %5d C", temp);
init_LCD();
LCD_cmd(0x0C);
_delay_ms(100);
LCD_write_string(buffer);
}警告:
可能是由于在主例程中多次写入相同的地址空间,所以你的EEPROM当前已被销毁:
while (1)
{
scaled_delay(1); // !!!THIS CREATES A DELAY OF 1 SECOND
ReadTemp(counter); // WRITE DATA TO EEPROM
ReadPressure(counter); // WRITE DATA TO EEPROM
// ...正常情况下,如果您的函数在main例程之上,则没有必要声明原型。您是否正在使用Atmel Studio进行开发?
发布于 2020-08-03 00:59:29
尝试使用EEPROM清除程序,然后重新尝试运行您的程序。
https://stackoverflow.com/questions/63217239
复制相似问题