Atmega8 i sterowanie 7seg LED

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
Denar
-
Posty: 18
Rejestracja: 13 sty 2013, 14:12
Lokalizacja: Wlkp

Atmega8 i sterowanie 7seg LED

Post autor: Denar » 11 gru 2014, 23:30

Witam.
Być może szukam dziury w całym ale chciałbym sterować 4-cyfrowym 7seg wyświetlaczem LED z zachowaniem możliwości programowania po SPI jak również zachowania wolnego wejścia INT0 i możliwością podłączenia zewnętrznego rezonatora kwarcowego. Z powyższych założeń nie mam wolnego portu z 7 pinami do podłączenia segmentowego wyświetlacza. Ze sterowaniem całych segmentów nie ma większych problemów (można użyć różnych wolnych wyprowadzeń z różnych portów) ale wykorzystanie wolnych 7 bitów jednego portu jest w tym wypadku niemożliwe. Jako mogę rozwiązać ten problem? Z góry dziękuję za wskazówki. Pozdrawiam.

Awatar użytkownika
Ertew
Użytkownik
Posty: 1414
Rejestracja: 03 lip 2005, 10:36
Lokalizacja: Leszno
Kontakt:

Post autor: Ertew » 12 gru 2014, 0:53

Nie SPI tylko ISP, ale to mało istotny szczegół.

Opcja a) Wykorzystaj wszystkie 6 pinów portu C oraz D6 i D7. Dalej programowo (przy pomocni operacji bitowych) zmieniasz stan tylko tych 2 pinów. Na port C możesz wrzucić cały bajt informacji, po prostu dwa bity nie wyjdą na zewnątrz.
Napisz jaki stan chcesz mieć na pinie by wyświetlacz świecił i w jakim języku piszesz, pomożemy.

Opcja b) robisz 8 warunków if:
Jeśli bit 0 ma stan 1 to ustaw 1 na pinie 1 portu C, jeśli 0 to ustaw 0.
Jeśli bit 1 ma stan 1 to ustaw 1 na pinie 4 portu D, jeśli 0 to ustaw 0.
I analogicznie kolejne 6 warunków, w ten sposób możesz przyporządkować dowolne piny w dowolny sposób.

Opcja c) stosujesz rejestr przesuwny np. 74HC595 albo ekspander portów na i2c. Dane ładujesz do niego przez dwużyłowy interfejs dane+zegar lub (nie dotyczy i2c) dodatkowo możesz podłączyć linię zatrzask i wyłączenie wyjścia.

Denar
-
Posty: 18
Rejestracja: 13 sty 2013, 14:12
Lokalizacja: Wlkp

Post autor: Denar » 12 gru 2014, 9:40

Witam.
W moim układziku stanem aktywnym będzie stan niski - podanie logicznego zera zaświeci segment. Programik piszę w Bascom. Sugerując się podpowiedzią, takie rozwiązanie zda egzamin? (przedstawiam tylko zarys koncepcji):

Config portc = output
Config portd.6 = output
Config portd.7 = output
.......
portc = lookup (zmienna , tabela)
.......
portd = portc And &B1100000 'lub inaczej 192
Chodzi mi głównie o to żeby skopiować stany brakujących wyprowadzeń portu c i przypisać je do PD.6 i PD.7.

Awatar użytkownika
Ertew
Użytkownik
Posty: 1414
Rejestracja: 03 lip 2005, 10:36
Lokalizacja: Leszno
Kontakt:

Post autor: Ertew » 12 gru 2014, 19:14

Zależy jak spojrzysz na problem, możesz mieć 1 lub 2 błędy w tym rozwiązaniu.

1. port C ma 7 pinów z tego 6 (PC0..PC5) jest dostępnych a PC6 działa zamienne z RST. Bit w rejestrze oznaczony jako PC7 jest tylko do odczuty, czyli port jest fizycznie wybrakowany. Nieważne co wpiszesz, zawsze odczytasz 0.
Jeśli segmenty zakodujesz na pinach 0..6 a kropką będziesz sterować oddzielnie - możesz się nie przejmować powyższą uwagą. Natomiast rada na przyszłość, takie uproszczenie sprawy może kiedyś spowodować błąd bardo trudny do wyłapania.

2. Twoja idea jest słuszna, ale w ten sposób bity 6 i 7 trafią na piny D6 i D7 przy jednoczesnym wyzerowaniu reszty pinów. Nie wiem jak Ty, ale ja wolał bym zmienić tylko stan 2 pinów, bez ruszania reszty. Więc do dzieła:
Wczytujesz stan portu D do jednej zmiennej a wartość docelową (zwróconą z funkcji lookup) do drugiej. Następnie są dwie drogi:
a) w pierwszej zmiennej (port) zerujesz bity 6 i 7, a w drugiej (lookup) bity 0..5. Następnie sumujesz (OR) obie zmienne i wrzucasz na port D.
b) w pierwszej zmiennej (port) ustawiasz bity 0..5, a w drugiej (lookup) ustawiasz bity 6 i 7. Następnie łączysz obie zmienne funkcją AND.

Całość można uprościć operując na porcie D zamiast na dodatkowej zmiennej, ale ma to wadę, na chwilę oba piny będą miały stan 0 lub 1, zależnie od wybranej metody. W twoim przypadku diody mogą na chwilę zgasnąć (można podać stan 1) więc rozpiszę to dla przypadku (b).

Kod: Zaznacz cały

Config portc = output
Config portd.6 = output
Config portd.7 = output
.......
' gasimy wszystkie segmenty
portc = &B11111111
portd = portd OR &B11000000  ' Ty zapomniałeś tu dać jednego zera

' tutaj procedura przełączająca piny/tranzystory sterujące cyframi, btw, polecam dać tu 4017, wymaga tylko 2 przewodów

wyjscie =  lookup (zmienna , tabela)
portc = wyjscie 
wyjscie = wyjscie OR &B00111111
portd = portd AND wyjscie ' zmienna wyjscie wyzeruje tylko piny D6 i D7

Denar
-
Posty: 18
Rejestracja: 13 sty 2013, 14:12
Lokalizacja: Wlkp

Post autor: Denar » 14 gru 2014, 13:36

Witam.
Rozwiązałem swój problem. Do testów na razie 2 segmenty zliczające od 0 do 99. Może mało estetycznie ale najważniejsze, że dobrze działa:

Kod: Zaznacz cały

On Timer0 , Startuj
Do : Loop : End

Startuj:
Toggle Ktorywysw
Incr Licznik
If Licznik = 50 Then
Licznik = 0
  Incr Jednostki
  If Jednostki = 10 Then
  Jednostki = 0
    Incr Dziesiatki
    If Dziesiatki = 10 Then
    Dziesiatki = 0
    End If
  End If
End If

Portc = 255
Portd = 255
Select Case Ktorywysw:
Case 0:
Portc = Lookup(dziesiatki , Tabela1)
Portd = Lookup(dziesiatki , Tabela2)
Portd.0 = 0
Case 1:
Portc = Lookup(jednostki , Tabela1)
Portd = Lookup(jednostki , Tabela2)
Portd.1 = 0
End Select
Return

Tabela1:
Data 194 , 247 , 204 , 228 , 241 , 224 , 192 , 246 , 192 , 224

Tabela2:
Data 239 , 239 , 239 , 239 , 239 , 255 , 255 , 239 , 239 , 239

Awatar użytkownika
Ertew
Użytkownik
Posty: 1414
Rejestracja: 03 lip 2005, 10:36
Lokalizacja: Leszno
Kontakt:

Post autor: Ertew » 15 gru 2014, 12:19

O tak, brzydko i źle. Przy okazji zmieniasz stan wszystkich pinów portu D, co oznacza że sam obsługa multipleksowania wyświetlacza może generować przerwania zewnętrzne INT0/INT1, czego na pewno nie chcesz. Ale najważniejsze że działa, prawda? :razz:

ODPOWIEDZ