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

Atmega8 - Konflikt Timer0 i Print przy odczycie impulsatora RS232

Roburr 18 Mar 2006 09:20 1275 4
REKLAMA
  • #1 2427650
    Roburr
    Poziom 21  
    Posty: 550
    Pomógł: 1
    Ocena: 15
    Program ma odczytywać dane z impulsatora i wysyłać je poprzez RS232 do komputera. Dane mają być wysyłana co: 0,5ms lub 1ms lub 2ms lub 4ms(domyślnie mam przerwanie co 250us a czas po którym wysyłam dane to 4ms). A po 5 sekunach pomiar ma zostać zakończony. Wszystko działa jak należy jednak są jakieś problemy z Timerem. Przypuszczam że instrukcja Print z racji tego że działa na przerwaniu blokuje mi Przerwanie Timera i czas końca pomiaru czas jest wiekszy niż 5s. Po drugie nawet jak w miejscu Load Timer0 = 250 wpisze wartość 50 to czas ten się nie skraca. Wszystko jest dobrze jak wyrzuce linijkę Print Wysylana. Wyglada na to że wysyłanie instrukcją Print przeszkadza przerwaniu Timera. Prosze o pomoc, Poniżej zamieszczam kod:

    $regfile = "m8def.dat"
    $crystal = 8000000
    $baud = 38400
    Config Com1 = Dummy , Parity = None , Stopbits = 1 , Databits = 8


    Config Pind.2 = Input
    Config Pind.3 = Input
    Config Pind.4 = Input
    Config Pind.5 = Input
    Config Pind.6 = Input
    Config Pind.0 = Input
    'Config Adc.7 = Output
    Config Pinb.0 = Output
    Config Pind.7 = Output
    Config Pind.1 = Output
    Config Timer0 = Timer , Prescale = 8

    On Timer0 Cykl

    Dim Czas1 As Byte
    Dim Czas3 As Integer
    Dim Czas2 As Word
    Dim Probkowanie As Integer
    Dim Wysylana As Integer
    Dim Kierunek As Bit
    Dim A As Byte
    Dim Zmienna As Byte
    Dim Af As Bit

    'Led_koniec Alias Portd.1
    Led_konfiguracja Alias Portb.0
    Led_pomiar Alias Portd.7
    Txd Alias Portd.1
    Konfiguracja Alias Pind.2
    Pomiar Alias Pind.3
    I1 Alias Pind.4
    I2 Alias Pind.6

    Poczatek:

    'inicjalizacja
    Reset Led_konfiguracja
    Reset Led_pomiar
    Wait 1
    Set Led_konfiguracja
    Set Led_pomiar
    Czas1 = 0
    Czas2 = 0
    Czas3 = 0
    Input "Podaj czas: " , Zmienna

    Reset Led_konfiguracja
    Select Case Zmienna
    Case 1:
    Print "Cykl 0.5ms "
    Probkowanie = 4
    Case 2:
    Print "Cykl 1ms "
    Probkowanie = 8
    Case 3:
    Print "Cykl 2ms "
    Probkowanie = 16
    Case 4:
    Print "Cykl 4ms "
    Probkowanie = 31

    Case Else : Goto Poczatek

    End Select


    Wait 1

    Print "Nacisnij START "

    Set Led_konfiguracja


    Do

    If Pomiar = 0 Then
    Enable Interrupts
    Enable Timer0
    Load Timer0 = 250
    Exit Do
    End If

    Loop
    'glowna petla
    'obsluga impulsatora
    Wysylana = 0
    Do

    If I1 = 1 And I2 = 1 Then 'impulsator w pozycji - zwarte
    Af = 1
    End If

    If I1 = 0 And I2 = 0 Then
    Af = 0
    End If


    If I1 = 0 And I2 = 1 Then
    If Af = 1 Then
    Do
    If I2 = 0 Then Exit Do

    Loop
    Incr Wysylana

    Else
    Do
    If I1 = 1 Then Exit Do
    Loop
    Decr Wysylana
    End If
    End If


    If I1 = 1 And I2 = 0 Then
    If Af = 1 Then
    Do
    If I1 = 0 Then Exit Do
    Loop
    Decr Wysylana

    Else
    Do
    If I2 = 1 Then Exit Do
    Loop
    Incr Wysylana
    End If
    End If
    Loop


    'przerwanie 1uS
    Cykl:
    Load Timer0 = 250
    Incr Czas1

    If Czas1 = 8 Then
    Czas1 = 0
    Incr Czas2
    Print Wysylana
    Wysylana = 0
    End If


    If Czas2 = 1250 Then
    Czas1 = 0
    Print "koniec"
    Wysylana = 0
    End
    End If


    Return
  • REKLAMA
  • #2 2430367
    jacobsek
    Poziom 22  
    Posty: 419
    Pomógł: 61
    Ocena: 24
    nie możesz używać instrukcji load timer=
    jeśli chcesz w ten sposób to tak:load timer0,250(to daje do odliczenia 250 cykli) lub counter0=6 co też daje tyle samo do odliczenia czyli 250 cykli, to jeden z problemów z Twoim tajmerem

    Dodano po 3 [minuty]:

    Zapamiętaj zasadę, instrukcja load timer oblicza sama ilość cykli zliczanych do wystąpienia (tyle ile wpiszesz po przecinku tyle będzie zkliczonych cykli do przepełnienia)przepełnienia a instrukcja counter nie oblicza więc trzeba to zrobić samemu wg zasady pojemność licznika - wartość początkowa = ilość cykli zliczonych do przepełnienia.
  • REKLAMA
  • #3 2431261
    jacobsek
    Poziom 22  
    Posty: 419
    Pomógł: 61
    Ocena: 24
    A co ma zrobić program jeśli opuści tę ostatnią pętlę do loop?
  • REKLAMA
  • #4 2433998
    Roburr
    Poziom 21  
    Posty: 550
    Pomógł: 1
    Ocena: 15
    Ta pętla??:
    Do

    If Pomiar = 0 Then
    Enable Interrupts
    Enable Timer0
    Load Timer0 = 250
    Exit Do
    End If

    Loop

    Czeka na sygnał z przycisku na rozpoczęscie pomiaru.

    Dlaczego nie mogę używać Load Timer0 = 250?? Przecież jak chce odmierzyć 250uS to muszę tam wpisać wartość 250 prawda?? No ale co z tym RS232? czy on czasem nie blokuje przerwania Timer0 podczas nadawania??
  • #5 2439413
    jacobsek
    Poziom 22  
    Posty: 419
    Pomógł: 61
    Ocena: 24
    Raz jeszcze:
    Load timer służy owszem do załadowania wartości początkowej ale w postaci- "load timer0,250"
    wtedy odlicza on 250 cykli,ze znakiem równości używasz tylko jeśli dajesz polecenie "counter0=250" i wtedy w tajmer0 zostaje umieszczona wartość początkowa=250 czyli odliczy tylko 6 cykli do przepełnienia.
REKLAMA