Sunday, 15 April 2012

c - Flow handling in interrupt driven UART - ATMEGA328P -



c - Flow handling in interrupt driven UART - ATMEGA328P -

i'm trying implement interrupt driven uart communication atmega328p. need accomplish sending commands (char arrays) on uart in order extract values variables in main routine can program behaviour in circuit.

the info i'm sending has format: 2 255 0 255 0 0 255 1000 (it's rgb led lamp) describes long int values mode, 2 rgb colors , duration.

so far have in main:

while(1) { if(rxflag==1){ char * pend; mode = strtol(buffer,&pend,10); ri = strtol (pend, &pend,10); gi = strtol (pend, &pend,10); bi = strtol (pend, &pend,10); rf = strtol (pend, &pend,10); gf = strtol (pend, &pend,10); bf = strtol (pend, &pend,10); duration = strtol (pend,null,10); rxflag=0; } switch(mode){ case 1: // fixed color fixed(rf, gf, bf); break; case 2: // yoyo pulse yoyo(ri,gi,bi,rf,gf,bf,duration); break; default:// reddish blinky fixed(0,255,255); _delay_ms(500); fixed(255,255,255); _delay_ms(500); break; } }

and isr (interrupt service routine) handles reception:

isr(usart_rx_vect) { while ( !(ucsr0a & (1<<rxc0)) ); if (rxn==80){ // if buffer_size reached, reset start of buffer. rxn=0; } buffer[rxn++] = udr0; // increment rxn , homecoming new value. if(buffer[rxn]=='\0'){ rxflag=1; // notify main of receipt of data. } }

as can see, i'm trying update variables' values when observe \0 @ end of stream.

it's (in isr):

read incoming byte , store in buffer @ 80 bytes long if \0 comes in, allow main know has new info process

in main:

if there's new data, break buffer long int , store values clear new info flag act according new values.

the problem isn't playing out wanted , i'm kinda lost. know switch statement works correctly given vars have right values. i've narrowed downwards problem either communication/buffer populating phase beingness broken or extraction of variables' values beingness broken, not sure or if both.

can share insight?

edit: had more time think this. ignore previous answer.

make sure buffer declared keyword volatile.

the fact you're wrapping without performing handling worrying. circular buffer, it's much improve maintain track of head, tail, , current size.

#define buff_max_bytes 80 #define true 1 #define false 0 typedef unsigned char boolean; static volatile unsigned char buff[buff_max_bytes]; static volatile unsigned char buffhead = 0; static volatile unsigned char bufftail = 0; static volatile unsigned char buffsize = 0; boolean store_byte(unsigned char b) { boolean success = true; if(buffsize < buff_max_bytes){ buff[bufftail] = b; buffsize++; bufftail = (bufftail + 1) % buff_max_bytes; } else{ success = false; } homecoming success; } boolean eol_received(void) { unsigned char prev_index = (bufftail == 0) ? buff_max_bytes - 1 : bufftail - 1; boolean eol = false; if(buff[prev_index] == '\0'){ eol = true; } homecoming eol; } // because strtol has no conception of buffer ends , wraps, // have create modified version can handle case. // // simple approach calculate length of message, re-create // buffer parsing (advancing buffhead read bytes), // , phone call strtol on new buffer. isr(usart_rx_vect) { while ( !(ucsr0a & (1<<rxc0)) ); if(!store_byte(udr0)){ // utilize flag inform main() of overflow, handle appropriate } rxflag = eol_received() ? 1 : 0; }

c arrays interrupt uart strtol

No comments:

Post a Comment