У меня есть программа, которая считывает датчики температуры и давления и выполняет на них внутреннее преобразование AD C, затем сохраняет данные в EEPROM, затем конвертирует обратно в исходное значение и отображает его на ЖК-дисплее. Проблема в том, что когда я отлаживаю программу в 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 после завершения записи значений. Обратите внимание, что значение не должно меняться, потому что я сохраняю его постоянным. Правильные значения должны быть 0x134
при «0x0000» и 0x0073
при 0x0064
. Я не понимаю, почему это не работает.
Любая помощь приветствуется!
![enter image description here](https://i.stack.imgur.com/UlWW2.png)
full code
#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;
}
}
}