mikt data in een buffer: wat/waar is die buffer ?
Nou eh... gewoon een stukkie RAM van die controller? Waar wil je het anders laten?
ik schrijf het nu meteen in de ext. RAM
Dat is dus erg onhandig en vragen om problemen. Zeker vanuit een ISR
na buffer full (300 bytes) mag de rest worden weggegooid.
En hoe weet je dan dat je de juist 300 bytes hebt? ZO simpel is het dus niet.
en dat mag dus niet in de ISR, ik moet dan buiten de ISR de data in de ext. RAM schrijven ?
Van mij wel hoor. Maar... OF je maakt je ISR 'rete snel' en laat 'm geen rare dingen doen. Dan hoef je er (bijna) niet over na te denken. OF je doet alles in de ISR, MAAR dan moet je na gaan denken over timing en andere interrupts die niet afgehandeld worden in de tijd dat jij met die RAM staat te pielen. Alhoewel de laatste niet onmogelijk is (ja, ik heb het ook wel eens gedaan), moet je wel verduveld goed snappen wat je aan het doen bent. Met alle respect: als ik je vragen zo zie, ben jij daar nog lang niet. (geeft niks, ik was er ook niet in de eerste week dat ik met interrupts werkte hoor)
en dat is dus wat ik nu doe ?
Je haalt nu gewoon 300 bytes binnen. Zijn het er 301... eh? Zijn het er 299... eh... En valt er onderweg een bit om... eh... Stap af van het concept '300 bytes'. Er komt gewoon data binnen op die UART. En het zou kunnen dat die 300 bytes die jij hebben wilt daar tussen zitten. DAT is de juiste benadering. Ofwel: input bekijken tot je iets tegen komt waarvan je denkt... Hmz... dit zou wel eens voor mij kunnen zijn. Kijken of het klopt. En DAN ga je er eens wat mee doen.
Als je variabelen test of manipuleert in twee threads heb je daar een mutex voor nodig (of het moet met een atomic operation). In jouw geval heb je de main code en de interrupt routine. (Voor een 8bit mcu is de oplossing vaak: disable ints, test variable, enable ints).
Je kunt overdrijven he... Een 8-bit compare is atomair. Dus dat gaat altijd wel goed. Een 16-bits compare wordt al een ander paar mouwen.
@Arco: bij een AVR gaat 'de volgende' interrupt nog goed. Zolang die maar niet dezelfde source heeft Maar in essentie zie ik het ook zo.
[edit]
Concept van een stukkie code wat NMEA strings binnen lepelt. Helaas een stuk bestaande hardware wat ff voor een ander doel gebruikt moet worden met een wat 'krappe' controller, dus ff trucen: niet genoeg ram om het eerst fatsoenlijk te bufferen en eruit te lepelen wat ik hebben wil...
De ISR in pseudo code:
code:
c=getFromUART
if ('$' == c) (daar begint een NMEA string mee)
{
stringReady = 0;
weAreReading = 1;
charInBuff = 0;
} else if (CR == c ) (dat is bruikbaar als terminator)
{
stringReady = 1;
weAreReading = 0;
}
else
{
if (( charInBuff < MAX ) && (0 != weAreReading ))
{
buff[charInBuf] = c;
charInBuff++;
}
}
In de main kijk je naar stringReady en zodra die 1 is, moet je als je raket wat doen met die string (en daarna StringReady 0 maken). Dit gaat goed, omdat
- NMEA data 'traag' binnen komt. Als je main te traag is in deze variant, zul je daar wat mee moeten
- Mocht je een keer wat missen, dan is het geen drama. Alles wat van belang is (in deze context) komt elke seconde binnen. Mis je wat... nou ja, het komt zo weer voorbij
- Je kunt evt. ook nog een beetje filtering in je ISR doen. Als je bijvoorbeeld alleen GPRMC wilt hebben, dan kun je kijken of die ook binnen komen en zo nee, dan al afbreken. Je ISR wordt wel steeds groter en complexer.
Kortom: dit is een beetje 'wonky', maar voor het doel werkt het uitsteekbaar.