logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[c] Jak używać funkcji itoa do konwersji bajtów na kod hex w AVR?

kasprzak 25 Gru 2010 12:36 1487 3
REKLAMA
  • #1 8910498
    kasprzak
    Poziom 10  
    Posty: 61
    Ocena: 7
    Mam ciągle problem z funkcją itoa. Chyba nie do końca wiem jak sie nią posługiwać.
    Chciałbym odczytane bajty zapisać jako kod w hexie, żeby potem stworzyć jakieś funkcje do obsługi tych kodów. Muszę mieć rozgraniczenie na poszczególne bajty, żeby wyciągać charakterystyczne części tylko. Zdarza się że pilot którego muszę obsłużyć ma początek bajtu inny, ale zawiera pewne elementy zawsze charakterystyczne.

    Dodam, że zaczynam dopiero zabawę z obsługą AVR, a dawno nie programowałem więc błędy w kodzie będą na pewno, ale męczę się strasznie z tym, a to przecież wygląda na taki banał. Rozwiązań z ir, tsop, itoa jest sporo, ale żadne z zastosowanych nie pomogło.

    Nie wiem jeszcze czy itoa musi być w głównej pętli, tutaj też może powodować komplikacje.


    
    #include "main.h"
    #include "lcd.h"
    #include "stdlib.h"
    //-----------------------------------
    // IR frame settings
    //-----------------------------------
    #define MAX_FRAME_LEN 16	// maximum bytes to be stored in a single frame
    #define CTR_TIMER_TICKS 23	// clock ticks for timer0 (1024 prescalled) after frame is cleared
    uint16_t j; 				// bit index in a byte
    uint8_t k; 					// byte count
    uint8_t b;  				// current byte code
    char buf[MAX_FRAME_LEN+1]; 	// frame buffer
    unsigned char ir_code;
    unsigned char ir_firstByte;
    unsigned char ir_secondByte;
    unsigned char ir_thirdByte;
    unsigned char ir_fourthByte;
    
    //-----------------------------------------------------------------------
    // INTERRUPT SERVICES
    //-----------------------------------------------------------------------
    //-----------------------------------
    // INT0 routine
    // triggered on any pin change 
    ISR(INT0_vect)
    {	
    _delay_us(800); // wait till end of a half bit (it will last for 0.864ms)
    
    	if (j == 8) // full byte was received
    	{
    		if (k < MAX_FRAME_LEN) buf[k] = b; // put the byte into the buffer
    		b = 0; // reset byte code
    		j = 0; // reset bit index
    		k++; // increase frame length
    	}	
    	else // not full byte was received
    	{
    		
    		if (PIND & 0b00000100) b |=  1 << j; // append current bit into the byte code  
    	}
    
    	j++; // increate bit intex
    
    	TCNT0 = 0; // reset time control 
    
    }
    //-----------------------------------
    // timer 0 compare vector
    // will occur every 5.46ms for 12MHz Quartz and 256 prescalling
    ISR(TIMER0_COMP_vect)
    {
    	// Next pulse came too late (it must be a distortion)
    
    	j=0; // reset all variables
    	k=0;
    	b=0;
    	TCNT0 = 0;
    }
    //-----------------------------------------------------------------------
    // REGULAR ROUTINES
    //-----------------------------------------------------------------------
    char GetKey()
    {
    	char rkey = PINB & 0x01F;
    	
    	switch(rkey)
    	{
    		case S3: return 1;
    		case S6: return 2;
    		case S9: return 3;
    		case S2: return 4;
    		case S5: return 5;
    		case S8: return 6;
    		case S1: return 7;
    		case S4: return 8;
    		case S7: return 9;
    		case ENTER: return 10;
    	} // switch 
    
     return 0;
    }
    //-----------------------------------
    int main() // main loop starts here 
    {
    
    PORTA = 0x0;
    DDRA = 0x1F;
    PORTB = 0x00;
    DDRB = 0x0F;
    DDRC = 0xFF;
    
    PORTD = 0x80;
    DDRD = 0x80;
    
    PORTC = 0xff;
    
    _delay_ms(300);
    lcdInit();
    
    _delay_ms(300);
    
    //--------------------------------------------
    // Cunfigure the interrupt system 
    //--------------------------------------------
    cli();
    
    MCUCR |= (1 << ISC00); 		// make INT0 sens any pin change
    GICR |= (1 << INT0);		 // set INT0 as interrupt source
    
    TCCR0 = (1 << CS02) | (1 << CS00); 		// make 1024 prescalling
    TIMSK = 1 << OCIE0; 					// use timer 0 compare as interrupt source
    OCR0 = CTR_TIMER_TICKS;  				// set clock ticks to compare register
    
    sei();
    //--------------------------------------------
    
    // reset variables
    j = 0; 
    k = 0;
    b = 0;
    
    
    
    while (1)  // main loop 
    {
    	if(buf[0] && buf[1] !=0){
    		itoa(buf[0],ir_firstByte,16);
    		itoa(buf[1],ir_secondByte, 16);
    		itoa(buf[2],ir_thirdByte, 16);
    		itoa(buf[3],ir_fourthByte, 16);
    
    		strcat(ir_code, ir_firstByte);
    		strcat(ir_code, ir_secondByte);
    		strcat(ir_code, ir_thirdByte);
    		strcat(ir_code, ir_fourthByte);
    		}
    
    	// show the status
    	lcdGotoXY(0,0);
    	lcdPrintStr("Kod:");
    	lcdPrintStr(ir_code);
    
    	// reset variables if needed	
    	if (GetKey())
    	{
    		 j = 0;
    		 k = 0;
    		 b = 0;
    		 buf[0] = 0x00;
    	}
    	_delay_ms(300);
    } 
    
    	return 0;
    }
    


    dodam, że jak wywołam w głównej pętli while
    lcdPrintStr(buf);

    to wyświetla zawartość bufora, czyli to co odebrał od pilota.
  • REKLAMA
  • #2 8910690
    ginar
    Poziom 21  
    Posty: 595
    Pomógł: 26
    Ocena: 34
    Cytat:
    itoa(buf[0],ir_firstByte,16);

    http://www.cplusplus.com/reference/clibrary/cstdlib/itoa/ gdzie jest napisane:
    Cytat:
    str should be an array long enough to contain any possible value: (sizeof(int)*8+1) for radix=2, i.e. 17 bytes in 16-bits platforms and 33 in 32-bits platforms.


    jest u ciebie zadeklarowanie jako a powinno pomieścić także znak NULL.
    unsigned char ir_firstByte 
    spróbuj zamienić na
    unsigned char ir_firstByte [2]
    . Tyczy się to pozostałych części ir_xByte
  • REKLAMA
  • #3 8910720
    sulfur
    Poziom 24  
    Posty: 617
    Pomógł: 92
    Ocena: 14
    Nie czytałem całości, ale 8-bitowa zmienna zajmie 3 znaki w reprezentacji hexadecymalnej (wliczając NULL terminator). Prawdopodobnie zatem prawidłowe będzie
    unsigned char ir_firstByte [3]
  • #4 8910787
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    Tylko skąd wyczarowaliście to unsigned do tekstu? Warningi kompilatora oczywiście jak zwykle zignorowane, no bo kto by to czytał... A jak coś nie działa, to na pewno nie ma nic wspólnego z warningami...

    4\/3!!
REKLAMA