void EEPROM_writee(unsigned int uiAddress, unsigned char ucData) dosent work in atmel studio

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

Hi;

i wanna write a byte in eeprom with atmel studio , and i use example of datasheet atmega8 , but it dosnt work , i test many cases . but i could not get answer.
in atmel simulation  , and  EEWE  dosent get 1 , i dont know why, and my interrupt is off; 

but eeprom lib in atmel studio work good with any problem. 

 

what is my wrong ?

void EEPROM_writee(unsigned int uiAddress, unsigned char ucData)
{
	
	//cli();
	/* Wait for completion of previous write */
	while(EECR & (1<<EEWE))	;
	
	/* Set up address and data registers */
	EEAR = uiAddress;
	EEDR = ucData;
	/* Write logical one to EEMWE */
	EECR |= (1<<EEMWE);	
	
	/* Start eeprom write by setting EEWE */
	EECR |= (1<<EEWE);

}

 

This topic has a solution.
Last Edited: Sat. Sep 12, 2020 - 05:18 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If it's Atmel Studio then do you mean you are using the  avr-gcc compiler that came with it? (IOW do your programs start with #inlcude <avr/io.h> ?) If so then why do you feel the need to write your own EEPROM routines when the compiler comes with:

 

https://www.nongnu.org/avr-libc/user-manual/group__avr__eeprom.html

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

clawson wrote:

If it's Atmel Studio then do you mean you are using the  avr-gcc compiler that came with it? (IOW do your programs start with #inlcude <avr/io.h> ?) If so then why do you feel the need to write your own EEPROM routines when the compiler comes with:

 

https://www.nongnu.org/avr-libc/user-manual/group__avr__eeprom.html

 

this is my code :

 

main:

#define F_CPU 8000000
#define  SET_LED  PORTB = (1<<PORTB5);
#define  RESET_LED  PORTB = (0<<PORTB5);


#include <avr/io.h>
#include "util/delay.h"
#include "eepromm.h"
#include "CharacterLCDLib.h"
#include <stdlib.h>
#include <avr/eeprom.h>



int main(void)
{
    /* Replace with your application code */
	
	lcd_init();
	
	lcd_puts("Ready");
	
	
	
	//eeprom_write_byte((uint8_t*)1,20);
	//EEPROM_writee((char)1,20);
	
	
	int i = EEPROM_readd(1);
	char s[20];
	utoa(i,s,10);
	lcd_puts(s);
	
	_delay_ms(5000);
	
	
    while (1) 
    {
    }
}

 

and eepromm.h code :

 

#ifndef __EEPROM__
#define __EEPROM_
#include <avr/io.h>



void EEPROM_writee(unsigned int uiAddress, unsigned char ucData)
{
	
	//cli();
	/* Wait for completion of previous write */
	while(EECR & (1<<EEWE))	;
	
	/* Set up address and data registers */
	EEAR = uiAddress;
	EEDR = ucData;
	/* Write logical one to EEMWE */
	EECR |= (1<<EEMWE);	
	
	/* Start eeprom write by setting EEWE */
	EECR |= (1<<EEWE);

}

unsigned char EEPROM_readd(unsigned int uiAddress)
{
	/* Wait for completion of previous write */
	while(EECR & (1<<EEWE))
	;
	/* Set up address register */
	EEAR = uiAddress;
	/* Start eeprom read by writing EERE */
	EECR |= (1<<EERE);
	/* Return data from data register */
	return EEDR;
}



#endif

 

 

certainly   i use eeprom.h of gcc compiler. 
so , i am very involved  that why i cant do this, and why that is not working , and i wanna find realy my wrong.
thank you;

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#define  RESET_LED  PORTB = (0<<PORTB5);

this is a mistake for sure....... it will work for now, but this is definitely not the way to do what you intend to do.....

 

	//eeprom_write_byte((uint8_t*)1,20);
	//EEPROM_writee((char)1,20);

address is 8 bits????

void EEPROM_writee(unsigned int uiAddress, unsigned char ucData)

or 16 bits... what do you want??? you should have at least gotten a warning on this.

 

spot the problem here: it is a subtle one.

#ifndef __EEPROM__
#define __EEPROM_

 

I suggest stop trying to make your own routines. and use the ones that come with GCC. Then you can have more fun and energy for things that you really need to make yourself.

 

IIRC there not only are bit flags that you need to check, but also a lot of timing things that have to be right in order to actually get an EEPROM write done....

As a matter of fact you better use the ' update'  functions in GCC as this ensures a much longer EEPROM lifetime....

 

Last but not least have a look at the EEPROM tutorial written by Dean in the tutorials forum, that should help you understand things better......

 

 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your code is copied straight from the data-sheet so there's no problem there:

 

But Did you read this:

5. Write a logical one to the EEMWE bit while writing a zero to EEWE in EECR.
6. Within four clock cycles after setting EEMWE, write a logical one to EEWE.

 

You can only achieve that in C when optimisation is enabled. A pound-to-a-penny that is your problem.

 

Last Edited: Thu. Sep 10, 2020 - 12:27 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

N.Winterbottom wrote:

Your code is copied straight from the data-sheet so there's no problem there:

 

But Did you read this:

5. Write a logical one to the EEMWE bit while writing a zero to EEWE in EECR.
6. Within four clock cycles after setting EEMWE, write a logical one to EEWE.

 

You can only achieve that in C when optimisation is enabled. A pound-to-a-penny that is your problem.

 

 

yes, when i turn on optimisation , the problam was fixed . thank you;

 

but 

 

i read 

 

5. Write a logical one to the EEMWE bit while writing a zero to EEWE in EECR.
6. Within four clock cycles after setting EEMWE, write a logical one to EEWE.

and i saw in simulator of atmel stdio from 5 to 6 was 6 clock pulse , and i cant do that for 4 clock pulse ; 
 

i think if i write this function on assambly , this problem was clear; 

thank you all freinds;

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

meslomp wrote:

	//eeprom_write_byte((uint8_t*)1,20);
	//EEPROM_writee((char)1,20);

address is 8 bits????

void EEPROM_writee(unsigned int uiAddress, unsigned char ucData)

or 16 bits... what do you want??? you should have at least gotten a warning on this.

 

 

this function declare in eeprom.h of atmel studio default lib.

 

/** \ingroup avr_eeprom
    Write a byte \a __value to EEPROM address \a __p.
 */
void eeprom_write_byte (uint8_t *__p, uint8_t __value);