Atmega32 - Internal EEPROM read and write problem

Go To Last Post
16 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello friends,

I am trying to store variables in internal eeprom of atmega32. I have written program to write and read the internal memory. I have attached the source code for your reference ( already scanned using licensed quick heal anti virus).

In my program I have created to functions

1. To write data to specific eeprom address.
2. To read data from specific eeprom address.

I am using a bit variable to control the eeprom write operation.
In while(1), I am checking values read from eeprom with the values I have written to it. If the values are matched, then only I am displaying them on hyperterminal.

I have executed the program in following fashion.

Case 1. When eeprom_write_enable is set to 1

The hyperterminal shows output as

AA0000000000AA00000000000..

The 2 AA chars are used to indicate 2 write operations to eeprom.
The continuous 0s is the value I have written to the
memory location 0x10 of eeprom .

Questions:
1. Why I am not getting second byte written to the memory location 0x20 which is 1.

2. Why the chars AA are repeated in string even when I am not calling the function: write_eeprom_byte() again in while(1)?

Case 2: When eeprom_write enable is set to 0.

I don't get anything on hyperterminal.

Since data written to eeprom should persists after power off, i am expecting the data values 0 and 1.

Question: Why I am not getting the data values when writing to eeprom is disabled and performed only once?

Thanks in advance.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dear vijay,

If you want to post some code, please copy and paste within CODE tags like everyone else.

Otherwise no one will bother to look at a pdf.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear David,
Thanks for the advice. From here onwards I will always use them.


/*****************************************************
This program was produced by the
CodeWizardAVR V2.03.9 Evaluation
Automatic Program Generator
© Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
Version : 
Date    : 4/6/2009
Author  : Freeware, for evaluation and non-commercial use only
Company : 
Comments:  program to read and write internal eeprom memory.


Chip type               : ATmega32
Program type            : Application
AVR Core Clock frequency: 4.000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 512
*****************************************************/

#include 

// Standard Input/Output functions
#include 
#include 
// Declare your global variables here

eeprom char str[3] = {48,49,50};
eeprom int a=48;
int b=50;

int write_eeprom_byte(char address, char data)
{
//    EEARH=0x00;
//    EEARL = address ;
   
    while(EECR & 0x02 == 1) ;           // CHECK EEWE BIT
    
    while( SPMCR & 0x01 == 1);          // CHECK SPMEN BIT
   
    EEARH=0x00;                       // SET ADDRESS MSB BYTE
    EEARL = address ;                 // SET LSB BYTE OF ADDRESS
    EEDR = data ;                     // WRITE data to be written to EEPROM    
    EECR = 0x04 ;                       // SET EEMWE BIT
    #asm
        nop;
        nop;
       
    #endasm
    EECR = 0x06;                        // SET EEMWE & EEWE BITS
    
    while(EECR & 0x04 == 1);           // CHECK EEMWE IS CLRED
    
    
  //  delay_ms(10);                      // general delay
    
    return(1);
    

}

//////////////////////////////////////////////////////////////////////

char eeprom_read_byte(char address)
{
    char data=0;
    
    while(EECR & 0x02 == 1) ;           // check EEWE BIT IS CLRed
   
    EEARH=0x00;                       // SET MSB BYTE OF ADDRESS
    EEARL = address ;                   // SET LSB BYTE OF ADDRESS
    
    EECR = 0x01 ;                       // SET EERE BIT
    
    #asm
        nop;
        nop;
       
    #endasm
   
    data = EEDR;                   // read data from the EEPROM
    
    return(data);                // RETURN EEPROM data value
         

}

////////////////////////////////////////////////////////////////////////////


void main(void)
{
// Declare your local variables here
    int i=0;        
    int ret=1;                      // to store function return value
    char read_byte=0;               // to store eeprom data value
    bit eeprom_write_enable=1;      // to enable write operation on eeprom
                           
    
    
    
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: Off
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x08;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x19;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

  // if 1, perform write opertion on internal EEPROM    
  
if( eeprom_write_enable == 0)
{
   
    ret=write_eeprom_byte(0x10,0x30);      // write value to specified eeprom address
    if(ret == 1)                           // check write successful completion 
        putchar(65) ;                      // display char A on hyperterminal 
    
    ret=0;                                 // clr before reading again
        
    ret=write_eeprom_byte(0x20,0x31);      // write value to specified eeprom address
    if(ret == 1)                           // check write successful completion
        putchar(65) ;                      // display char A on hyperterminal
   
    
}



while (1)
      {      
          
           read_byte = eeprom_read_byte(0x10);   // read data from specified eeprom address
           if(read_byte == 0x30)                 // verify read data with data written to eeprom
                  putchar(read_byte);           // if write_data = read data, display on hyperterminal
          
            read_byte = eeprom_read_byte(0x20);    // read data from specified eeprom address
            if(read_byte == 0x31)                  // verify read data with data written to eeprom
                  putchar(read_byte);               // if write_data = read data, display on hyperterminal
                      
          delay_ms(100);        // display data values every 100 msec on hyperterminal
         
        
        
           
            
      };
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

your code has:

    while(EECR & 0x02 == 1) ;           // CHECK EEWE BIT

you probably mean:

    while((EECR & 0x02) != 0) ;           // CHECK EEWE BIT

I would write:

    while (EECR & 0x02) ;           // CHECK EEWE BIT

You should read about operator precedence in your C textbook.

looking at my equivalent function:

void wreeprom(unsigned short ads, unsigned char c)
{
	EEAR = ads;
	EEDR = c;
	EECR |= (1<<2);
	EECR |= (1<<1);
	while (EECR & (1<<1)) ;
	EECR &= ~(1<<2);
}

it is fairly straightforward to do the write. You must obey the timing constraints of the data sheet.

Of course since you are using CodeVision, you only have to say in the first place:

eeprom int a = '0';    // automatically handled by compiler

If you want to place your eeprom variables at specific locations, read the manual. Or cast constants appropriately. Easiest to do this with a macro.

#define wreeprom_int(ads, val) *((eeprom int *)(ads)) = (val)

n.b. it is wise to read the eeprom contents before writing to avoid unnecessary write when there is no change in value.

HTH David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Of course since you are using CodeVision, you only have to say in the first place:

Yes, I've used CV since the beginning with EEPROM used extensively in nearly all apps and I have never had to dabble with the provided low-level primitives.

CV gives you [nearly] transparent EEPROM access--use it. Done. Structure assignments, write suppression of identical values, direct assignment, direct reading, ...

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks David,
I really forgot to put parenthesis. I have made the changes suggested by you.
1. I tried using CV Avr provided eeprom keyword to declare the eeprom variables. But it gives me garbage value.
2. Even after making the suggested change my program is still not storing the values in eeprom.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Follow the appropriate eeprom examples in the example folder, or Help files. Compile an Run the programs and understand how they work.

It is simpler to just declare a named eeprom variable and just use it. No need to specify where it actually lives. Switch your power off and on, and the variable is retained.

1. remember to save eeprom contents when programming
2. if you use an initialised variable, it will initialise to the same value every time you run the program.
3. So you normally may use a eeprom flag to say you have a virgin eeprom. And only initialise virgins.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

1. I tried using CV Avr provided eeprom keyword to declare the eeprom variables. But it gives me garbage value.

What do you mean by that?

Are you using AVRStudio simulator to do this?

Are you programming the .EEP file to the chip?

CV's built-in EEPROM facilities work just fine. Look elsewhere.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
// Init the UART, etc.
// Are you sure your AVR is really running at 4MHz?  With a crystal?
...
unsigned char			schar = 'S';
eeprom unsigned char	echar = 'E';
flash unsigned char		fchar = 'F';
...
while (1)
	{
	putchar (schar);
	putchar (echar);
	putchar (fchar);
	delay_ms (100);
	putchar ('U');	// check bit timings with a 'scope
	putchar ('U');	// check bit timings with a 'scope
	putchar ('U');	// check bit timings with a 'scope
	putchar ('U');	// check bit timings with a 'scope
	delay_ms (100);
	}

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear friends,

I have looked at my previous projects in which I have successfully stored variables and array. The problem I feel is with the CV AVR version.

problem:

The project where storing data in eeprom is working successfully are developed using CV AVR version 1.25.3 where as currently I am using version 1.25.3.

I have migrated the licensed version so many times from one pc to another ( due to virus threats). Now I am not getting the version 1.25.3 setup file.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sorry I mean to say " currently I am using version 1.25.8 "

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Vijay,

If you have a problem with your licensed compiler, I suggest that you contact HPInfotech.

It is probably about time to upgrade to a more modern version anyway.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Repeat after me: There are no problems with the CV EEPROM intrinsics.

I also extensively used 1.24.5, 1.25.5, 1.25.7a, 1.25.8, etc. versions. EEPROM primitives have been essentially unchanged since 2000.

When you do the program I posted, or similar, what do you get?

Please post the smallest program that demonstrates your symptoms.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can anybody tell me how to save a float variable in the internal eeprom of atmega 32A using AS7 ?

I am not using CVAVR.

 

-Abhishek

Abhishek

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include <avr/io.h>
#include <avr/eeprom.h>

float foo EEMEM = 3.14159;

int main(void) {
    eeprom_write_float(&foo, 2.71828);
}

This overwrites the 3.14159 that may initially be in the EEPROM location "foo" with the value 2.71828.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks

Abhishek