logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[atiny2313][asm]Licznik impulsów

bulek01 26 Cze 2010 22:04 1332 1
REKLAMA
  • #1 8235062
    bulek01
    Poziom 15  
    Witam!
    Pisze właśnie program w asm który będzie liczył impulsy o opadającym zboczu podawane na wejście licznika T1 i je wyświetlał na wyświetlaczu diodowym.I mam jeden drobny problem ponieważ wyświetlacz ma 3 segmenty więc po policzeniu do 999 następne powinno być zero.I gdy zwiększam programowo co 1 sekundę wartość rejestru z liczbą o 1 to po przekroczeniu 999 wszystko ładnie liczy od zera.Ale jeśli w pętli nieskończonej przepisuje wartość licznika T1 to procedura wyświetlania po przekroczeniu 999 niby go zeruje, ale w rzeczywistości nie liczy od zera tylko od 769.I nie mam pojęcia dlaczego.Oto kod:
    .include "tn2313def.inc"
    
    .def temp	= r16
    .def temp2	= r17
    //Wartosc wyswietlana
    .def liczbaL = r6
    .def liczbaH = r7
    //////////////
    .def tempL = r8
    .def tempH = r9
    //////////////
    .def seg = r20
    //Kopia liczby uzywana do wyswietlania
    .def kopiaH = r25
    .def kopiaL = r24
    /////////////////////////////
    .equ CSETEK = PD3
    .equ CJEDNOSCI = PD0
    .equ CDZIESIATEK = PD6
    .equ WEJSCIE = PD5
    /////////////////////////////
    .cseg
    .org 0x00
    rjmp start
    .org 0x000d
    rjmp pomiar
    start:
    
    //////////////////////////////////////////////
    //////////////KONFIGURACJA PORTÓW/////////////
    //////////////////////////////////////////////
    ldi temp,0xff
    //PORTB zwarcie do masy zaświeca wybrany element cyfry
    out DDRB,temp ;port b jako wyjscie
    out PORTB,temp ;zgaszenie wyswietlacza
    ///////////////////////////////////////////////
    
    //KONFIGURACJA PORTUD
    //USTAWIENIE SEGMENTOW JAKO WYJSCIA
    //A JAKO WEJSCIE TO WEJSCIE LICZNIKA IMPULSOW
    ldi temp,(1<<CSETEK|1<<CDZIESIATEK|1<<CJEDNOSCI|0<<WEJSCIE) //Zalaczanie segmentow wystwetlacza
    out DDRD,temp ;
    
    //WEJSCIE PODCIAGNIETE DO PLUSA
    sbi PORTD,WEJSCIE
    
    //WKSAŹNIK STOSU USTAWIAMY NA KONIEC PAMIECI
    ldi temp, RAMEND
    out SPL, temp ;ustawienie wskaznika stosu
    
    /////////////////////////////////////////////
    /////////////////////////////////////////////
    /////////////////////////////////////////////
    
    /////////////////////////////////////////////
    ///////////KONFIGURACJA LICZNIKÓW
    /////////////////////////////////////////////
    //////////////////////////////////////
    //Preskaler na clk/8 dla timera0
    //Sluzy do wykonywania pomiaru
    ldi r16,(1<<CS02|1<<CS00)
    out TCCR0B,r16
    //////////////////////////////////////
    
    //TIMER1 JAKO LICZNIK IMPULSOW(OPADAJACE ZBOCZE)
    ldi temp,(1<<CS12|1<<CS11)
    out TCCR1B,temp
    ///////////////////////////////////
    
    
    //Wlaczenie przerwan 
    //TOIE0 od przepelnienia do wykonywania pomiaru
    ldi r16,(1<<TOIE0)
    out TIMSK,r16
    ////////////////////////////////////
    
    sei ;zezwolenie na przerwania
    
    clr seg
    clr liczbaL
    clr liczbaH
    
    //Watchdog
    ///////////////////////////////////////////////////////
    //WDR
    //ldi temp,(1<<WDE|1<<WDP2|1<<WDP1)
    //////////////////////////////////////////////////////////
    ////Koniec ustawień
    //////////////////////////////////////////////////////////
    petla:
    rcall wyswietl
    rcall wyswietl
    rcall wyswietl
    in liczbaL,TCNT1L
    in liczbaH,TCNT1H
    rjmp petla
    
    
    //////////////////////////////////////////////////////////
    /////Obsługa wysiwetlacza
    //////////////////////////////////////////////////////////
    wyswietl: //Wyswietlanie zawartości liczby
    ////
    ldi ZH,high(znaki<<1)
    ldi ZL,low(znaki<<1)
    //WDR
    cpi seg,0
    breq setki
    cpi seg,1
    breq dziesiatki
    cpi seg,2
    breq jednosci
    //Jesli seg jest poza tymi wartosciami to zakoncz
    clr seg
    ret
    
    setki:
    mov kopiaL,liczbaL
    mov kopiaH,liczbaH
    //Sprawdzamy czy wieksza od 1000
    ldi temp,0xe8
    ldi temp2,0x03
    cp kopiaL,temp
    cpc kopiaH,temp2
    brcs sprawdx_setki //Skok jesli zmniejszy
    clr liczbaL
    clr liczbaH
    clr kopiaL
    clr kopiaH
    clr temp
    out TCNT1L,temp
    out TCNT1H,temp
    sprawdx_setki:
    clr temp
    cpi kopiaL,100
    cpc kopiaH,temp
    brcs end1//Skok jesli mniejszy
    ldi temp,1
    add ZL,temp
    clr temp
    adc ZH,temp
    sbiw r25:r24,63 //Odejmujemy 100 od liczby
    sbiw r25:r24,37 //Odejmujemy 100 od liczby
    rjmp sprawdx_setki
    end1:
    lpm
    cbi PORTD,PD0 //Wylaczamy poprzedni segment
    sbi PORTD,PD3 //Wlaczamy segment setek
    out PORTB,r0
    inc seg
    ret
    
    dziesiatki:
    cpi kopiaL,10
    brcs end2 //Skocz jesli mniejsze
    clr temp
    petelka1:
    inc temp
    subi kopiaL,10
    cpi kopiaL,10
    brcc petelka1 //Skok jesli wieksze lub równe
    add ZL,temp
    clr temp
    adc ZH,temp
    end2:
    lpm
    cbi PORTD,PD3 //Wylaczamy poprzendi segment
    sbi PORTD,PD6 //Wlaczane segment dziesiatek
    out PORTB,r0 //Wyswietlamy cyfre
    inc seg
    ret
    
    jednosci:
    clr temp
    add ZL,kopiaL
    ADC ZH,temp
    lpm
    cbi PORTD,PD6 //Wylaczamy poprzedni segment
    sbi PORTD,PD0 //Wlaczamy segment jednosci
    out PORTB,r0
    clr seg
    ret
    ///////////////////////////////////////////////////
    ///////////////////////////////////////////////////
    pomiar:
    /*push temp
    in temp,SREG
    push temp
    ldi temp,1
    add liczbaL,temp
    clr temp
    adc liczbaH,temp
    pop temp
    out SREG,temp
    pop temp*/
    reti
    
    znaki:
    .db 0b00101000,0b11101011,0b00110010,0b10100010,0b11100001,0b10100100,0b00100100,0b11101010,0b00100000,0b10100000,0
    

    Tak wygląda sprawdzanie czy liczba jest większa od 1000
    //Sprawdzamy czy wieksza od 1000
    ldi temp,0xe8
    ldi temp2,0x03
    cp kopiaL,temp
    cpc kopiaH,temp2
    brcs sprawdx_setki //Skok jesli zmniejszy
    clr liczbaL
    clr liczbaH
    clr kopiaL
    clr kopiaH
    clr temp
    out TCNT1L,temp
    out TCNT1H,temp
    sprawdx_setki:
  • REKLAMA
  • #2 8237844
    bulek01
    Poziom 15  
    Już wymyśliłem jak to zrobić, aby działało po prostu dwa razy pod rząd zeruję licznik.O tak:
    //Sprawdzamy czy wieksza od 1000
    ldi temp,0xe8
    ldi temp2,0x03
    cp kopiaL,temp
    cpc kopiaH,temp2
    brcs sprawdx_setki //Skok jesli zmniejszy
    clr liczbaL
    clr liczbaH
    clr kopiaL
    clr kopiaH
    in temp,sreg
    push temp
    cli
    clr temp
    out TCNT1L,temp
    out TCNT1H,temp
    
    pop temp
    out sreg,temp
    in temp,sreg
    push temp
    cli
    clr temp
    out TCNT1L,temp
    out TCNT1H,temp
    
    pop temp
    out sreg,temp
    
    sprawdx_setki:
    Przy okazji dodałem jeszcze drobne poprawki.
    Niby problem rozwiązałem, ale chciałbym wiedzieć, dlaczego to nie działa gdy raz zeruje licznik tylko muszę dwa razy?
REKLAMA