eeprom_write_byte() vs. mjukvaru UART

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
FS
Inlägg: 245
Blev medlem: 14 januari 2005, 23:35:45

eeprom_write_byte() vs. mjukvaru UART

Inlägg av FS »

I min ATtiny45 har jag en mjukvaru UART som rullar konstant och tar emot värden utifrån och lagrar i en buffert. "Sammtidigt" skulle jag vilja skriva saker mha. eeprom_write_byte() till EEPROMet. Dock fungerar eeprom_write_byte() inte ihop med (mjukvaru) UARTen. Antar att den inte gillar att det kommer en del interrupt etc...

Om jag kör utan UARTen fungerar eeprom_write_byte() klanderfritt.

Vad är det som gör att eeprom_write_byte() från avr/eeprom.h inte fungerar ihop med mina interrupt?
Användarvisningsbild
oJsan
EF Sponsor
Inlägg: 1541
Blev medlem: 11 november 2005, 21:36:51
Ort: Umeå
Kontakt:

Inlägg av oJsan »

Vilka interrupt då? Mjukvaru-UART:en har väl inga avbrott som kan tänkas störa eeprom-skrivningen, (och tvärtom). Möjligtvis så ta eeprom-skrivningen för lång tid, så att mjukvaru-UART:en missar ett eller flera tecken...
Alltså vilken del är det som slutar fungera, och vad innebär det rent konkret när du skriver "sluta fungera".
FS
Inlägg: 245
Blev medlem: 14 januari 2005, 23:35:45

Inlägg av FS »

Min mjukvaru-UART använder såväl timer som externt interrupt. Denna rutin är hemsnickrad och fungerar utmärkt.

Felet som yttrar sig är att inga bytes skrivs till eepromet. Dvs eeprom_write_byte() fungerar ej om min mjukvaru-UART ligger i väntläge för att ta emot data.
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Inlägg av exile »

Det är svårt att veta vad som är fel då man inte ser hela koden.
Det kan vara en tanke miss eller liknade ^.^
FS
Inlägg: 245
Blev medlem: 14 januari 2005, 23:35:45

Inlägg av FS »

Nu ser jag att tinyn lyckas skriva: FF:00:D0 av inkommna FF:00:02:82:4C:D0, samma missade bytes varje gång...

Hur lång tid tar en skrivning till EEPROMet? Vad händer om det kommer ett interrupt när man kör eeprom_write_byte(), avbryts detta genast?
FS
Inlägg: 245
Blev medlem: 14 januari 2005, 23:35:45

Inlägg av FS »

Har läst på ytterligare i databladet till tiny45:an och det står en del intressanta saker på sid 12...

Där menar de att man ska köra cli() och stänga av alla interrupt inför några tidskritiska kommandon. Dock verkar det som om man då får använda deras exempel på sid 19 och lägga till cli() istället för att använda eeprom_write_byte() från avr/eeprom.h.

Om man nu gör enligt ovan, finns det inte en risk att man missar att ta emot en inkommande byte?
Användarvisningsbild
rickeboy
Inlägg: 678
Blev medlem: 13 augusti 2003, 09:12:17
Ort: Göteborg / Karlskrona
Kontakt:

Inlägg av rickeboy »

Om du stänger av alla interrupts funkar inte din mjukvara uart... dvs risken för att du missar ngt är inte stor utan ett faktum... att skriva till eepromet tar längre tid än vad det tar att hantera inkommande bytes... kanske bättre att skriva ett kommando som skriver till eeprommet och under den tiden skickar man inte ngt får då lär det inte komma fram... och sedan återuppta möjligheten att ta emot saker... kanske skicka till baka ngt och säga att det är ok att skicka saker igen eller liknande...

en tanke...

//rickeboy
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Inlägg av exile »

Jag tror snarare att du råkar skriva över byte med uarten...
testa att skapa en fifo. ^^ delvis en buffert, kom ihåg att stänga av globala intrruptet vid läsningen av bufferten.
FS
Inlägg: 245
Blev medlem: 14 januari 2005, 23:35:45

Inlägg av FS »

Nja, andra änden av UARTen går tyvärr ej att ändra på... Datan kommer när den kommer ;)

Men hur lång tid tar det att skriva till eepromet då? En UART frame (9 bitar) @ 19200baud är ca 469us lång...
FS
Inlägg: 245
Blev medlem: 14 januari 2005, 23:35:45

Inlägg av FS »

exile skrev:Jag tror snarare att du råkar skriva över byte med uarten...
testa att skapa en fifo. ^^ delvis en buffert, kom ihåg att stänga av globala intrruptet vid läsningen av bufferten.
Missade ditt inlägg... Har du lust att utveckla ditt svar? "fifo"?

Edit: Man kanske ska köpa en JTAG ICE 2 så man kan kontrollera vad det står i minnet, men den kostar ju tyvärr en del... :roll:
Användarvisningsbild
rickeboy
Inlägg: 678
Blev medlem: 13 augusti 2003, 09:12:17
Ort: Göteborg / Karlskrona
Kontakt:

Inlägg av rickeboy »

I databladet står det hur långtid det tar för just AVR:en du använder och vid vilken klockfrekvens... skrev för en tid sen till EEPROMet på en ATTiny15 och om jag inte minns helt fel tog det en bra stund... minns dessvärre inte nu på rakarm...

//rickeboy
FS
Inlägg: 245
Blev medlem: 14 januari 2005, 23:35:45

Inlägg av FS »

1.8ms - 4ms beroende på vad man ska göra... Det är ju en evighet!

Hur löser man detta? Det måste ju finnas komersiella applikationer som har "mitt" problem. Dvs. mottagning av data som ej går att påverka, den kommer när den bäst vill samt inget stöd för hårdvaru-UART.
Användarvisningsbild
rickeboy
Inlägg: 678
Blev medlem: 13 augusti 2003, 09:12:17
Ort: Göteborg / Karlskrona
Kontakt:

Inlägg av rickeboy »

Måste du spara allt som kommer in då?
Om inte så kankse det går... men du kommer ändå missa en massa saker...

//rickeboy
Användarvisningsbild
maha
EF Sponsor
Inlägg: 1685
Blev medlem: 22 november 2005, 09:47:02
Ort: Jakobstad, Finland

Inlägg av maha »

Jo jag håller lite med rickeboy här, måste du verkligen spara ner allt i EEPROM:et? En AVR:s EEPROM är ju förhållandevis litet så det "normala" man brukar spara ner dit är väl inställningar och annat man inte vill att ska gå förlorat vid en reset.

Måste AVR:en vara så liten som en ATTiny15? En hårdvaru UART skulle ju inte vara fel alltså...

Ahaaa, Tiny15 har inget SRAM...då förstår jag att du behöver EEPROM:et.
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Inlägg av exile »

En hårdvaru uart löser inte ditt problem....
Du inte svara på frågan varför du vill använda eepromet, det finns lite olika lösningar beroden på problemet, Exempel du kan ha en spegling av eepromet i ram minnet och sedan interuptritin som uppdaterar eepromet när den hinner.
Eller använda en fifo... men det beror på vad du vill åsta komma... ^^

Fifo = First In First Out
Fifo används där man behöver buffra data av olika anledningar..

Exempel på fifo i c

Kod: Markera allt

#include <inttypes.h>

#define fifo_size 4	// måste vara av 2^n max 256
#define	fifo_mask fifo_size-1

//variabler för fifo
uint8_t	fifo_buff[fifo_size];
uint8_t	fifo_w_p = 0;
uint8_t fifo_r_p = 0;

//skriver data till bufferten
int8_t fifo_w(uint8_t data){	
	//kollar att buferten inte är full
	if ((fifo_r_p - fifo_w_p - fifo_mask) & fifo_mask){
		fifo_w_p++;
		fifo_w_p &= fifo_mask;
		fifo_buff[fifo_w_p] = data;
		return 0;	//skrivningen är utförd
	}
	return -1;	//bufferten är full
}

//läser buffern
int8_t fifo_r(uint8_t *data){
	//kollar att bufferten inte är tom	
	if (fifo_w_p - fifo_r_p){
		fifo_r_p = (fifo_r_p + 1) & fifo_mask;
		*data = fifo_buff[fifo_r_p];
		return 0;	//läsningen slut förd
	}
	return -1;
}

Jag hoppas att du hittar en lösning på problemet ^^
Skriv svar