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

[Atmega16][AVR-GCC]Błąd inkrementacji

wiewiur667 28 Lut 2010 19:11 1376 6
  • #1 7765017
    wiewiur667
    Poziom 10  
    Napisałem prosty program obsługujący 4 połączone wyświetlacze 7-segmentowe.
    Program ma inkrementować zmienną a i przypisywać ją zmiennej numer lecz nie wiem z jakiego powodu inkrementajca odbywa się w sposób geometryczny(2,4,8...), do tego if który powinien resetować pętle tego nie robi.
    Pracuje na AVR Studio 4(najnowsze winavr) i Proteus 7 do symulacji.

    
    #define F_CPU 8000000
    #include <avr/io.h>
    #include <util/delay.h>
    
    
    int pos_tab[]={0,0,1,0,0,1,1,1};
    //				0		1			2		3			4		5			6		7			8		9
    int liczba[]={0,0,0,0 , 1,0,0,0 , 0,1,0,0 , 1,1,0,0 , 0,0,1,0 , 1,0,1,0 , 0,1,1,0 , 1,1,1,0 , 0,0,0,1 , 1,0,0,1};
    
    int main()
    {
    	int a;
    	int pos,numer;
    	
    	
    	
    	DDRD=0xff;
    	DDRC=0xff;
    	PORTD=0x00;
    	PORTC=0x00;
    	a=0;
    	
    	while(1)
    	{	
    	
    	numer=a;// liczba
    	
    	pos=0;	// pozycja
    	
    	PORTC|=(pos_tab[pos*2]<<1)|(pos_tab[(pos*2)+1]<<2)|(liczba[numer*4]<<3)|(liczba[(numer*4)+1]<<4)|(liczba[(numer*4)+2]<<5)|(liczba[(numer*4)+3]<<6);
    	_delay_ms(200);
    	a++;
    	if(a>9){a=0;}
    	
    	}
    	
    	
    
    
    }
    
  • #2 7765205
    michalko12
    Specjalista - Mikrokontrolery
     pos=0;   // pozycja
       
       PORTC|=(pos_tab[pos*2]<<1)|(pos_tab[(pos*2)+1]<<2)|(liczba[numer*4]<<3)|(liczba[(numer*4)+1]<<4)|(liczba[(numer*4)+2]<<5)|(liczba[(numer*4)+3]<<6); 


    Zastanów się co robisz.

    (pos_tab[pos*2]<<1)|(pos_tab[(pos*2)+1]<<2)


    Jak myślisz ile będzie wynosiło pos*2 przy kolejnych przejściach pętli?

    Jak myślisz kiedy jakikolwiek pin portu C przyjmie wartość "0"?

    Przekombinowałeś. Lepiej pokaż schemat i napisz jaki chcesz uzyskać rezultat.
  • #3 7765214
    gadula88
    Poziom 15  
    Na początku zacznij od poinformowania kompilatora, żeby uważał na zmienną. Robi się to przez dopisanie volatile przed deklaracją zmiennej.
  • #4 7765247
    michalko12
    Specjalista - Mikrokontrolery
    gadula88 napisał:
    Na początku zacznij od poinformowania kompilatora, żeby uważał na zmienną. Robi się to przez dopisanie volatile przed deklaracją zmiennej.


    A na która zmienną ma tu "uważać"? Chyba nie bardzo rozumiesz jaką funkcję ma kwalifikator volatile.
  • #6 7765307
    wiewiur667
    Poziom 10  
    Skoro przy każdym przejściu pętli ustawiam pos=0 to wydaje mi się że powinien przyjmować 0 w tym wypadku. Chodzi mi głównie o to że "numer" powinien wyświetlać się po kolei(1,2,3) a nie z takimi przeskokami, bo w każdej innej funkcji inkrementacja działa poprawnie i tylko nie mogę dojść w czym problem jest z tą zmienną a.
    [Atmega16][AVR-GCC]Błąd inkrementacji

    Dodano po 3 [minuty]:

    Krauser napisał:
    Przed musisz go wyzerować.

    Dzięki Krauser wystarczyło usunąć "|" i wszystko działa poprawnie. Nie przypuszczałem że w tym może być problem.

    Do zamknięcia.
  • #7 7765486
    michalko12
    Specjalista - Mikrokontrolery
    wiewiur667 napisał:
    Skoro przy każdym przejściu pętli ustawiam pos=0 to wydaje mi się że powinien przyjmować 0 w tym wypadku. Chodzi mi głównie o to że "numer" powinien wyświetlać się po kolei(1,2,3) a nie z takimi przeskokami, bo w każdej innej funkcji inkrementacja działa poprawnie i tylko nie mogę dojść w czym problem jest z tą zmienną a.

    Do zamknięcia.


    Masz ciekawy sposób na komplikowanie sobie życia

    void WyswietlCyfre(unsigned char liczba, unsigned char pos)
    {
    
    	PORTC &= 0x80;
    	PORTC |= ((liczba & 0x0F) << 3) | ((pos & 0x03) << 1);
    }


    A temat sam zamykasz.
REKLAMA