[avr-gcc] Zapis do eeprom - problem

May 07, 2007 1 Replies

Witam, Otó¿ pisze program na ATmega32 i mam problem z zapisem do eepromu (AT24C08-SMD), odczyt jest ³adny. I mam tak: Struktura która trzyma 3 kody: <code>



typedef struct { uint8_t length_on; uint8_t code_on[8]; uint8_t length_off; uint8_t code_off[8]; uint8_t length_m2; uint8_t code_m2[8]; uint8_t f_key; uint8_t time; } EE_OUTPUT_CODE; // Globalna deklaracja - "main.c" EE_OUTPUT_CODE g_out_code; </code>



Struktura ma 29bajtów (w pamiêci eeprom zaaokr±glam do 32 bajtów - ³atwiej siê liczy :)) ) ,a takich rekordów jest 16 i s± one trzymane na 2 stronach (512bajtów).



I wszystko jest ³±dnie do momentu zapisu, niby zapis jest ok gdy¿ dane mi siê nie zmieniaj± w rekordzie przed i po zapisie ale do eepromu trafiaj± bzdury.. I tak wygl±da "log" : <code>



SelectedOut=00 tmp=08 ic_ee_adr=A8 Write OUT Code - przed zapisem: DEBUG OUTPUT CODE:



-------------- out_code: len_on=03 code_on=[0]07[1]00[2]01[3]FF[4]FF[5]FF[6]FF[7]FF len_off=03 code_off=[0]07[1]00[2]02[3]FF[4]FF[5]FF[6]FF[7]FF len_m2=03 code_m2=[0]07[1]00[2]03[3]FF[4]FF[5]FF[6]FF[7]FF f_key=01 time=0F



************************************ SelectedOut=00 tmp=08 ic_ee_adr=A8 Write OUT Code - po zapisie: DEBUG OUTPUT CODE:

-------------- out_code: len_on=03 code_on=[0]07[1]00[2]01[3]FF[4]FF[5]FF[6]FF[7]FF len_off=03 code_off=[0]07[1]00[2]02[3]FF[4]FF[5]FF[6]FF[7]FF len_m2=03 code_m2=[0]07[1]00[2]03[3]FF[4]FF[5]FF[6]FF[7]FF f_key=01 time=0F



************************************ </code>


I po tym odczyt rekordu z pamiêci:



<code>

SelectedOut=00 Code Out Id=00



Read Output Settings: DEBUG OUTPUT CODE:



-------------- out_code: len_on=FF code_on=[0]FF[1]03[2]07[3]00[4]03[5]FF[6]FF[7]FF len_off=FF code_off=[0]FF[1]01[2]0F[3]FF[4]FF[5]FF[6]FF[7]FF len_m2=FF code_m2=[0]FF[1]FF[2]FF[3]FF[4]FF[5]FF[6]FF[7]FF f_key=FF time=FF



************************************ </code>


Procedura odczytu jest dobra gdy¿ mam ju¿ napisan± funkcjê sprawdzaj±c± odczytany kod i porównuj±c± z wporwadzonym z klawiatury.


Kod procedury zapisu do eepromu: <code>



void Write_EE_OUT_Code(uint8_t out) { uint8_t addr, tmp, tmp2, page_offset;



if (out > 7) { // strona 2 addr = (out-8) * 32; page_offset = 2; } else { // out < 8 addr = out * 32; page_offset = 0; } /* typedef struct { uint8_t length_on; uint8_t code_on[8]; uint8_t length_off; uint8_t code_off[8]; uint8_t length_m2; uint8_t code_m2[8]; uint8_t f_key; uint8_t time; } EE_OUTPUT_CODE; */ #if _DEBUG_MSG == 1 // je¶li program jest z opcj± debugowania to wypluj dane: usart_SendStrP((prog_char*)PSTR("SelectedOut=")); SendHexCharByte(out); usart_SendStrP((prog_char*)PSTR(" tmp=")); SendHexCharByte(tmp); usart_SendStrP((prog_char*)PSTR(" ic_ee_adr=")); SendHexCharByte(IC_EEPROM_ADDR+page_offset); usart_SendStrP((prog_char*)PSTR("\n\r")); DialogDebugOutCode(&g_out_code,(prog_char*)PSTR("Write EE OUT Code - przed zapisem:\n\r")); // DialogDebugOutCode(&g_out_code,(prog_char*)PSTR("...")); - ta funkcja rozk³ada strukturê i wypluwa ja w "ludzkim jêzyku" przez rs'a #endif BUZ_ON; i2c_start(); i2c_send(IC_EEPROM_ADDR+page_offset); // 1,2 strona - kody 32bajtowe i2c_send(addr); // adres pocz±tkowy // CODE_ON i2c_send((uint8_t)(g_out_code.length_on)); // d³ugo¶æ code_on for (tmp2=0;tmp2<8;tmp2++) { i2c_send((uint8_t)(g_out_code.code_on[tmp2])); // 8 cyfr CODE_ON } // CODE_OFF i2c_send(g_out_code.length_off); // d³ugo¶æ code_off for (tmp2=0;tmp2<8;tmp2++) { i2c_send(g_out_code.code_off[tmp2]); // 8 cyfr CODE_OFF } // CODE_M2 i2c_send(g_out_code.length_m2); // d³ugo¶æ code_m2 for (tmp2=0;tmp2<8;tmp2++) { i2c_send(g_out_code.code_m2[tmp2]); // 8 cyfr CODE_M2 } // F_Key i2c_send(g_out_code.f_key); // czas _M2 i2c_send(g_out_code.time); // czas dzia³ania code_M2 i2c_stop();



#if _DEBUG_MSG == 1 usart_SendStrP((prog_char*)PSTR("SelectedOut=")); SendHexCharByte(out); usart_SendStrP((prog_char*)PSTR(" tmp=")); SendHexCharByte(tmp); usart_SendStrP((prog_char*)PSTR(" ic_ee_adr=")); SendHexCharByte(IC_EEPROM_ADDR+page_offset); usart_SendStrP((prog_char*)PSTR("\n\r")); DialogDebugOutCode(&g_out_code,(prog_char*)PSTR("Write EE OUT Code - po zapisie:\n\r")); #endif



BUZ_OFF; } </code>


I tak siedze ju¿ nad tym i mêcze i dogryz³em siê i¿ jakim¶ cudem eeprom nie odbiera poprawnie pierwszych dwóch bajtów danych (np. length_on powinien mieæ 3 ,a z eepromu odczytuje FF, i taki sam wynik odczytu z eepromu drugiej komórki (z addr=01) zamiast 7 mam te¿ FF) , nawet doda³em weryfikacje zapisu (sygnalizuje te¿ b³±d)... Sprawdza³em na dwóch ko¶ciach.

Te same procedry zapisu do eepormu mam w programatorze RS-EERPOM_I2C i dzia³aj± (zapis bajtu jak i wielozapis).

Teraz tak napisa³em i nie mam ju¿ pomys³u jak to napisaæ aby zadzia³a³o: Mo¿e b³±d jednak le¿y w pliku i2c.c? ... (w co nie specjalnie uwierze gdy¿ inne procesory z tymi samymi f. steruj±cymi i2c dzia³±j± od d³u¿szego czasu)

<code>

void WriteOutputSettings(uint8_t _out,IN_CODE *Code_on, IN_CODE

*Code_off,IN_CODE *Code_m2, uint8_t _time, uint8_t _key) { uint8_t tmp; uint8_t chip_addr, mem_addr; // przekopiowanie do zmiennej kodów ze wska¼ników for (tmp=0;tmp<8;tmp++) { g_out_code.code_on[tmp] = Code_on->digit[tmp]; g_out_code.code_off[tmp] = Code_off->digit[tmp]; g_out_code.code_m2[tmp] = Code_m2->digit[tmp]; }

g_out_code.length_on = Code_on->length; g_out_code.length_off = Code_off->length; g_out_code.length_m2 = Code_m2->length; g_out_code.time = _time; g_out_code.f_key = _key;

#if _DEBUG_MSG == 1 usart_SendStrP((prog_char*)PSTR("Code Out Id=")); SendHexCharByte(_out); usart_SendStrP((prog_char*)PSTR("\n\r")); DialogDebugOutCode(&g_out_code,(prog_char*)PSTR("Write Output Settings:\n\r")); #endif

//Write_eeprom_few_bytes(uint8_t chip_addr, uint8_t st_adr, uint8_t *data, uint8_t bytes) //Write_eeprom_byte(uint8_t chip_addr, uint8_t adr, uint8_t data) if (_out > 7) { // strona 2 mem_addr = (_out-8) * 32; chip_addr = IC_EEPROM_ADDR+2; } else { // out < 8 mem_addr = _out * 32; chip_addr = IC_EEPROM_ADDR+0; } /* typedef struct { uint8_t length_on; // offset=0 uint8_t code_on[8]; // offset=1-8 uint8_t length_off; // offset=9 uint8_t code_off[8]; // offset=10-17 uint8_t length_m2; // offset=18 uint8_t code_m2[8]; // offset=19-26 uint8_t f_key; // offset=27 uint8_t time; // offset=28 } EE_OUTPUT_CODE; */

#if _DEBUG_MSG == 1 usart_SendStrP((prog_char*)PSTR("\n\r mem_addr_begin=")); SendHexCharByte(mem_addr); usart_SendStrP((prog_char*)PSTR("\n\r chip_addr=")); SendHexCharByte(chip_addr); #endif // Zapis length_on Write_eeprom_byte(chip_addr,mem_addr,g_out_code.length_on); Write_eeprom_byte(chip_addr,mem_addr,g_out_code.length_on); // próba podwójnego zapisu komórki nie pomaga :/ // zapis code_on[8] mem_addr++; // incr mem_address Write_eeprom_few_bytes(chip_addr,mem_addr,&(g_out_code.code_on),8); // 8 bajtów Write_eeprom_few_bytes(chip_addr,mem_addr,&(g_out_code.code_on),8); // 8 bajtów // zapis length_off mem_addr += 8; // przesuñ o 8 bajtów Write_eeprom_byte(chip_addr,mem_addr,g_out_code.length_off); // zapis code_off mem_addr++; Write_eeprom_few_bytes(chip_addr,mem_addr,&(g_out_code.code_off),8); // 8 bajtów // zapis length_m2 mem_addr += 8; // przesuñ o 8 bajtów Write_eeprom_byte(chip_addr,mem_addr,g_out_code.length_m2); // zapis code_m2 mem_addr++; Write_eeprom_few_bytes(chip_addr,mem_addr,&(g_out_code.code_m2),8); // 8 bajtów // zapis f_key mem_addr += 8; // przesuñ o 8 bajtów Write_eeprom_byte(chip_addr,mem_addr,g_out_code.f_key); // zapis time mem_addr++; Write_eeprom_byte(chip_addr,mem_addr,g_out_code.f_key);

//Write_EE_OUT_Code(_out); }

void Write_eeprom_byte(uint8_t chip_addr, uint8_t adr, uint8_t data) { /* typedef struct { uint8_t length_on; uint8_t code_on[8]; uint8_t length_off; uint8_t code_off[8]; uint8_t length_m2; uint8_t code_m2[8]; uint8_t f_key; uint8_t time; } EE_OUTPUT_CODE; */ #if _DEBUG_MSG == 1 usart_SendStrP((prog_char*)PSTR("\n\r-- WRITE EEPROM BYTE --\n\r")); usart_SendStrP((prog_char*)PSTR("ChipAdress=")); SendHexCharByte(chip_addr); usart_SendStrP((prog_char*)PSTR("\n\r Address=")); SendHexCharByte(adr); usart_SendStrP((prog_char*)PSTR("\n\r data=")); SendHexCharByte(data); #endif BUZ_ON;

i2c_start(); i2c_send(chip_addr); // 1,2 strona - kody 32bajtowe i2c_send(adr); // adres pocz±tkowy i2c_send(data); // bajt i2c_stop();

delay1ms8(5); // wait 5ms

#if _DEBUG_MSG == 1

usart_SendStrP((prog_char*)PSTR("\n\r--------------------------------------

------ \n\r")); #endif

BUZ_OFF; }

void Write_eeprom_few_bytes(uint8_t chip_addr, uint8_t st_adr, uint8_t

*data, uint8_t bytes) { uint8_t dta, tmp; /* typedef struct { uint8_t length_on; uint8_t code_on[8]; uint8_t length_off; uint8_t code_off[8]; uint8_t length_m2; uint8_t code_m2[8]; uint8_t f_key; uint8_t time; } EE_OUTPUT_CODE; */ #if _DEBUG_MSG == 1 usart_SendStrP((prog_char*)PSTR("\n\r-- WRITE EEPROM FEW BYTES --\n\r")); usart_SendStrP((prog_char*)PSTR("ChipAdress=")); SendHexCharByte(chip_addr); usart_SendStrP((prog_char*)PSTR("\n\r StartAddress=")); SendHexCharByte(st_adr); #endif BUZ_ON;

i2c_start(); i2c_send(chip_addr); // 1,2 strona - kody 32bajtowe i2c_send(st_adr); // adres pocz±tkowy for (tmp=0;tmp<bytes;tmp++) { dta = *(data+tmp); i2c_send(dta); // bajt #if _DEBUG_MSG == 1 usart_SendStrP((prog_char*)PSTR("\n\r data[offset:")); usart_SendDec(tmp); usart_SendStrP((prog_char*)PSTR("]=")); SendHexCharByte(dta); #endif } i2c_stop();

delay1ms8(5);

BUZ_OFF; #if _DEBUG_MSG == 1

usart_SendStrP((prog_char*)PSTR("\n\r--------------------------------------

------ \n\r")); #endif } </code>

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required