Multipleksowanie wyswietlaczy i dziwny problem

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
JOLLY
-
Posty: 17
Rejestracja: 07 wrz 2007, 9:17
Lokalizacja: st-ce

Multipleksowanie wyswietlaczy i dziwny problem

Post autor: JOLLY » 24 mar 2008, 19:32

Witam

Mam problem z zegarkiem na wyswietlaczach led, gdyz po wlaczeniu zasilania badz resecie migaja mi segmenty ktore powinny byc wygaszone, trzeba wcisnac przycisk ustawiania minut lub godzin wtedy jest ok dopiero, za to jesli dam instrukcje wait 1 wtedy wszystko jest ok, ale za to ciezko obsluguje sie przyciski, gdyz trzeba je wciskac dluzej i nie zawsze lapia przez ten wait, i nie moze byc np waitms 1000 tylko koniecznie wait 1 co jest dziwne dla mnie, pewnie gdzies jest byk w kodzie, ale nie potrafie go znalesc, wiec prosilbym o pomoc. oto kod z wait 1:

Kod: Zaznacz cały

$regfile = "m8def.dat"
$lib "I2C_TWI.LBX"
$crystal = 16000000



Config Portd = Output
Config Pinc.0 = Output
Config Pinc.1 = Output
Config Pinc.2 = Output
Config Pinc.3 = Output
Config Portb = Input

Config Sda = Portc.4
Config Scl = Portc.5
I2cinit
Config Twi = 100000

S1 Alias Portb.0
S2 Alias Portb.1
S3 Alias Portb.2
S4 Alias Portb.3

Set S1
Set S2
Set S3
Set S4

Config Timer0 = Timer , Prescale = 256



Declare Sub Pobr_znaku(cyfra As Byte)

Declare Sub Ustawh
Declare Sub Ustawm
Declare Sub Settime


On Timer0 Mult_wysw
Enable Timer0

Load Timer0 , 250

Dim A As Byte , B As Byte , C As Byte , D As Byte

Dim M As Byte
Dim S As Byte
Dim H As Byte



Dim Nr_wysw As Byte


Dim Minuta As Byte
Dim Godz As Byte

W1 Alias Portc.0
W2 Alias Portc.1
W3 Alias Portc.2
W4 Alias Portc.3


Enable Interrupts

Do

  'i2c
    I2cstart
   I2cwbyte 160
   I2cwbyte 2
   I2cstart
   I2cwbyte 161
   I2crbyte S , Ack
   I2crbyte M , Ack
   I2crbyte H , Nack
   I2cstop


Minuta = M

 D = Minuta And &B00001111

 Shift Minuta , Right , 4

 C = Minuta

Godz = H

 B = Godz And &B00001111
 Shift Godz , Right , 4

 A = Godz
'***************************
 Wait 1   'nieszczesny wait
'***************************
Debounce Pinb.2 , 0 , Ustawh , Sub

Debounce Pinb.1 , 0 , Ustawm , Sub
Loop
End


Sub Pobr_znaku(cyfra As Byte)


  Portd = Lookup(cyfra , Kody7seg )


End Sub

Mult_wysw:


 Load Timer0 , 250

 Set W1
 Set W2
 Set W3
 Set W4
 Select Case Nr_wysw

  Case 0:
   Call Pobr_znaku(a)


   Reset W1
  Case 1:
   Call Pobr_znaku(b)


   Reset W2
  Case 2:
   Call Pobr_znaku(c)


   Reset W3
  Case 3:
   Call Pobr_znaku(d)


   Reset W4
 End Select
 Incr Nr_wysw

 If Nr_wysw > 3 Then

  Nr_wysw = 0
 End If
Return

Ustawh:
H = Makedec(h)
M = Makedec(m)
S = Makedec(s)
Incr H
If H > 23 Then
   H = 0
End If

Call Settime

Waitms 100

Return

Ustawm:
S = 0
H = Makedec(h)
M = Makedec(m)
Incr M
If M > 59 Then
   M = 0
End If

Call Settime

Return

Sub Settime:
S = Makebcd(s)
M = Makebcd(m)
H = Makebcd(h)


I2cstart
I2cwbyte 160
I2cwbyte 0
I2cwbyte 8
I2cstop

I2cstart
I2cwbyte 160
I2cwbyte 2
I2cwbyte S
I2cwbyte M
I2cwbyte H
I2cstop
Waitms 100
End Sub


Kody7seg:

Data &B11000000 , &B11111001 , &B10100100 , &B10110000 , &B10011001,
Data &B10010010 , &B10000010 , &B11111000 , &B10000000 , &B10010000

ZbeeGin

Post autor: ZbeeGin » 24 mar 2008, 22:45

A dlaczego raz podprogramy są w formie SUB a raz jako części rozpoczynające się etykietą a zakończone RETURN? Choć wszystkie są w sekcji DECLARE jako SUB.

JOLLY
-
Posty: 17
Rejestracja: 07 wrz 2007, 9:17
Lokalizacja: st-ce

Post autor: JOLLY » 25 mar 2008, 8:49

Racja, nie zwrocilem uwagi. Poprawilem, niestety sytuacja bez zmian. Kod:

Kod: Zaznacz cały

$regfile = "m8def.dat"
$lib "I2C_TWI.LBX"
$crystal = 16000000



Config Portd = Output
Config Pinc.0 = Output
Config Pinc.1 = Output
Config Pinc.2 = Output
Config Pinc.3 = Output
Config Portb = Input

Config Sda = Portc.4
Config Scl = Portc.5
I2cinit
Config Twi = 100000

S1 Alias Portb.0
S2 Alias Portb.1
S3 Alias Portb.2
S4 Alias Portb.3

Set S1
Set S2
Set S3
Set S4

Config Timer0 = Timer , Prescale = 256



Declare Sub Pobr_znaku(cyfra As Byte)

Dim Ustawh As Byte
Dim Ustawm As Byte
Declare Sub Settime


On Timer0 Mult_wysw
Enable Timer0

Load Timer0 , 250

Dim A As Byte , B As Byte , C As Byte , D As Byte

Dim M As Byte
Dim S As Byte
Dim H As Byte



Dim Nr_wysw As Byte


Dim Minuta As Byte
Dim Godz As Byte

W1 Alias Portc.0
W2 Alias Portc.1
W3 Alias Portc.2
W4 Alias Portc.3


Enable Interrupts

Do

  'i2c
    I2cstart
   I2cwbyte 160
   I2cwbyte 2
   I2cstart
   I2cwbyte 161
   I2crbyte S , Ack
   I2crbyte M , Ack
   I2crbyte H , Nack
   I2cstop


Minuta = M

 D = Minuta And &B00001111

 Shift Minuta , Right , 4

 C = Minuta

Godz = H

 B = Godz And &B00001111
 Shift Godz , Right , 4

 A = Godz
'***************************
 Wait 1   'nieszczesny wait
'*************************** 


Debounce Pinb.2 , 0 , Ustawh , Sub

Debounce Pinb.1 , 0 , Ustawm , Sub
Loop
End


Sub Pobr_znaku(cyfra As Byte)


  Portd = Lookup(cyfra , Kody7seg)


End Sub

Mult_wysw:


 Load Timer0 , 250

 Set W1
 Set W2
 Set W3
 Set W4
 Select Case Nr_wysw

  Case 0:
   Call Pobr_znaku(a)


   Reset W1
  Case 1:
   Call Pobr_znaku(b)


   Reset W2
  Case 2:
   Call Pobr_znaku(c)


   Reset W3
  Case 3:
   Call Pobr_znaku(d)


   Reset W4
 End Select
 Incr Nr_wysw

 If Nr_wysw > 3 Then

  Nr_wysw = 0
 End If
Return

Ustawh:
H = Makedec(h)
M = Makedec(m)
S = Makedec(s)
Incr H
If H > 23 Then
   H = 0
End If

Call Settime

Waitms 100

Return

Ustawm:
S = 0
H = Makedec(h)
M = Makedec(m)
Incr M
If M > 59 Then
   M = 0
End If

Call Settime

Return

Sub Settime:
S = Makebcd(s)
M = Makebcd(m)
H = Makebcd(h)


I2cstart
I2cwbyte 160
I2cwbyte 0
I2cwbyte 8
I2cstop

I2cstart
I2cwbyte 160
I2cwbyte 2
I2cwbyte S
I2cwbyte M
I2cwbyte H
I2cstop
Waitms 100
End Sub


Kody7seg:

Data &B11000000 , &B11111001 , &B10100100 , &B10110000 , &B10011001,
Data &B10010010 , &B10000010 , &B11111000 , &B10000000 , &B10010000

Awatar użytkownika
Tranzystor
Użytkownik
Posty: 889
Rejestracja: 28 sie 2005, 19:19
Lokalizacja: Świętochłowice
Kontakt:

Post autor: Tranzystor » 25 mar 2008, 8:54

Heh, problem prawdopodobnie ten sam co przy 1wire :D Spróbuj komunikację z układem PCF8583 wrzucić do podprogramu, gdzie odświeżane są cyfry na wyświetlaczu. Pamiętaj jednak, że przy jednym przerwaniu Timera wykonywane ma być jedno z poleceń I²C. Polecam użyć dzielenia z resztą czyli MOD i instrukcji Select Case.

Pozdrawiam ;)

JOLLY
-
Posty: 17
Rejestracja: 07 wrz 2007, 9:17
Lokalizacja: st-ce

Post autor: JOLLY » 25 mar 2008, 11:14

Nawet tak moze byc jesli robie obsluge i2c przez TWI? W takim razie przezuce obsluge pcfa do podprogramu wyswietlania. Dziwne jest tylko ze koniecznie musi byc opoznienie 1 sekunda, przy innych nie ma zmian.

Awatar użytkownika
Tranzystor
Użytkownik
Posty: 889
Rejestracja: 28 sie 2005, 19:19
Lokalizacja: Świętochłowice
Kontakt:

Post autor: Tranzystor » 25 mar 2008, 11:20

Te opóźnienie pozwala na wykonanie przez sekundę prawidłowo poleceń, które masz w przerwaniu, a później jest ono zakłócane przez transmisję I²C. No i z powrotem poprawnie wykonywane. To nie jest dziwne, tylko logiczne, podobnie miałem z komunikacją przez 1wire :D

Powiadom nas o efektach...

Pozdrawiam ;)

JOLLY
-
Posty: 17
Rejestracja: 07 wrz 2007, 9:17
Lokalizacja: st-ce

Post autor: JOLLY » 25 mar 2008, 21:33

Naprawilem:) rozwiazanie bylo prostsze niz myslalem, wystarczylo ze przezucilem obsluge i2c i obsluge tresci wyswietlanej do osobnych podprogramow i juz zadnych anomalii nie ma, dziala pieknie jak byc powinno:)
Ale czeka mnie jeszcze obsluga 1wire, wiec to dopiero poczatek:)

Pozdrawiam

ODPOWIEDZ