Tips på kodsnutt för att ta emot en sträng
-
- EF Sponsor
- Inlägg: 2109
- Blev medlem: 27 augusti 2005, 20:57:58
- Ort: Borlänge
Tips på kodsnutt för att ta emot en sträng
Har någon nåt tips på en kodsnutt för att lagra en sträng med data som tas emot från uarten. Tex om jag skickar "hejsan" från ett terminalprogram från en PC vill jag lagra denna i en array i uC'n. Jag använder Atmega 128 och avr-gcc och har enablat interupt (ISR(USART0_RX_vect)). Att ta emot tecken fungerar bra men kommer inte riktigt på hur jag ska lagra en hel sträng.
-
- EF Sponsor
- Inlägg: 2109
- Blev medlem: 27 augusti 2005, 20:57:58
- Ort: Borlänge
Nej, i interrupten (för visst körde du interruptstyrt?) får du tecknet i UDR, så du lägger bara det som finns i UDR på "nästa lediga plats" i din array.
EDIT: lade till en liten kodsnutt som bör funka, se Atmels appnote avr306 för mera kod.
EDIT2: observera att min interruptrutin är för iccavr, du får byta ut till gcc's namn på usartinterrupten.
EDIT: lade till en liten kodsnutt som bör funka, se Atmels appnote avr306 för mera kod.
Kod: Markera allt
#pragma interrupt_handler twi_isr:18
void twi_isr(void)
{
unsigned char data;
unsigned char tmphead;
data = UDR;
/* calculate buffer index */
tmphead = ( UART_RxHead + 1 ) & UART_RX_BUFFER_MASK;
UART_RxHead = tmphead; /* store new index */
if ( tmphead == UART_RxTail )
{
/* ERROR! Receive buffer overflow */
}
UART_RxBuf[tmphead] = data; /* store received data in buffer */
}
-
- EF Sponsor
- Inlägg: 2109
- Blev medlem: 27 augusti 2005, 20:57:58
- Ort: Borlänge
Tack nu funkar det. Min tanke var om det gick att stanna i interruptet tills alla tecken var mottagna men det kanske inte går/är dumt? Vill lagra strängen i en tvådimensionell array (sSMS) så jag vill även öka index med ett när en sträng är mottagen, men det går väl att lösa på nåt annat vis.
Koden:
ISR(USART0_RX_vect)
{
sTemp[counter] = UDR0;
counter++;
strcpy(sSMS[0],sTemp);
numberOfSMS = 1;
}
Koden:
ISR(USART0_RX_vect)
{
sTemp[counter] = UDR0;
counter++;
strcpy(sSMS[0],sTemp);
numberOfSMS = 1;
}
-
- EF Sponsor
- Inlägg: 2109
- Blev medlem: 27 augusti 2005, 20:57:58
- Ort: Borlänge
Att den måste vara nullterminerad visste jag inte men det låter ju logiskt nu när du säger det. Att den kopieras varje gång är jag medveten om, ville bara kolla om det funka. Om man nu vill kopiera och öka index när en sträng är mottagen, något tips på hur man kan göra. Jag kommer bara skicka en sträng då och då. Ska man sätta en "flagga" i interuptet som man kollar av då och då i huvudprogrammet eller hur göra?
Kod: Markera allt
typedef unsigned char byte;
#pragma interrupt_handler twi_isr:18
void twi_isr(void)
{
byte Data;
static byte Index = 0;
Data = UDR; // Read incoming char
if(Index >= UART_RxTail)
{ // Trying to fill in too muck, flag for error
/* ERROR! Receive buffer overflow */
}
else
{ // All is well, put in buffer
UART_RxBuf[Index++] = data; // store received data in buffer
UART_RxBuf[Index] = 0; // Terminate string
}
}
Det här borde väl göra vad du vill.
edit: Koden förutsätter att texten som skickas via UART:en är nullterminerad. Startvärdet för numberOfSMS bör vara 0.
Kod: Markera allt
ISR(USART0_RX_vect)
{
static uint8_t counter = 0;
if (counter >= sizeof(sTemp))
{
// Bufferten full
}
else
{
sTemp[counter] = UDR0;
if (sTemp[counter] == '\0')
{
strcpy(sSMS[numberOfSMS++], sTemp);
counter = 0;
}
else
counter++;
}
}
Senast redigerad av cykze 31 maj 2006, 21:39:18, redigerad totalt 2 gånger.
-
- EF Sponsor
- Inlägg: 2109
- Blev medlem: 27 augusti 2005, 20:57:58
- Ort: Borlänge
> Min tanke var om det gick att stanna i interruptet tills alla tecken var mottagna...
Generellt (oavsett om det är AVR, PIC eller något annan processor) är det
en dålig ide, om det inte är väldigt snabb kommunikation (alltså inget
som en UART klarar av).
En ISR ska inte göra mer än vad som absolut *måste* göras just i ISR'en...
Generellt (oavsett om det är AVR, PIC eller något annan processor) är det
en dålig ide, om det inte är väldigt snabb kommunikation (alltså inget
som en UART klarar av).
En ISR ska inte göra mer än vad som absolut *måste* göras just i ISR'en...