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

Program w C. Wyświetlanie liczb na wyświetlaczach.

mlfox85 09 Sty 2009 17:55 1983 13
  • #1 5973826
    mlfox85
    Poziom 10  
    Cały program wygląda tak:
    
    #include <avr/io.h>               // dostęp do rejestrów
    #include <avr/interrupt.h>        // funkcje sei(), cli()
    #include <avr/signal.h>           // definicje SIGNAL, INTERRUPT
    
    #define tau                0x06
    #define vlicz              15
    
    volatile unsigned int licz;
    unsigned int t, a, b, c, x, y, z, w;
    
    SIGNAL (SIG_OVERFLOW0)			// przerwanie co ....hmmm? sie juz nie dolicze :D
    {
      TCNT0 = tau;              	// przeładuj timer 0
      licz--;                       // dekrementuj
    }
    
    //******************* program głowny ************************
    
    int main(void)
    {
    
    	DDRB = 0xFF;  // wszystkie linie PORTB jako wyjścia
    	PORTB = 0x00; // wygaś diody segmentow
    
    	DDRD = 0xFF; 	//wyjscia
    	PORTD = 0x00; 
    
    	DDRA = 0x00; 	//wejscia
    	PORTA = 0xFF; 
    
    
    	//TIMER0
    	TIMSK = _BV(TOIE0);        	// włącz obsługę przerwań T/C0
    	TCNT0 = tau;        			// wartość początkowa T/C0
    	TCCR0 = 0xc2;//_BV(CS01)|_BV(CS00); 			// preskaler 64
    
    	t = 0;
    
    	sei(); // włącz obsługę przerwań
    	a=97;
    	b=245;
    	c=245;
    	w=1;
    	x=0;
    	y=0;
    	z=1;
    
    	while(1)
    	{
    
    		if (licz==0)
    		{
    			licz=vlicz;
    
    		 	t++;
    			
    			if (t>2) t=0;
    
    			if (t == 0)
    			{
    		    	PORTD = 0xFE; // uruchom wyswietlacz 1
    				PORTB = a; 
    			}
    
    			if (t == 1)
    			{
    		    	PORTD = 0xFD; // uruchom wyswietlacz 2
    				PORTB = b;
    			}
    
    			if (t == 2)
    			{
    		    	PORTD = 0xFB; // uruchom wyswietlacz 3
    				PORTB = c;
    			}
    
    		}
    		if (bit_is_clear(PINA, PA5))
    		{
    			if (w == 1) 
    			{
    				w = 0;
    				x = x*2;
    				if (y > 127)
    				{
    					x++;
    				}
    				y = y*2;
    				if (z > 127)
    				{
    					y++;
    				}
    					z = z*2;
    			}
    		}
    		if (bit_is_set(PINA,PA5))
    		{
    			if (w == 0)
    			{
    				
    				w = 1;
    				if(bit_is_clear(PINA,PA6))
    				{
    					if(bit_is_set(PINA,PA7))
    					{
    						__asm("nop");
    						z++;
    					}
    					
    				}
    				if(bit_is_set(PINA,PA6))
    				{
    					a = x;
    					b = y;
    					c = z;
    					
    				}
    			}
    		}
    
    	}
    }
    

    Zadaniem programu jest wyświetlanie na trzech wyświetlaczach segmentowych liczb przychodzących na portA za pomocą (na portA wchodzą sygnały clock, strobe i date). Problem w tym, że na symulatorze i w realu program nie wykonuje funkcji z++, z=z*2 i tym podobnych. Program napewno wchodzi w if-y co sprawdzałem na symulatorze (wykonywał __asm("nop");). Ogólnie chodzi o to dlaczego nie wykonuje obliczeń. Z góry dzięki za pomoc.

    Proszę używać znaczników [code]
    [zumek]
  • #2 5974200
    lucas_mcs
    Poziom 22  
    a y++ wykonuje?
    zamien miejscami __asm i z++, albo wywal __asm zeby dla sprawdzenia.
  • #3 5974216
    mlfox85
    Poziom 10  
    y+= też nie wykonuje, a asm był tylko do sprawdzenia i bez tego też nie działało
  • #4 5974220
    Dr.Vee
    VIP Zasłużony dla elektroda
    Jak sformatujesz kod, to na pewno zwiększysz szanse na to, że komuś będzie sie go chciało przeczytać.

    Pozdrawiam,
    Dr.Vee
  • #6 5975283
    BoskiDialer
    Poziom 34  
    skynet_2: Zmienne globalne jak ta, nie muszą być inicjalizowane. Ta zmienna trafi do sekcji bss, a więc na starcie będzie równa 0. Co innego zmienne lokalne funkcji, które znajdują się w rejestrach lub na stosie - te trzeba inicjalizować.

    Dodano po 20 [minuty]:

    Mnożenia, if'y, dodawania - rozumiem, że stanowią programową realizację rejestru przesuwanego. Trzeba jednak uwzględnić, że rozmiar zmiennych y i z (2 bajty) koliduje z warunkami postaci "y > 127" - interesujący nas dolny bajt może być równy zero, w górnym pojawi się jedynka co spowoduje błędne przeniesienie.
    Proponuję:
    - zamienić fragmenty postaci "x++;" na "x |= 1;";
    - przesunięcia postaci "x = x*2;" na "x <<= 1;";
    - porównania "x > 127" na "x & 0x80"
    - rozmiar zmiennych x, y i z na unsigned char lub uint8_t z stdint.h
  • #7 5975523
    mlfox85
    Poziom 10  
    wywalił tylko jedno ostrzeżenie: c:/winavr-20080610/lib/gcc/../../avr/include/avr/signal.h:36:2: warning: #warning "This header file is obsolete. Use <avr/interrupt.h>."
  • #8 5975695
    Dr.Vee
    VIP Zasłużony dla elektroda
    Może napisz jeszcze co ten program miałby robić... Np. co jest podłączone do pinów PA5, PA6, PA7. Jeśli to ma być rejest przesuwny (jak pisze BoskiDialer) to można go opisać duuuużo prościej.

    Rozumiem, że jednoliterowe nazwy zmiennych globalnych są Twoją metodą na oszczędzenie klawiatury i ograniczenie rozmiaru pliku z kodem źródłowym... :]

    Pozdrawiam,
    Dr.Vee
  • #9 5975754
    BoskiDialer
    Poziom 34  
    Dr.Vee: Autor wyraźnie napisał, choć nie do końca powiedział:
    mlfox85 napisał:
    (na portA wchodzą sygnały clock, strobe i date)


    Osobiście rozwiązał bym to przez sprzętowe spi, wstawką asemblera lub za pomocą jednej, większej zmiennej.
    Globalne zmienne są dopuszczalne, jednak ograniczenie zakresu zmiennych jest wskazane.
  • #10 5975916
    Dr.Vee
    VIP Zasłużony dla elektroda
    SPI byłoby dobre przy założeniu, że zawsze zostają wysłane kompletne bajty. W przeciwnym przypadku operacje na uint32_t + unia do podziału na bajty też działają nieźle - chyba ciężko byłoby tu coś wygrać asemblerem...

    Jakiś dziwny ten rejestr - jeśli PA5 to clock, to na każdym zboczu opadającym rejestr jest przesuwany, ale nie na każdym zboczu narastającym dostaje dane (PA7) (zależy od strobe (PA6)).

    Chyba strobe powinno być poza warunkiem zbocza zegara? Alternatywnie aktywacja strobe nie powinna blokować wsunięcia nowych danych do rejestru.

    Pozdrawiam,
    Dr.Vee
  • #11 5977005
    lucas_mcs
    Poziom 22  
    Sprawdz może ustawienia kompilatora/ skompiluj czym innym

    ja bym zamienił x++ na x= x+1;

    Wiem, że to troche OT,ale czy przypadkiem (ogólnie) nie jest tak że x++ dotyczy c++?
  • #12 5977037
    Freddie Chopin
    Specjalista - Mikrokontrolery
    lucas_mcs napisał:
    Sprawdz może ustawienia kompilatora/ skompiluj czym innym

    ja bym zamienił x++ na x= x+1;

    Wiem, że to troche OT,ale czy przypadkiem (ogólnie) nie jest tak że x++ dotyczy c++?

    przypadkiem warto najpierw poszukac, a potem pisac tego typu kwiatki.

    hint: bzdura.

    4\/3!!
  • #13 5977091
    lucas_mcs
    Poziom 22  
    Ano bzdura, w ramach samoukarania się przeczytałem stosowne artykuły na wiki.
  • #14 5979859
    mlfox85
    Poziom 10  
    Wielkie dzięki dla BoskiDialer. Twoje rady pomogły. Dr.Vee też miał racje, strobe powinno być poza if-ami od Clocka. Ale właściwie dlaczego gdy pisałem z++, i kompilator wchodził do pętli wartość z nie zwiększała się? Podobnie było z mnożeniem przez 2, przesuwanie w lewo nie było wykonywane (przynajmniej w symulatorze)?
REKLAMA