Sterowanie wyswietlaczem 7seg

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
Laik
Użytkownik
Posty: 242
Rejestracja: 21 maja 2007, 19:19
Lokalizacja: z nienacka

Sterowanie wyswietlaczem 7seg

Post autor: Laik » 17 wrz 2010, 12:03

Witam. Chcę zrobić czujnik odległości. Mam już potrzebne elementy tylko na razie brakuje wiedzy i dlatego mam pytania. Mam taki program do sterowania 2 wyświetlaczami 7seg problem w tym ze przerwania nie startują. Co jest problemem?

Kod: Zaznacz cały

#define F_CPU 1000000L
#include <avr/io.h>
#include <util/delay.h>    
#include <avr/interrupt.h>
 
#define Enable_INT0_F MCUCR |= (1 << ISC01); GICR |= (1 << INT0);
#define Timer0_Start TCCR0 = (1 << CS01) | (1 << CS00); TIMSK |= (1 << TOIE0); TCNT0 = 131;
#define Timer0_Stop TCCR0 =0; 


int cyf[10] = {0xA0,0xFc,0x92,0x98,0xCC,0x89,0x81,0xBC,0x80,0x88};
int wyswietlacz = 1;
int liczba = 12; 
int dziesiatki = 0;
int jednosci = 0;  


int main(void)
{

Enable_INT0_F;
Timer0_Start;
sei(); 

 
 DDRB = 0x01;
 PORTB = 0xFF;
  
 DDRD =    0xFF;
 PORTD = 0x80;



  while(1)
  {   
    
// Odczytywanie stanu przyciskow

    while(!(PINB & 0x02)) {
    
        liczba++;
        _delay_ms(80);
        while(!(PINB & 0x02)) {}
        _delay_ms(80);
        
    }

    while(!(PINB & 0x04)) {
    
        liczba--;
        _delay_ms(80);
        while(!(PINB & 0x04)) {}
        _delay_ms(80);
        
    }
    
    while(!(PINB & 0x08)) {
    
        liczba = 0;
        _delay_ms(80);
        while(!(PINB & 0x08)) {}
        _delay_ms(80);
        
    }
    
        while(!(PINB & 0x10)) {
    
        liczba = 9;
        _delay_ms(80);
        while(!(PINB & 0x10)) {}
        _delay_ms(80);
        
    }
    
    
//Rozdzielanie liczby dwu cyfrowej na dziesiatki i jednosci
    
dziesiatki = liczba / 10;
jednosci -= 10 * dziesiatki;
    


  }
}
SIGNAL (INT0_vect) //Obsluga przerwania
{
//...
}

SIGNAL (TIMER0_OVF_vect)
{
	if(wyswietlacz == 1){
	
		PORTB ^= 0x40;
		PORTD = cyf[dziesiatki];
		wyswietlacz++;
		
	}
	if(wyswietlacz == 2){
	
		PORTB ^= 0x80;
		PORTD = cyf[jednosci];
		wyswietlacz--;
	}
} 

keruseykaryu

Post autor: keruseykaryu » 17 wrz 2010, 16:57

Magiczne słowa są potrzebne: volatile. No i nie używaj SIGNAL() bo to przestarzałe jest. A i samo przerwanie jest źle napisane. Raportu kompilacji się nie czyta?

[ Dodano: 2010-09-17, 18:34 ]
Aha! I jeszcze tu się zastanów co dadzą te dwie instrukcje

Kod: Zaznacz cały

dziesiatki = liczba / 10; 
jednosci -= 10 * dziesiatki;

Laik
Użytkownik
Posty: 242
Rejestracja: 21 maja 2007, 19:19
Lokalizacja: z nienacka

Post autor: Laik » 18 wrz 2010, 15:12

Magiczne słowa są potrzebne: volatile
Już wstawiłem w kod i jest ok. Przerwania ruszyły :)
No i nie używaj SIGNAL() bo to przestarzałe jest.
To co używać zamiast tego ?

Kod: Zaznacz cały

dziesiatki = liczba / 10;
jednosci -= 10 * dziesiatki;
tutaj glupi błąd powinno być

Kod: Zaznacz cały

 jednosci = liczba - (10 * dziesiatki);
Problem jest z wyświetlaniem bo wyświetla mi tylko 1 segment. Coś nie tak w przerwaniu ?

PS. jak zrobic pod PB6 i PB7 czyli piny od kwarcu aby dzialaly jako zwykle wejscia/wyjscia?

keruseykaryu

Post autor: keruseykaryu » 18 wrz 2010, 18:29

Laik pisze:To co używać zamiast tego ?
Zapewne jakbyś poszukał to i owo w dokumentacji to znalazłbyś makro ISR(), które zastąpiło poprzednie makra.
Laik pisze:Problem jest z wyświetlaniem bo wyświetla mi tylko 1 segment. Coś nie tak w przerwaniu ?
Owszem. Dlatego napisałem, że masz je źle napisane. Musisz zrobić tak, by obie cyfry miały czas się wyświetlić. Tylko bez żadnych _delay_ms/us() w przerwaniu.
Laik pisze:PS. jak zrobic pod PB6 i PB7 czyli piny od kwarcu aby dzialaly jako zwykle wejscia/wyjscia?
Skąd mam wiedzieć jak nie napisałeś nawet jakiego procesora używasz...

Laik
Użytkownik
Posty: 242
Rejestracja: 21 maja 2007, 19:19
Lokalizacja: z nienacka

Post autor: Laik » 19 wrz 2010, 0:37

Korzystam z ATmega8. Co do zwolnienia przerwań chodzi o preskaler CS00, CS01, CS02 ? Znalazłem w internecie taka tabele:
Obrazek
Ale zmieniając konfiguracje efekt nie był zadowalający. Jak rozumiem timer0 w trybie normalnym zlicza od 0 do 255. Więc potrzebuje użyć trybu CTC i ustawić OCR0 na większą wartość niż 255 tak? W moim kodzie mam jeszcze cos takiego jak TCNT0 - ustawienie licznika jest na 131 czyli licznik pracuje 131 - 255 tak ? Zmiana wartości także nie przynosi rezultatu.
Tak wygląda symulacja (wyświetlacz powinien wyświetlić 25)
Obrazek

keruseykaryu

Post autor: keruseykaryu » 19 wrz 2010, 6:21

Nie masz zwalniać przerwań! Masz je poprawnie napisać. Przeanalizuj sobie jaki czas będzie świecić jedna, a jaki druga cyfra. Co możesz zrobić by się wyświetlały z tym samym czasem? Przy pisaniu programów trzeba niestety ruszyć głową, a nie szukać gdzie popadnie. Nie możesz wpisać do licznika 8bit wartości większej niż 255. Zostaw tą konfigurację licznika na razie w spokoju.

Laik
Użytkownik
Posty: 242
Rejestracja: 21 maja 2007, 19:19
Lokalizacja: z nienacka

Post autor: Laik » 19 wrz 2010, 20:11

Faktycznie głupi błąd w kodzie przerwania. Kod poprawiłem na taki:

Kod: Zaznacz cały

ISR(TIMER0_OVF_vect)
{
    PORTD = 0xFF;
    PORTB ^= 0xC0; 
    
    switch(wys){
    
        case 1:  
            PORTD = cyf[dziesiatki];
            wys++;
            break;
        case 2: 
            PORTD = cyf[jednosci]; 
            wys = 1;
            break;
        default: wys = 1;
            break;
        
    }
} 
I jest wszystko ok. Teraz wracam z pytaniem o tych pinach PB6 i PB7 w atmega8. Jak ustawić abym mógł z nich korzystać?

keruseykaryu

Post autor: keruseykaryu » 21 wrz 2010, 5:24

Laik pisze:Teraz wracam z pytaniem o tych pinach PB6 i PB7 w atmega8. Jak ustawić abym mógł z nich korzystać?
W zasadzie nic nie trzeba robić. Nowa ATMega8 (taka prosto ze sklepu) ma tak ustawione bezpieczniki, że PB6 i PB7 to normalne porty. Jak już przestawiałeś fuski to musisz zawrócić zmiany oscylatora na Internal RC.

Laik
Użytkownik
Posty: 242
Rejestracja: 21 maja 2007, 19:19
Lokalizacja: z nienacka

Post autor: Laik » 21 wrz 2010, 7:35

Oto chodzi że żadnych fuse bitów nie przestawiałem a porty nie działają. W takim razie będę zmuszony do zmiany układu. Dziękuje za pomoc.

ODPOWIEDZ