eeprom

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

I have a very simple USART program to send a charecter to my hyper terminal. I want to copy those charecters into ATMEGA8515's EEPROM. USART is working fine. Could anyone tell me how to copy USART RECEIVED DATA into EEPROM.I tried to use eeprom_write_byte(). But it is not generating the .eep file.Here is my code Is this correct?
USART protocal:2400baudrate, 8 data,1 stop bit, no parity, f_cpu = 1MHZ.

#include 
#include 
#include 

#define BAUD_RATE			2400
#define UART_CLOCK_DIVIDER	16
#define UBRR_VALUE 		(((F_CPU/UART_CLOCK_DIVIDER)/BAUD_RATE) - 1)



void SCIInitialize(void)
{
	// Set the baud rate 
	UBRRH = UBRR_VALUE >> 8;
	UBRRL = UBRR_VALUE;
	
	/* Setup the frame format
	 * UCSRC: 
	 *   Bit 7: URSEL   = 1, Not used
	 *       6: UMSEL  = 0, Asynchronous operation
	 *       5: UPM1   = 0, Odd Parity
	 *       4: UPM0   = 0
	 *       3: USBS   = 0  1 stop bit
	 *       2: UCSZ1  = 1, 8 data bits 
	 *       1: UCSZ0  = 1
	 *       0: UCPOL  = 0, Not used for asynchronous mode
	 */

	UCSRC =  _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0) ;
 
	/* UCSRB: 
	 *   Bit 7: RXCIE  = 0, RX interrupt enabled
	 *       6: TXCIE  = 0, TX Complete interrupt disabled 
	 *       5: UDRIE  = 0, Data Reg Empty interrupt disabled. This will be
	 * 						enabled when we're ready to transmit.
	 *       4: RXEN   = 1, Receiver enabled
	 *       3: TXEN   = 1, Transmitter enabled
	 *       2: UCSZ2  = 0, 8 data bits (see UCSRC)
	 *       1: RXB8   = 0, No 9th data bit
	 *       0: TXB8   = 0, No 9th data bit
	 */

	UCSRB  =  _BV(RXEN) | _BV(TXEN);

	/* UCSRA: 
	 *   Bit 7: RXC   = 0, Input
	 *       6: TXC   = 0, Input
	 *       5: UDRE  = 0, Input
	 *       4: FE    = 0, Input
	 *       3: DOR   = 0, Input
	 *       2: UPE   = 0, Input
	 *       1: U2X   = 0, Do not want to double TX rate
	 *       0: MPCM  = 0, No multi-processor mode
	 */
	UCSRA = 0;

}


void tx(unsigned char data)
{
	while ( ( UCSRA & 0x20) == 0);
	
	UDR = data;		
		
}

unsigned char rx()
{
	unsigned char a;
	while ( ( UCSRA & 0x80) == 0);

	return UDR;
}

int main()
{
	unsigned char val = 0;
	DDRB = 0XFF;
	PORTB = 0XFF;
	
	SCIInitialize();

			
	for(;;)
	{
	
	  //tx(rx());	
		eeprom_write_byte((unsigned char*)0x03, (unsigned char)rx());
	}
}



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

Hello dolphin,

if I understand your program correctly it will always write the received char to the fourth EEPROM position (i.e. address 0x03).
And yes, this will not generate an .eep file.
This will only be generated, if you allocate memory in the EEPROM statically at compile time, e.g.

typedef struct {
   char name[25] = "good news";
   int value = 123;
   } tMyStruct;
tMyStruct myEEPROMvars EEPROM;
 

A hint: put all your EEPROM variables in one(!) structure, to go sure, that the addresses will not change, if you add C file and/or change the compiler version.

Best regards,
michaeL

In the beginning was the Word, and the Word was with God, and the Word was God.

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

I accept that it doesnt create .eep file.
But I am not sure , it writes the correct value in that location.
Here is what i did.
eeprom_write_byte((unsigned char*)0x03, (unsigned char)rx());
val = eeprom_read_byte((unsigned char*)0x03);
PORTB = val;

When i transmit the charecter 'a', PORTB Shows a different value. (I HAVE connected PORTB t0 LEDS)It supposed to be 0x0000 1010.but PORTB GIVES 0X1111 1000

When i type letter 'a' my hyper terminal should echo back the letter 'a' and then i want to store the letter 'a' in EEPROM. DOES my code write 'a' into 0x03?How do we make sure?

skotti wrote:
Hello dolphin,

if I understand your program correctly it will always write the received char to the fourth EEPROM position (i.e. address 0x03).
And yes, this will not generate an .eep file.
This will only be generated, if you allocate memory in the EEPROM statically at compile time, e.g.

typedef struct {
   char name[25] = "good news";
   int value = 123;
   } tMyStruct;
tMyStruct myEEPROMvars EEPROM;
 

A hint: put all your EEPROM variables in one(!) structure, to go sure, that the addresses will not change, if you add C file and/or change the compiler version.

Best regards,
michaeL

Last Edited: Wed. May 25, 2011 - 11:50 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please DO NOT double post, I wasted a lot of electrons replying to you here https://www.avrfreaks.net/index.p...

That thread is now locked.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

By mistake, I double posted.

I accept that it doesnt create .eep file.
But I am not sure , it writes the correct value in that location.
Here is what i did.
eeprom_write_byte((unsigned char*)0x03, (unsigned char)rx());
val = eeprom_read_byte((unsigned char*)0x03);
PORTB = val;

When i transmit the charecter 'a', PORTB Shows a different value. (I HAVE connected PORTB t0 LEDS)It supposed to be 0x0000 1010.but PORTB GIVES 0X1111 1000

When i type letter 'a' my hyper terminal should echo back the letter 'a' and then i want to store the letter 'a' in EEPROM. DOES my code write 'a' into 0x03?How do we make sure?

js wrote:
Please DO NOT double post, I wasted a lot of electrons replying to you here https://www.avrfreaks.net/index.p...

That thread is now locked.

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

Quote:
It supposed to be 0x0000 1010
How do you come up with that conlusion? 'a' is 0x61 or 0b01100001.

Also you need to wait for the EEPROM to be ready before writing to it .

	uint8_t EEMEM Off_time_h, Off_time_m;
.
.
.
	eeprom_busy_wait(); 
	eeprom_write_byte((uint8_t*)(& Off_time_h),hh);					//Write Hours to EEPROM

	eeprom_busy_wait(); 
	eeprom_write_byte((uint8_t*)(& Off_time_m),mm);					//Write Minutes to EEPROM

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Also, this is the wrong forum. Since this is GCC specific, it should be in the AVR GCC Forum.

Regards,
Steve A.

The Board helps those that help themselves.

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

js wrote:
Quote:
It supposed to be 0x0000 1010
How do you come up with that conlusion? 'a' is 0x61 or 0b01100001.

Also you need to wait for the EEPROM to be ready before writing to it .

	uint8_t EEMEM Off_time_h, Off_time_m;
.
.
.
	eeprom_busy_wait(); 
	eeprom_write_byte((uint8_t*)(& Off_time_h),hh);					//Write Hours to EEPROM

	eeprom_busy_wait(); 
	eeprom_write_byte((uint8_t*)(& Off_time_m),mm);					//Write Minutes to EEPROM

Thanks for your reply. I see all strange charecter in my hyper terminal. Here is what I did. Should i need to atoi()  converstion?


#include 
#include 
#include 
#include 

#define BAUD_RATE			2400
#define UART_CLOCK_DIVIDER	16
#define UBRR_VALUE 		(((F_CPU/UART_CLOCK_DIVIDER)/BAUD_RATE) - 1)

//const unsigned char array[]__attribute__((section(".eeprom"))) = { 0x0a, 0X0B,0X0C, 0X0D};
unsigned char EEMEM store_ee;

void SCIInitialize(void)
{
	// Set the baud rate 
	UBRRH = UBRR_VALUE >> 8;
	UBRRL = UBRR_VALUE;
	
	/* Setup the frame format
	 * UCSRC: 
	 *   Bit 7: URSEL   = 1, Not used
	 *       6: UMSEL  = 0, Asynchronous operation
	 *       5: UPM1   = 0, No Parity
	 *       4: UPM0   = 0
	 *       3: USBS   = 0  1 stop bit
	 *       2: UCSZ1  = 1, 8 data bits 
	 *       1: UCSZ0  = 1
	 *       0: UCPOL  = 0, Not used for asynchronous mode
	 */

	UCSRC =  _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0) ;
 
	/* UCSRB: 
	 *   Bit 7: RXCIE  = 0, RX interrupt enabled
	 *       6: TXCIE  = 0, TX Complete interrupt disabled 
	 *       5: UDRIE  = 0, Data Reg Empty interrupt disabled. This will be
	 * 						enabled when we're ready to transmit.
	 *       4: RXEN   = 1, Receiver enabled
	 *       3: TXEN   = 1, Transmitter enabled
	 *       2: UCSZ2  = 0, 8 data bits (see UCSRC)
	 *       1: RXB8   = 0, No 9th data bit
	 *       0: TXB8   = 0, No 9th data bit
	 */

	UCSRB  =  _BV(RXEN) | _BV(TXEN);

	/* UCSRA: 
	 *   Bit 7: RXC   = 0, Input
	 *       6: TXC   = 0, Input
	 *       5: UDRE  = 0, Input
	 *       4: FE    = 0, Input
	 *       3: DOR   = 0, Input
	 *       2: UPE   = 0, Input
	 *       1: U2X   = 0, Do not want to double TX rate
	 *       0: MPCM  = 0, No multi-processor mode
	 */
	UCSRA = 0;

}

void delay(unsigned int val)
{
   volatile unsigned int temp;
   volatile unsigned int temp2;

   for(temp = 0; temp < val; temp++) 
   for (temp2 = 0; temp2 < val; temp2 ++) ;

}


void tx(unsigned char data)
{
	while ( ( UCSRA & 0x20) == 0);
	
	UDR = data;		
		
}

unsigned char rx()
{
	unsigned char a;
	while ( ( UCSRA & 0x80) == 0);

	return UDR;
}

int main()
{
	unsigned char val , a;
	DDRB = 0XFF;
	PORTB = 0XFF;
	
	SCIInitialize();

			
	for(;;)
	{
	
	    val = rx();	
		//val = atoi(&val);
		tx(val);
		
		
		eeprom_busy_wait();

		eeprom_write_byte((unsigned char*)(&store_ee), (unsigned char)val);

		eeprom_busy_wait();
		

		
		a = eeprom_read_byte((unsigned char*)(&store_ee));
		PORTB = a; 
	}
}



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

js wrote:
Also you need to wait for the EEPROM to be ready before writing to it .
No.
Documentation of avr/eeprom.h wrote:
All of the read/write functions first make sure the EEPROM is ready to be accessed.

Stefan Ernst

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

sternst wrote:
js wrote:
Also you need to wait for the EEPROM to be ready before writing to it .
No.
Documentation of avr/eeprom.h wrote:
All of the read/write functions first make sure the EEPROM is ready to be accessed.

It is still not working. I still see some strange charecters in my hyper terminal. If I commnet out all
eeprom read & write.It is perfect. Why do I see weird charecters , when I include eeprom read and write?
Could anyone help me?Urgent please.

Here is what I did.

int main()
{
	unsigned char val , a;
	DDRB = 0XFF;
	PORTB = 0XFF;
	
	SCIInitialize();

			
	for(;;)
	{
	
	    val = rx();	
		//val = atoi(&val);
		tx(val);
		
		
		eeprom_busy_wait();

		eeprom_write_byte((unsigned char*)(&store_ee), (unsigned char)val);

		eeprom_busy_wait();
		

		eeprom_busy_wait();

		a = eeprom_read_byte((unsigned char*)(&store_ee));

		eeprom_busy_wait();
		
		PORTB = a; 
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You've already been told you don't need all the busy_wait()s in there. Remove them.

Anyway there's nothing you are doing with the EEPROM that should be having ANY effect on the read/write of 'val'.

By the way could I recommend (1<<RXC) rather than 0x80 and (1<<UDRE) rather than 0x20? I had to download the mega8515 datasheet just to check that your tx() and rx() routines were OK. If you'd used the bitnames I'd have known you were doing the right thing.

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

clawson wrote:
You've already been told you don't need all the busy_wait()s in there. Remove them.

Anyway there's nothing you are doing with the EEPROM that should be having ANY effect on the read/write of 'val'.

By the way could I recommend (1<<RXC) rather than 0x80 and (1<<UDRE) rather than 0x20? I had to download the mega8515 datasheet just to check that your tx() and rx() routines were OK. If you'd used the bitnames I'd have known you were doing the right thing.

Thanks. I modified the code with RXC & UDRE. i really don't understand what you mean here

"Anyway there's nothing you are doing with the EEPROM that should be having ANY effect on the read/write of 'val'."

Could you please give me sample code. to write into eeprom from USART received data? I removed all eeprom calls.I just wanted to see the what is there in the val varibale. I tried like this
PORTB = val;

this gives me like 0xf8,0xc0 when i press the letter a or c? ii think writing the val into eeprom is not perfect.I found the problem is not with the eeprom calls.

COULD ANYONE TELL HOW TO COPY THE USART TRANMITTED DATA INTO EEPROM. hOW TO CAPTURE THE TRANSMITTED CHARECTER?

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

Quote:

this gives me like 0xf8,0xc0 when i press the letter a or c?

Then your UART comms are not working - probably a clock speed issue.

Try to get one thing working at a time - you cannot build a house on straw foundations.

If you want to experiment with EEPROM then do an eeprom_write_byte() in the code then use your ISP proggrammer to read out the EEPROM contents and see if it worked. This doesn't rely on UART working at all.

If you want to get UART working statr by transmitting "Hello" and get that working.

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

Try the following:

int main()
{
   SCIInitialize();

   tx('a');
   tx('b');
   tx('c');
   tx('d');
         
   for(;;);

What do you receive?

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

wek wrote:
Try the following:

int main()
{
   SCIInitialize();

   tx('a');
   tx('b');
   tx('c');
   tx('d');
         
   for(;;);

What do you receive?

it is not receiving anything . I don't see anything in my hypo.
but when i do like this
int main()
{
SCIinit();
for(; ;)
{
tx(rx());
}
}
what ever i type it is echoed back on my hypo.
when i try to check through PORTB like this

int main()
{
unsigned char val;
SCIinit();
for(;;)
{
val = rx();
tx(rx());
PORTB = val ///here is gives 0x1111 1000
}
}
but when i see the hypo, it just echo back the letter which i press. why PORTB = val gives different value? Any help? i use 1MHZ, ATMEGA8515, baud rate 2400, 8 data bit ,no parity, 1 stop bit

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

clawson wrote:
Quote:

this gives me like 0xf8,0xc0 when i press the letter a or c?

Then your UART comms are not working - probably a clock speed issue.

Try to get one thing working at a time - you cannot build a house on straw foundations.

If you want to experiment with EEPROM then do an eeprom_write_byte() in the code then use your ISP proggrammer to read out the EEPROM contents and see if it worked. This doesn't rely on UART working at all.

If you want to get UART working statr by transmitting "Hello" and get that working.

yes you are correct.Here is my code to send string to hypo. I see nothing in my hypo.Could you please correct my code?

void tx(unsigned char data)
{
	while ( ( UCSRA & (1 << UDRE)) == 0);
	
	UDR = data;		
		
}


void sendstring(const  char *stringp)
{
	while(*stringp != 0)
	{
		tx(*stringp);
		stringp++;
	}
}
int main()
{
	unsigned char val , a;
	
	DDRB = 0XFF;
	PORTB = 0XFF;
	
	SCIInitialize();

	sendstring("hello");
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dolphin@gmx.com wrote:
wek wrote:
Try the following:

int main()
{
   SCIInitialize();

   tx('a');
   tx('b');
   tx('c');
   tx('d');
         
   for(;;);

What do you receive?

it is not receiving anything . I don't see anything in my hypo.

It means, your UART does not work as you expect. Most probably your clock is not as you expect, or your UART clock setting is not what you expect (I did not check). Fix that first, until you see "abcd" receiving on PC after the mcu is reset.

Don't be deceived by the echo - if you'd write something like (pseudocode):

while(1) {
  x = Rx_pin;
  Tx_pin = x;
}

you'd have a perfect echo at almost any system clock, yet no UART reception.

Btw. you should really use a crystal oscillator when you use UART.

JW

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

tHANKS FOR YOUR imeediate reply.
I changed my FCPU TO 3.69MHZ. now i can see abcd in my hypo.I can write a string to hypo.

It's just perfect now. I am going to write into eeprom.

wek wrote:
dolphin@gmx.com wrote:
wek wrote:
Try the following:

int main()
{
   SCIInitialize();

   tx('a');
   tx('b');
   tx('c');
   tx('d');
         
   for(;;);

What do you receive?

it is not receiving anything . I don't see anything in my hypo.

It means, your UART does not work as you expect. Most probably your clock is not as you expect, or your UART clock setting is not what you expect (I did not check). Fix that first, until you see "abcd" receiving on PC after the mcu is reset.

Don't be deceived by the echo - if you'd write something like (pseudocode):

while(1) {
  x = Rx_pin;
  Tx_pin = x;
}

you'd have a perfect echo at almost any system clock, yet no UART reception.

Btw. you should really use a crystal oscillator when you use UART.

JW

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

My UART IS working & I can write & read the eeprom.
But when I declare them as array I get warning.

UINT8 store_in_eeprom[10] __attribute__((section(".eeprom"))) ;

receivedByte = rx();

eeprom_write_byte((UINT8*)(store_in_eeprom + index), (UINT8)receivedByte);

Here in this line i get a warning

../main.c:51: warning: passing argument 1 of 'eeprom_write_byte' makes integer from pointer without a cast

What's wrong in this array address passing?

clawson wrote:
Quote:

this gives me like 0xf8,0xc0 when i press the letter a or c?

Then your UART comms are not working - probably a clock speed issue.

Try to get one thing working at a time - you cannot build a house on straw foundations.

If you want to experiment with EEPROM then do an eeprom_write_byte() in the code then use your ISP proggrammer to read out the EEPROM contents and see if it worked. This doesn't rely on UART working at all.

If you want to get UART working statr by transmitting "Hello" and get that working.

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

dolphin@gmx.com wrote:
eeprom_write_byte((UINT8*)(store_in_eeprom + index), (UINT8)receivedByte);

Here in this line i get a warning

../main.c:51: warning: passing argument 1 of 'eeprom_write_byte' makes integer from pointer without a cast

There is something that you are not telling us. What is UINT8? How is it defined?

And, BTW, a few more things.
- Instead of "__attribute__((section(".eeprom")))" you can simply say "EEMEM"
- Try to not use cast. Yes, there are rare cases when one might need a cast. But normally, if you define your variables correctly in the first place, you would not need it.

Eugene

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
UINT8 store_in_eeprom[10] __attribute__((section(".eeprom"))) ; 

receivedByte = rx(); 

eeprom_write_byte((UINT8*)(store_in_eeprom + index), (UINT8)receivedByte); 

Try this instead:

UINT8 store_in_eeprom[10] EEMEM; 

receivedByte = rx(); 

eeprom_write_byte(&store_in_eeprom 
), receivedByte);

You seem to be trying to make things more complicated than they actually are! It also suggests you haven't visited the tutorial forum yet - all this is explained in abcmimiuser's EEMEM article.