Skocz do zawartości

timer0 bascom


sjacek

Pomocna odpowiedź

Skoro masz wewnętrzny rezonator RC, to dlaczego w programie ustawiłeś taktowanie na 16MHz? Atmega32 nie ma przypadkiem domyślnego 1MHz? Bo raczej na pewno nie 16... (tak, nota katalogowa nie gryzie - nie mam czasu szukać)

Link do komentarza
Share on other sites

A no to już wiadomo czemu to tak kuleje, jednak dobrze wywróżyłem z fusów.

Ustaw:

$crystal = 1000000

Problem nie tkwił w programie ale w tym, że Ty sobie stwierdziłeś, że procesor ma pracować z prędkością 16MHz choć nie jest do tego przygotowany.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

inne programy działały przy takich ustawieniach

Bo inne programy nie wymagające cyklu procesora do odmierzenia czasu, będą się normalnie zachowywać, a przynajmniej powinny.

Na wewnętrznym i tak wydusisz max 8MHz, po odpowiednim ustawieniu fusebitów. Temat ustawiania niejednokrotnie wałkowany na forum, na googlach też dużo znajdziesz. Jak coś to polecam http://www.engbedded.com/fusecalc/

Link do komentarza
Share on other sites

co ty nie powiesz 😋

$crystal ustawiłem na 1000000, zmieniłem wartość prescalera, wartość początkową timera i warunek w if'ie

Link do komentarza
Share on other sites

Według mnie powinno to tak wyglądać jeżeli się rozchodzi o przybliżone odmierzanie 1s. Czyli co ~1s będzie zmieniany stan na pinie D.0.

$regfile = "m32def.dat"
$crystal = 1000000

Config Pind.0 = Output
Reset Portd.0

Config Timer0 = Timer , Prescale = 1024

Dim Licz_int As Byte
Licz_int = 0

Enable Interrupts
Enable Timer0
Start Timer0
On Timer0 Licz:

Do

Loop

Licz:
  Licz_int = Licz_int + 1

  If Licz_int > 3 Then
     Toggle Portd.0
     Licz_int = 0
  End If
Return
Link do komentarza
Share on other sites

4 przepełnienia Timera przy 1024 prescalerze dają około 1s (dla dokładności 1.048576) nie wiem jak Ty to wyliczyłeś że Ci 4ms wychodzą. Program przetestowany w symulatorze bascoma i działa zgodnie z oczekiwaniem czyli co 1s zmienia stan portu.

Aha tak przy okazji polecam http://frank.circleofcurrent.com/cache/avrtimercalc.htm 🙂

Link do komentarza
Share on other sites

z neta ściągnąłem taki kod do obsługi wyświetlacza segmentowego i działa

kod:

'--------------------------------------------------------------------
'
'
'--------------------------------------------------------------------
'Program przygotowany dla zestawu EvB 4.3 firmy And-Tech.pl


$regfile = "m32def.dat"

'Częstotliwość kwarcu domyślnie 16MHz
$crystal = 16000000

'Podłaczenie wyświetlacza 7 segmentowego
' Digit1 PORTB.0
' Digit2 PORTB.1
' Digit3 PORTB.2
' Digit4 PORTB.3

'Segment A PORTA.1
'Segment B PORTA.2
'Segment C PORTA.3
'Segment D PORTA.4
'Segment E PORTA.5
'Segment F PORTA.6
'Segment G PORTA.7

Config Porta = Output
Config Pinb.0 = Output
Config Pinb.1 = Output
Config Pinb.2 = Output
Config Pinb.3 = Output


Config Timer0 = Timer , Prescale = 256

Declare Sub Pobr_znaku(cyfra As Byte)

On Timer0 Mult_wysw

Dim A As Byte
Dim B As Byte
Dim C As Byte
Dim D As Byte
Dim Nr_wysw As Byte

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

Wait 2
Set W1
Set W2
Set W3
Set W4
Wait 2

Enable Interrupts

Enable Timer0
Load Timer0 , 125

Do

Wait 1

D = D + 1

'Rozbicie na poszczegolne cyfry
If D > 9then
D = 0
C = C + 1
End If
If C > 9then
C = 0
B = B + 1
End If
If B > 9 Then
B = 0
A = A + 1
End If
If A > 9 Then
A = 0 : B = 0 : C = 0 : D = 0
End If

Loop

End                                                         'end program


Sub Pobr_znaku(cyfra As Byte)
Porta = Lookup(cyfra , Kody7seg)
End Sub


Mult_wysw:

Load Timer0 , 150
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 = 4 Then
Nr_wysw = 0
End If
Return


Kody7seg:

Data &B10000001 , &B11110011 , &B01001001 , &B01100001 , &B00110011 ,
Data &B00100101 , &B00000101 , &B11110001 , &B00000001 , &B00100001

kto widzi różnicę?

Link do komentarza
Share on other sites

Przecież mówiłem że 16MHz, ale ktoś się uparł że na pewno nie. Ten program który przed chwilą wysłałem jest robiony pod płytkę testową którą posiadam i działa, więc mój kod też powinien na takiej częstotliwości.

[ Dodano: 26 Lip 10 10:05 ]

a tam u Ciebie faktycznie ok 1s wychodzi, mój błąd sorki 😋

Link do komentarza
Share on other sites

No to trzeba było napisać że masz jakaś płytkę testową i masz na niej jakiś tam oscylator który podaje 16MHz?!

$regfile = "m32def.dat"
$crystal = 16000000

Config Pind.0 = Output
Reset Portd.0

Config Timer0 = Timer , Prescale = 1024

Dim Licz_int As Byte
Licz_int = 0

Enable Interrupts
Enable Timer0
Start Timer0
On Timer0 Licz:

Do

Loop

Licz:
  Licz_int = Licz_int + 1

  If Licz_int > 61 Then
     Toggle Portd.0
     Licz_int = 0
  End If
Return
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.