Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[ATTINY2313][BASCOM]Pomoc w obsłudze counter-a. Co nie tak?

guuciek 13 Mar 2010 21:05 3913 23
  • #1
    guuciek
    Level 14  
    Witam . Od dłuższego czasu walczę z obsłużeniem licznika impulsów w ww procesorze .
    Otóż sprawa wygląda następująco . Mam sobie układ taktowany częstotliwością 4 Mhz z kwarcu zewnętrznego . Na pind.5 (t1) przychodzi sobie sygnał prostokątny o częstotliwości 1 Mhz . Jest on podawany przez pewien okres czasu a ja mam zliczyć jego ile było okresów tego sygnału . Procesor startuje układ który generuje dany sygnał i następnie (takie jest moje założenie) załącza counter który jest wyłączany gdy na pind.0 pojawi się 1 oznaczający koniec pomiaru .
    I wszystko ładnie pięknie tylko że zawsze dostaję wartość 0 chociaż sygnał prostokątny dochodzi do tej nogi w czasie pomiaru .
    Jeśli to coś pomoże to układ ten ma zadanie mierzyć pojemność kondensatorów smd gdzie jeden okres to 1 pF .
    Oto kod jaki spłodziłem .
    Code:

    $crystal = 4000000
    Config Portb = &B11111111 ; Portb = &B11111100
    Config Portd = &B01010010 ; Portd = &B01011001
    Config Timer1 = Counter , Edge = Falling , Capture Edge = falling , Prescale = 1
    On Timer1 Zeruj
    Enable Timer1
    Enable Interrupts


    W1 Alias Portb.4
    W2 Alias Portb.3
    W3 Alias Portb.2

    Ds Alias Portb.5
    Sh Alias Portb.7
    st alias portb.6

    Pf Alias Portd.6
    Nf Alias Portb.1
    Uf Alias Portb.0

    Strt Alias Portd.4
    Safe Alias Portd.1

    Dim A As Byte
    Dim B As Byte
    Dim I As Byte
    Dim Licznik As Long
    Dim Przep As Byte
    Dim S As String * 1
    Dim Liczby As String * 3
    Dim Cyfry(3) As Byte

    Cyfry(1) = 10
    Cyfry(2) = 10
    Cyfry(3) = 10


    A = 1
    B = 0
    Licznik = 0
    Przep = 0

    Do
    If Pind.3 = 0 Then
     Pf = 0
      Nf = 0
      Uf = 0
    Timer1 = 0
    Przep = 0
    Bitwait Pind.3 , Set
    Start Timer1
    Safe = 1
    Strt = 0
    bitwait pind.0 , set
    Stop Timer1
    Safe = 0
    Strt = 1
    Licznik = Przep * 65536
    Licznik = Licznik + Timer1

    If Licznik < 1000 Then
    Set Pf
    Else
    Licznik = Licznik \ 1000
    If Licznik < 1000 Then
    Set Nf
    Else
    Licznik = Licznik \ 1000
    Set Uf
    End If
    End If

    Liczby = ""

    If Licznik < 10 Then
    Liczby = "00"
    End If
    If Licznik < 100 And Licznik > 9 Then
    Liczby = "0"
    End If
    Liczby = Liczby + Str(licznik)
    For B = 1 To 3
    S = Mid(liczby , B , 1)
    I = 4 - b
    Cyfry(i) = Val(s)
    Next B


    End If

    If A = 3 Then
    A = 1
    Else
    Incr A
    End If



    Gosub Wyslij

    Select Case A
    Case 1:
    Reset W1
    Case 2 :
    Reset W2
    Case 3 :
    Reset W3
    End Select




    Waitms 4
    Gosub Rst
    Waitms 1

    Loop

    End

    Wyslij:
       I = Lookup(cyfry(a) , Dta)

       For B = 0 To 7
       If I.b = 1 Then
       Set Ds
       Else
       Reset Ds
       End If
       Reset Sh
       Set Sh
       Next B
       Reset St
       Set St
    Return

    Rst:
      W1 = 1
      W2 = 1
      W3 = 1

    Return


    Zeruj:

    Incr Przep
    Return



    Dta:
     Data 126 , 80 , 109 , 121 , 83 , 59 , 63 , 112 , 127 , 123 , 128



    Sam moment załączania timera to
    Code:
    If Pind.3 = 0 Then
    
     Pf = 0
      Nf = 0
      Uf = 0
    Timer1 = 0
    Przep = 0
    Bitwait Pind.3 , Set
    Start Timer1
    Safe = 1
    Strt = 0
    bitwait pind.0 , set
    Stop Timer1
    Safe = 0
    Strt = 1
    Licznik = Przep * 65536
    Licznik = Licznik + Timer1

    Reszta kodu to zakresy i obsługa wyświetlacza multipleksowanego które na pewno działają poprawnie.
    Był bym wdzięczny za pomoc gdyż walczę z tym dość długo . Próbowałem odczytywać te dane z wszystkich zmiennych jakie bascom przeznacza na ten licznik , oraz bezpośrednio pod rejestry licznika (assamblerowe) . Zawsze to samo :/
  • #2
    landy13
    Level 30  
    Obsługa przerwania na pewno nie zmieści się w czterech cyklach.
  • #3
    guuciek
    Level 14  
    A skok do przerwania nie jest wykonywany gdy rejestry się przepełnią ??
    Czyli co 65536 cykli ?? Nawet jeśli jest tak jak mówisz to nawet przy krótkim czasie trwania impulsów pierwszy powinien być wyłapany i być widoczny w rejestrze Countera .
  • #4
    landy13
    Level 30  
    Nie analizowałem kodu. Piszę o założeniach.
    Quote:
    Mam sobie układ taktowany częstotliwością 4 Mhz z kwarcu zewnętrznego . Na pind.5 (t1) przychodzi sobie sygnał prostokątny o częstotliwości 1 Mhz
  • #5
    guuciek
    Level 14  
    Witam .
    Wiem że dzisiaj niedziela , czas wolny , ale na prawdę chciałbym się z tym uporać w końcu ponieważ walczę z tym tematem już dość długo .
    Postanowiłem sprawdzić czy sam timer / counter 1 działa . Przestawiłem go na timera i ustawiłem na dziesięć sec . Po tym czasie ma zaświecić diodę. I wszystko działa poprawnie po ~~ 10 sec od wciśnięcia przycisku zaświeca się dioda . Dałem też wewnętrzne podciąganie do vcc na T1 i nic to nie dało .
    Proszę o jakiekolwiek wskazówki .
  • #6
    H0miczek
    Level 20  
    Code:
    Licznik = Przep * 65536

    -> nie jestem pewna jak traktuje to bascom, ale przep jest bajtem. jesli wykonuje sie na bajcie a nie na longu to masz tzw lipe.
    sprobuj
    Code:
    Licznik = Przep
    
    Licznik = Licznik * 65536

    oze o to chodzi
  • #7
    guuciek
    Level 14  
    To nie to :/
    Dalej wyrzuca same zera . Nie mam pojęcia co może być w tym kodzie nie tak . Jak na moje oko wygląda on znośnie . Mimo wszystko dzięki za zainteresowanie . :)
  • #8
    landy13
    Level 30  
    Timer skonfigurowany jako Counter liczy impulsy z zewnątrz, a nie mierzy czasu.
  • #9
    guuciek
    Level 14  
    Tak wiem o tym i tak właśnie ma chodzić . Na timer przełączyłem go żeby sprawdzić czy w ogóle układ timera działa . Wystarczy czytać całe posty :) a nie po kawałku i wtedy wszystko staje się jasne .

    Mógłby mi ktoś przybliżyć działanie nóżki ICP . Z tego co wyczytałem jest to spust counter . Może to przez nią nie chce zliczać . Da się go jakoś ominąć ? Nóżka ta jest niestety używana do innych celów i nie może zostać wykorzystana , przez counter. Ale z tego co czytałem na forach to raczej nikt o nie j nic nie wspominał . Co o tym myślicie ??
  • #10
    landy13
    Level 30  
    guuciek wrote:
    Tak wiem o tym i tak właśnie ma chodzić
    Więc co tam robi "prescale"?
  • #11
    guuciek
    Level 14  
    Akt desperacji :)
    Zapomniałem usunąć , gdy próbowałem na wszystkie sposoby konfiguracji to odpalić . Zresztą w helpie też jest takie ustawienie zapisane . Nie wiem dokładnie po co .

    W tej chwili próbuje konfigurować ten counter i jego odczyt z poziomu asm . Zobaczymy co z tego wyjdzie
  • #12
    guuciek
    Level 14  
    Witam ponownie po przerwie .
    I napisałem cały program w Asm (postanowiłem się sprawdzić i nauczyć czegoś nowego ) . Jego działanie jest identyczne jak w bascomie , ale countera 1 dalej nie udało mi się odpalić :/ Nadal wyrzuca zera . I tak samo jak w bascomie gdy wpisze dane na sztywno wszystko się wyświetla ( wynik co prawda różni się od tego jaki powinien wyjść ale to tylko kwestia jakiegoś błędu w mnożeniu nad którym popracuję ) Może jutro kupię innego attiny2313 i sprawdzę na nim .

    Co do asm jest to moje pierwsze spotkanie z nim i od razu rzuciłem się na głębszą wodę , ale dzięki drobnej pomocy kolegi i pewnej książki udało mi się wykonać ten program w niecałe 3 dni z czego jestem dumny .

    Dla porównania ten sam program w asm zajmuje 27,8% pamięci procesora a w bascomie 89 % pamięci . Dla zainteresowanych kod asm (jeszcze z błędami w przeliczaniu ) :


    Code:

    .include "tn2313def.inc"
    .org 0x000
    rjmp start
    .org 0x005
    rjmp przer
    .org 0x006
    rjmp czas
    .def tbcd0 = r7
    .def tbcd1 = r8
    .def c1 = r10
    .def c2 = r11
    .def c3 = r12
    .def a = r17
    .def b = r18
    .def przep = r19
    .def i = r16
    .def zegar = r20
    .def w = r21
    .def b4 = r22
    .def b3 = r23
    .def b2 = r24
    .def b1 = r25
    .def r = r26
    .def f = r9

    .equ   AtBCD0   =7      
    .equ   AtBCD2   =8      
    .equ    mssb = 240
    .equ   lssb = 15


    ldi i,0xe0
    out spl,i


    start:
    ;ustawienia portów
    ldi i,0b11111111
    out ddrb , i
    ldi i,0b11111100
    out portb , i
    ldi i,0b01010010
    out ddrd , i
    ldi i,0b01011001
    out portd,i

    ;ustawienia timerow
    ;timer0

    ldi i,0b10000101
    out tccr0b,i
    clr i
    out tccr0a,i
    ldi i,0b10000010
    out timsk,i
    ;timer1
    clr i
    out tccr1a , i
    ldi i,0b00000000
    out tccr1b , i

    sei

    ;ustawienia poczatkowe
    ldi a , 1
    ldi i, 1
    mov c1,i
    ldi i, 3
    mov c2,i
    ldi i, 5
    mov c3,i

    clr zegar


    glowna:
    sbis pind , 3
    rcall pojemnosc
    cpi a , 4
    in i , sreg
    sbrs i,1
    inc a
    sbrc i,1
    ldi a , 1

    ;wysylanie

    cpi a, 1
    in w ,sreg
    sbrc w,1
    mov i,c1

    cpi a, 2
    in w ,sreg
    sbrc w,1
    mov i,c2

    cpi a, 3
    in w ,sreg
    sbrc w,1
    mov i,c3



    ldi ZH, high(znaki << 1)
    ldi ZL, low(znaki << 1)
    clc
    rol i
    add ZL,i
    clr i
    adc ZH,i
    lpm
    mov i,r0

    clr w

    we3:
    cpi w , 8
    breq we4
    sbi portb,5
    sbrs i,0
    cbi portb,5
    cbi portb,7
    sbi portb,7
    ror i
    inc w
    rjmp we3
    we4:
    cbi portb,6
    sbi portb,6



    ;miltipleksowanie
    cpi a, 2
    in i ,sreg
    sbrc i,1
    cbi portb,3

    cpi a, 3
    in i ,sreg
    sbrc i,1
    cbi portb,4

    cpi a, 1
    in i ,sreg
    sbrc i,1
    cbi portb,2
    ;****************8



    rcall waitms
    rcall waitms
    rcall waitms


    sbi portb,3
    sbi portb,4
    sbi portb,2
    rcall waitms


    rjmp glowna
    ;koniec petli *******




    przer:
    inc przep
    reti

    czas:

    inc zegar
    cpi zegar,255
    in b,sreg
    sbrs b , 1
    reti
    sbi portb,3
    sbi portb,4
    sbi portb,2
    ldi b,0b00000000
    out tccr0b,b
    clr zegar
    we:
    sbic pind,3
    rjmp we
    we2:
    sbis pind,3
    rjmp we2
    ldi b,0b00000101
    out tccr0b,b
    reti


    pojemnosc:

    clr zegar
    clr i
    out tccr0b,i
    out tcnt0,i
    sbi portb,3
    sbi portb,4
    sbi portb,2
    cbi portb,0
    cbi portb,1
    cbi portd,6
    clr i
    out tcnt1h,i
    out tcnt1l,i
    clr przep
    we5:
    sbic pind,3
    rjmp we5
    ldi i , 0b00000110
    out tccr1b,i
    sbi portd,1
    cbi portd,4
    rcall waitms
    we6:
    sbis pind,0
    rjmp we6
    ldi i , 0b00000000
    out tccr1b,i
    cbi portd,1
    sbi portd,4

    rcall mnozenie
    clr i
    in b, tcnt1l
    in r, tcnt1h
    add b1,b
    adc b2,r
    adc b3,i
    adc b4,i
    cpi b4,1
    brlo over ; jesli wieksze od 0x ff ffff wyswietl - - -
    ldi i, 11
    mov c1,i
    mov c2,i
    mov c3,i
    ldi i, 0b00000101
    out tccr0b , i
    clr i
    out tcnt0 , i
    ret
    over:
    ;obliczenia

    ldi i , 1
    mov f,i
    //Wpisujemy do rejwestrów liczbe 1000
    ldi i,0xe8
    ldi w,0x03
    clr r

    cp b1,i
    cpc b2,w
    cpc b3,r
    brlo dalej

    clr przep
    clr b4
    petla:
    add przep , f
    adc b4 , r
    //Odejmujemy tysiac od liczby 3 bajtowej
    sub b1,i
    sbc b2,w
    sbc b3,r
    //Sprawdzamy czy winik nie jest przypadkiem mniejszy od 1000 jesli tak to mamy
    //wynik
    cp b1,i
    cpc b2,w
    cpc b3,r
    brsh petla
    inc f
    add b1,przep
    adc b2,b4
    cp b1,i
    cpc b2,w
    brsh petla

    dalej:

    rcall bcd
    mov i , tbcd0
    andi i , lssb
    mov c1,i
    mov i, tbcd0
    andi i,mssb
    swap i
    mov c2,i
    mov i ,tbcd1
    andi i, lssb
    mov c3,i
    ldi i, 0b00000101
    out tccr0b , i
    clr i
    out tcnt0 , i

    mov w , f
    cpi w, 3
    in i ,sreg
    sbrc i,1
    sbi portb,0

    cpi w,2
    in i ,sreg
    sbrc i,1
    sbi portb,1

    cpi w, 1
    in i ,sreg
    sbrc i,1
    sbi portd,6



    ret

    waitms:

    clr i
    we7:
    nop nop nop nop
    nop nop nop nop
    nop nop nop nop
    nop
    inc i
    cpi i,235
    brne we7
    ret

    mnozenie:

    clr w
    ldi i, 0xff
    ldi b , 0xff

    mpy16u:   clr   b4      
       clr   b3
       ldi   r,16   
       lsr   w
       ror   przep

    m16u_1:   brcc   noad8   
       add   b4,i   
       adc   b4,b
    noad8:   ror   b4   
       ror   b3      
       ror   b2   
       ror   b1   
       dec   r   
       brne   m16u_1   



    ret

    bcd:


    ldi   i,16   ;Init loop counter   
       clr   tBCD1      
       clr   tBCD0      
       clr   ZH      ;clear ZH (not needed for AT90Sxx0x)
    bBCDx_1:lsl   b1      ;shift input value
       rol   b2      ;through all bytes
       rol   tBCD0      ;
       rol   tBCD1
       dec   i      ;decrement loop counter
       brne   bBCDx_2      ;if counter not zero
       ret         ;   return

    bBCDx_2:ldi   r30,AtBCD2+1   ;Z points to result MSB + 1
    bBCDx_3:
       ld   w,-Z   ;get (Z) with pre-decrement

       subi   w,-$03   ;add 0x03
       sbrc   w,3   ;if bit 3 not clear
       st   Z,w   ;   store back
       ld   w,Z   ;get (Z)
       subi   w,-$30   ;add 0x30
       sbrc   w,7   ;if bit 7 not clear
       st   Z,w   ;   store back
       cpi   ZL,AtBCD0   ;done all three?
       brne   bBCDx_3      ;loop again if not
       rjmp   bBCDx_1      




    znaki:
    .db 126
    .db 80
    .db 109
    .db 121
    .db 83
    .db 59
    .db 63
    .db 112
    .db 127
    .db 123
    .db 128
    .db 1
  • #13
    guuciek
    Level 14  
    Witam.
    Z góry przepraszam że pisze post pod postem ale mam nadzieję że tak uda mi się zwrócić uwagę ponieważ nie wiem już co robić . Założyłem drugiego (nowego) tinne-go i dalej jest to samo na obu wsadach (bascom i asm) . Już nie mam pojęcia co jest nie tak . Poniżej dorzucam wykres z pracy sygnału . Przebieg 2 to jest wejście enable do preskalera ( chwile przed podaniem go załączany jest counter który liczy do czasu aż na pinie pind.0 pojawi się "1") Przebieg 3 to przebieg jaki pojawia się na nóżce liczącej pind.5 (t1) o częstotliwości 1 MHz .
    Dodatkowo oba programy poprawnie reagują na zmianę pojemności tzn , przed pomiarem gaszą wyświetlacze i zapalają dopiero gdy na pind.0 pojawi się z powrotem jeden . I tak dla 50 nF trwa to mgnienie oka , natomiast dla 10 uf wyświetlacz gaśnie na ponad 2 sec .
    [ATTINY2313][BASCOM]Pomoc w obsłudze counter-a. Co nie tak?

    Pozdrawiam.
  • #14
    janbernat
    Level 38  
    Masz chyba błąd w założeniach konfiguracji Timera.
    Licznik ustawiony jako Counter po prostu liczy impulsy z zewnątrz- prescale nie powinno być- bo to nie jest Timer tylko Counter.
    Rejestr Capture też w tym wypadku jest użyty bez powodu- nie ma do niego żadnej obsługi przerwania a i zezwolenie na przerwanie nie jest ustawione.
    Zezwolenie na obsługę przerwania i procedurę obsługi masz tylko od przepełnienia licznika- czyli jak zliczy 65535 impulsów to przejdzie do obsługi przerwania.Zawsze.
    Czyli po pojawieniu się sygnału na nóżce STOP masz zatrzymać licznik, odczytać jego zawartość, wyzerować i puścić od początku- dbając aby się nie przepełnił- i tu ew. można wykorzystać przerwanie od przepełnienia.
    Zastosowanie do odczytu Bitwait oczywiście uniemożliwi działanie programu- Bitwait daje opóźnienie 25ms.
  • #15
    guuciek
    Level 14  
    Tak zgadza się , capture edge jest i prescaler jest to tylko akt desperacji :). Po prostu wersji w bascomie było bardzo dużo , żadna nie chciała działać. Wrzuciłem wersję z ostatniej próby , której założenie wyglądało "a może w końcu coś ruszy :/ "
    Próbowałem również po prostu counter, edge falling . Zawsze daje ten sam efekt . Gdy zliczy do 65535 przechodzi do przerwania i inkrementuje zmienną przep . Gdy pojawi się bit STOP . Licznik jest wyłączany , zmienna licznik jest mnożona przez ilość przepełnień * FFFF i dodawana jest wartość aktualna licznika .
    Po wykonaniu tego są jeszcze zakresy a potem ma po prostu wyświetlać te dane i czekać na następne wciśnięcie przycisku .

    Co do bitwait , sygnał startujący sygnał zegarowy to safe i strt . dopiero po ustawieniu tych 2 bitów pojawia się sygnał zegarowy(wcześniej załączam counter) . Counter działa równolegle do programu avr ( za wyjątkiem przerwania) . Po pojawieniu się STOP (1) na pin sygnał zegarowy już nie jest wysyłany (sygał stop jest również połączony z nogą clock enable preskalera) , więc 25 ms później licznik dalej ma taką samą wartość .
  • #16
    janbernat
    Level 38  
    Czyli tak:
    Code:

    If Pind.3 = 0 Then
     Pf = 0
      Nf = 0
      Uf = 0
    Timer1 = 0     'Timer= 0- ale dalej zlicza- bo przedtem nie było Stop Timer
    Przep = 0
    Bitwait Pind.3 , Set   'teraz proc. czeka 25ms- a timer dalej liczy te 1MHz
    Start Timer1           'No ale nie było stop- to dalej liczy- masło maślane
    Safe = 1
    Strt = 0
    bitwait pind.0 , set    ' dalej liczy przez 25ms
    Stop Timer1             ' teraz dopiero stop- ale co naliczył?
    Safe = 0
    Strt = 1
    Licznik = Przep * 65536
    Licznik = Licznik + Timer1
     

    To nie chodzi o to w jakim narzeczu piszesz (kompilatory są lepsze i gorsze) ale o zasady działania procesora.
    Datasheet jest darmo i plik pomocy po polsku do Bascoma ze strony MCSElectronics też jest darmo.
  • #17
    guuciek
    Level 14  
    Jak już pisałem nawet jeśli go nie wyłączyłem po inicjacji to nie liczy NIC ponieważ sygnał zegarowy pojawia się dopiero po linijce strt = 0 wtedy załącza się układ i pind.0 = 0 , potem liczy dopóki pind.0 = 1 (zależy od kondensatora) . Gdy na pind.0 pojawia się 1 , pojawia się równocześnie na clock enable preskalera (aktywowany stanem niskim) który przestaje wysyłać impulsy .
    Potem jest Stop timer1 czyli przestaje liczyć .
    We 1 lub 2 wersji kodu był ten stop timer1 zaraz po enable timer1 . Potem kod zaczął przybierać różne formy wedle zasady którą napisałem w wcześniejszym poście .

    Zamieszczam niedziałającą " poprawną wersję ".
    Code:
    $crystal = 4000000
    

    Config Portb = &B11111111 ; Portb = &B11111100
    Config Portd = &B01110010 ; Portd = &B01111001
    Config Timer0 = Timer , Prescale = 1024
    Config Timer1 = Counter , Edge = Falling
    On Timer0 Powerof
    On Timer1 Zeruj

    Enable Timer0
    Enable Timer1
    Enable Interrupts
    Start Timer0
    Stop Timer1


    W1 Alias Portb.4
    W2 Alias Portb.3
    W3 Alias Portb.2

    Ds Alias Portb.5
    Sh Alias Portb.7
    st alias portb.6

    Pf Alias Portd.6
    Nf Alias Portb.1
    Uf Alias Portb.0

    Strt Alias Portd.4
    Safe Alias Portd.1

    Dim A As Byte
    Dim B As Byte
    Dim I As Byte
    Dim Licznik As Long
    Dim Przep As Byte
    Dim S As String * 1
    Dim Liczby As String * 3
    Dim Cyfry(3) As Byte
    Dim Ter As Word


    Cyfry(1) = 10
    Cyfry(2) = 10
    Cyfry(3) = 10


    A = 1
    B = 0
    Licznik = 0
    Przep = 0

    Do
    If Pind.3 = 0 Then
    stop timer0 
    Ter = 0
       Pf = 0
       Nf = 0
       Uf = 0
       Timer1 = 0
       Przep = 0
       Bitwait Pind.3 , Set                                     'czekamy aż puszczę przycisk
       Start Timer1                                             ' startujemy timer1
       Safe = 1
       Strt = 0                                                 ' uruchamiamy genrator impulsów
       Bitwait Pind.0 , Set                                     ' gdy pind.0 = 1 generator przestaje dzialac
       Stop Timer1                                              'zatrzymujemy timer1
       Safe = 0
       Strt = 1                                                 'mnozymy ilosc przepelnien razy FFFF
       Licznik = Przep
       Licznik = Licznik * 65535
       Licznik = Licznik + Timer1                               ' dodajemy zawartośc licznika po ostatnim przepełniu

       If Licznik < 1000 Then                                   'jesli mniejszy od tysiaca zapalamy diode pF
          Set Pf                                                'jesli nie
       Else
          Licznik = Licznik \ 1000                              ' dzielimy przez 1000
          If Licznik < 1000 Then                                ' jesli mniejszy od 1000 zapalamy diode nf
             Set Nf
          Else                                                  ' jesli nie to dzielimy przez 1000
             Licznik = Licznik \ 1000                           '  zapalamy diode uf  , większe od tysiaca już nie bedzie
             Set Uf
          End If
          Liczby = ""
          If Licznik < 10 Then
             Liczby = "00"
          End If
          If Licznik < 100 And Licznik > 9 Then
             Liczby = "0"
          End If
        End If
        Liczby = Liczby + Str(licznik)                          ' rozdzielamy poszczegulne cyfry
        For B = 1 To 3
          S = Mid(liczby , B , 1)
          I = 4 - B
          Cyfry(i) = Val(s)
        Next B
    start timer0
    End If

    If A = 3 Then
    A = 1
    Else
    Incr A
    End If

    Gosub Wyslij

    Select Case A
    Case 1:
    Reset W1
    Case 2 :
    Reset W2
    Case 3 :
    Reset W3
    End Select




    Waitms 4
    Gosub Rst
    Waitms 1

    Loop

    End

    Wyslij:
       I = Lookup(cyfry(a) , Dta)

       For B = 0 To 7


       If I.b = 1 Then
       Set Ds
       Else
       Reset Ds
       End If
       Reset Sh
       Set Sh
       Next B
       Reset St
       Set St
    Return

    Rst:
      W1 = 1
      W2 = 1
      W3 = 1

    Return


    Zeruj:

    Incr Przep
    Return





    Powerof:                                                    ' po 30 sec bezczynnosci gasnie wyswietlacz
    Incr Ter                                                    ' zaswieca sie po ponownym wcisnieciu przycisku
    If Ter = 300 Then
    Gosub Rst
    Stop Timer0
    Ter = 0
    Bitwait Pind.3 , Reset
    Bitwait Pind.3 , Set
    Waitms 10
    Bitwait Pind.3 , Set
    Start Timer0
    End If
    Return


    Dta:
     Data 126 , 80 , 109 , 121 , 83 , 59 , 63 , 112 , 127 , 123 , 128 , 0
  • #18
    janbernat
    Level 38  
    Zacznijmy od pierwszych trzech linijek.
    Nie ma $regfile=
    Ustawiasz PortB jako wyjście.
    Ustawiasz dwa najmłodsze piny w stan niski.
    Ale nie wiadomo co się ustawi bo instrukcje oddzielasz średnikiem(; ) a nie dwukropkiem(: ).
    Kompilator nie ostrzega tylko robi jakieś bzdury- np. ustawia wszystkie piny w stan niski.
    Potem tu:
    W1 Alias Portb.4
    W2 Alias Portb.3
    W3 Alias Portb.2
    ustawiasz aliasy jako stan wyjść portu i odczytujesz stan rejestru wyjściowego a nie stan PINb.x.
    Każdy port ma trzy rejestry- kierunku, podciągania i stanu.
    Powinieneś ustawić te piny jako wejścia i dopiero wtedy odczytywać ich stan z PINB.x
    Naprawdę help po polsku jest do ściągnięcia.
  • #19
    guuciek
    Level 14  
    Z helpa bascoma (nawet nie bolało :)) :
    "; Średnik – rozdziela argumenty instrukcji wejścia/wyjścia "
    Zawsze mi działały instrukcje zapisane w ten sposób . Ale zmieniłem bo może jednak jest źle . Dalej nie działa więc to nie w tym problem .

    Drugi błąd to nie błąd ponieważ jak można znaleźć wyżej końcówki te są ustawiane jako WYJŚCIA więc nie mogą być sterowane z rejestru pin jedynie z rejestru port . :)

    Zwracam jednocześnie uwagę że równolegle z wsadem w bascomie napisałem program w asm który działa bez zarzutów poza tym że również nie zlicza impulsów. I to jest w tym wszystkim dziwne , ponieważ testowane było na 2 procesorach ( jeden z zapasów , drugi ze sklepu nowy ) . Dorzucam schemat i płytkę układu dla jasności . Może schemat nie najpiękniej poukładany ale został zrobiony tylko po to aby ułożyć płytkę , jak program ruszy to wszystko poukładam opiszę i wstawię całą paczkę na forum .
  • #20
    janbernat
    Level 38  
    Konfiguracja portów to nie są operacje wejścia/wyjścia.
    Dalej nie działa- chociaż jeden problem poprawiony.
    ldi i,0b01010010 a w Bascomie &B01110010
    out ddrd , i
    ldi i,0b01011001 a w Bascomie &B01111001
    out portd,i
  • #21
    guuciek
    Level 14  
    Witam ponownie .
    Tak i tutaj rzeczywiście jest błąd jeśli chodzi o bascoma i DDRD . Pin.5 ( t1) dałem jako wyjście zamiast wejście . Po prostu chciałem zmienić podciąganie tego pinu i nie wiem czemu wpisałem w oba rejestry (1) . Jednak dalej nie działa . Zaczynam powoli rezygnować z countera , i zliczać impulsy przerwaniem int0 albo int1 , zmniejszając częstotliwość sygnału do 0,5 MHz i mnożąc wynik w programie przez 2 . Chociaż z drugiej strony ciekawy jestem czemu ten counter nie chce ruszyć .
  • #22
    grysek
    Level 19  
    W Twoim programie w asm nie widzę odkładania na stos adresu powrotu podczas przerwań. Program może przez to się gubić.

    Dodano po 27 [minuty]:

    Poprawiłem troche Twój kod w asm. W symulacji licznik pięknie zlicza jeśli nie bedzie działało to będzie oznaczało ze problem jest z wyświetlaniem. Spróbuj teraz :P
  • #23
    guuciek
    Level 14  
    Z tego co mi wiadomo podczas ustawienia flagi przerwania procesor sam zapisuje adres powrotu do stosu następnie przeskakuje do etykiety przerwania . Na symulatorze również nadpisywany jest adres stosu (+2)
    a po reti (-2) mimo iż sam nic na stos nie zapisuję . Program również powraca do właściwego adresu .
    Z książki Mikrokontrolery AVR w praktyce :
    "Skok do procedury obsługi (przyp.przerwania ) odbywa się zawsze ze śladem (adres powrotu odkładany na stosie ) . Po zakończeniu działań sterowanie jest przekazywane do miejsca w którym wystąpiło żądanie obsługi "

    Edit:
    Załadowałem twój program i nie za bardzo chodzi tka jak powinien , cały czas wyświetla 26 , po wciśnięciu przycisku zaczyna procedurę poprawnie lecz nie czeka na puszczenie przycisku , po wykonaniu obliczeń na cześć sekundy pojawia się 000 potem z powrotem 26 . Tak samo nie chce wchodzić w stan uśpienia . (timer0) .
    Co do tych pop i push to jakoś nie mogę ich ogarnąć , przecież :
    1 . Adres aktualnej pozycji nie jest zapisywany w rejestrze Z tylko PC .
    2. Zapisujesz ten adres gdy już jesteś w podprogramie czyli zapisujesz adres podprogramu (jeśli odwołujesz się do PC , jeśli do Z to zapisujesz 0 i odczytujesz też zero chyba że wcześniej było coś wpisane do tego rejestru ) .
    Gdy włączę mój program na symulatorze (strasznie nie lubię tego symulatora) też wszystko ładnie zlicza . Ale w rzeczywistości jest inaczej .

    Mimo wszystko dzięki za zainteresowanie .
  • #24
    guuciek
    Level 14  
    Okazuje się że w moim przypadku były to jakieś błędy kompilatora lub wadliwa wersja procesora .
    Problem udało się rozwiązać dwukrotnie wpisując te same dane do rejestrów sterujących .
    tj. np.
    ldi a , 10
    out tccr1b , a
    nop
    nop
    out tccr1b , a