Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Atm16,Bascom. Jak zrealizować kilkakrotną zmianę stanu portu

karolczyzycki 28 Wrz 2009 23:07 5778 76
  • #1 28 Wrz 2009 23:07
    karolczyzycki

    Poziom 20  

    Witam,
    Napisałem kawałek programu który ma generować przebieg na porcie b.0
    około 9ms - stan wysoki
    około 4,5ms - stan niski
    Użyłem do tego licznika, żeby odmierzał czas, dokładność tutaj akurat nie ma znaczenia.
    Problem w tym że nie działa to jak należy, tzn wykonuje się tylko jeden podprogram.
    Wiem że jest coś nie tak, bo po przepełnieniu licznika, wykonuje się znów ten sam podprogram.
    Jak zrobić żeby ustawić port jako "1" na jakiś czas, później zmienić na "0" na jakiś czas itd itd...

    Nie mam pomysłu na ten program...
    Jak można zrealizować, kilkakrotną zmiane stanu portu?
    Może być na podprogramach?


    Code:
    $regfile = "m16def.dat"
    
    $crystal = 16000000                                         

    dim a as single
    Config Timer1 = Timer , Prescale = 1
    enable interrupts
    enable timer1
    on timer1 sygnal1
    cls

    Do
    loop                                                                                                   
    End


    sygnal1:

    timer1 = 65535
    incr a
    portb.0 = 1

     IF a = 308 then
       stop timer1
       a = 0
       goto sygnal2
     end if

    return


    sygnal2:

    start timer1
    timer1 = 65535
    incr a
    portb.0 = 0
     IF a = 150 then
       stop timer1
       a = 0
       goto koniec
    end if

    return


    koniec:
    portb.0 = 1
    end

    0 29
  • Pomocny post
    #2 28 Wrz 2009 23:32
    atom1477
    Poziom 43  

    Wychodzisz z przerwania za pomocą GoTo. To jest problem.
    Ostatecznie nawet by to działało, ale przed GoTo musiał byś ręcznie zdejmować trochę rzeczy ze stosu. Ale grzebanie w stosie to raczej nie najlepszy pomysł.
    Musisz kompletnie zmienić koncepcję programu.

    0
  • #3 29 Wrz 2009 17:24
    karolczyzycki

    Poziom 20  

    A jakąś podpowiedz? Czy może to być na podprogramach?

    0
  • Pomocny post
    #4 29 Wrz 2009 18:58
    atom1477
    Poziom 43  

    Jeżeli to ma nic nie robić tylko generować impulsy, to po prostu może użyj Waitms.

    A jeżeli nie, zmieniaj wartość porównania w zależności od dodatkowej zmiennej. Np:

    Code:

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

    Dim A As Word    'Zmienna zwiększana i porównywana.
    Dim B As Byte     'Zmienna decydująca z jaką wartością będzie porównywana zmienna A.
    Config Timer1 = Timer , Prescale = 1
    Enable Interrupts
    Enable Timer1
    On Timer1 Sygnal1
    Cls

    Do
    Loop                                                                                                   
    End


    Sygnal1:
        Timer1 = 65535    'Nie wiem po co to, ale niech będzie
        Incr A

        If B = 0 Then
            If A >= 100 Then
                A = 0
                B = 1
                PortB.0 = 1
            End If
        Else
            If A >= 200 Then
                A = 0
                B = 0
                PortB.0 = 0
            End If
        End If
    Return


    Pisałeś to w BASCOMie? Dlaczego masz wszystko z małych liter. BASCOM automatycznie formatuje na duże litery.



    PS. Coś takiego:
    Code:

    Dim A As Single

    Incr A
    ...
    ...
    Incr A

    If A = 380 Then
    ...


    Nie zadziała. To taka mała rada przyszłość.

    0
  • #5 30 Wrz 2009 00:35
    karolczyzycki

    Poziom 20  

    To jest program który powinien wygenerowac na portb.0 "1" na czas 9ms.

    Code:
    $regfile = "m16def.dat"
    
    $crystal = 16000000                                     

    Dim A As Word    'Zmienna zwie;kszana i porównywana.
    Dim B As Byte     'Zmienna decyduja;ca z jaka; wartos'cia; be;dzie porównywana zmienna A.
    Config Timer1 = Timer , Prescale = 1 : Enable Interrupts : Enable Timer1 : On Timer1 Sygnal1

    b = 0
    a = 0
    PortB.0 = 0

    Do
    Loop
    End

    Sygnal1:
    Timer1 = 65376   'laduje do timera 65376 dla jednostki 10us (160 cylki x 0,0625us)
    Incr A

         If B = 0 Then
                  PortB.0 = 1                         ' na porcie pb.0 pojawi sie 1 na 9ms
                  If A >= 900 Then                 ' 10us * 900 = 9ms
                      A = 0                           
                      B = 1
                      goto koniec
                  end if
         End If

    Return

    koniec:
    portb.0 = 0
    end


    Jest to tylko teoria, bo rzeczywiście czas mierzony na oscyloskopie różni się i to sporo...
    W związku z tym nasuwa mi się kilka pytań:
    Nie wiem czy to słaba dokładność kwarca, czy ja coś robię źle...

    1. Czy dobrze obliczam czas?
    Dla:
    Częstotliwość: 16 MHz
    Prescale: 1
    Ilość cykli: 65536 (timer1)
    Czas taktu: 0,06250 us

    - jeśli 1 takt, to 0,0625us, więc 10us wynosi 160 taktów
    żeby procesor wykował 160 taktów muszę załadować 65376

    2. Czy za każdym razem jeśli w kodzie zmieniam wartość zegara, to w opcjach BASCOM też muszę zmienić?

    3. Czy z rezonatora 16MHz (zewn.) mogę taktować 1MHz'em? to się ustawia tylko fusebitami?

    4. Muszę uzyskać dokłądny czas 10us (który będę sobie później mnożył np razy 56, dla uzyskania 560us)
    Czy jest jakaś różnica w dokładności jeśli użyję oscylatora 1Mhz a 16MHz? (oczywiście resztę parametrów dobiorę do czasu 10us)

    0
  • Pomocny post
    #6 30 Wrz 2009 01:08
    atom1477
    Poziom 43  

    1. Ogólnie liczysz dobrze, ale procesor nie wyrobi się w 160-ciu cyklach (a dokłądniej mówiąc to liczysz trochę źle bo własnie nie uwzględniasz czasu potrzebnego na obsługę przerwania).
    Nie uzyskasz czasu 10us, nawet dla kwarca 16MHz. Musiał byś to napisać w assemblerze i użyć dyrektywy Nosave.

    2. Nie. Jeżeli coś zadeklarujesz w programie to ta rzecz ustawiona w opcjach BASCOMa jest olewana.

    3. Nie bardzo rozumiem pytanie.

    4. Dla 1MHz nie uzyskasz tego. Procesor miał by tylko 10 taktów pomiędzy przerwaniami. Choćby nic nie robił, nawet nie zachowywał rejestrów na stos, to się nie wyrobi, bo wejście to ze 4 takty, wyjście kolejne 4 a do tego jeszcze musi coś w programie głównym robić (zawsze przed kolejnym wejściem do przerwania wykonuje co najmniej jeden rozkaz w programie głównym, przynajmniej tak mi się wydaje). Czyli 9 albo więcej taktów jest mu potrzebne. Więc absolutnie NIC nie zostanie mu na obsługę przerwania.
    Musi być o wiele więcej. 16MHz będzie akuratne, ale nadal czasu jest mało i trzeba się ratować assemblerem.

    Ja bym się nastawiał na czas 100us.

    0
  • #7 30 Wrz 2009 09:41
    karolczyzycki

    Poziom 20  

    Co do pytania 3, to chodzi mi o to że w procesorze mogę ustawić zegar, albo 1 labo 4 albo 8.
    A jeśli mam zewnętrzny kwarc 16, to można procesor taktować mniejszym zegarem np. 8 MHz'ami czy tylko taką prędkością jaki mam kwarc?

    Ja muszę mieć najmniejszą jednostkę 10us, bo potrzebny mi to jest do generowania kodu NEC.
    A np. logiczne zero w NECu to 560us wysoki i 560us niski.
    Żeby mieć liczbę całkowitą, to muszę użyć 10us.

    0
  • Pomocny post
    #8 30 Wrz 2009 12:26
    atom1477
    Poziom 43  

    No jak masz kwarca 16MHz, to tylko 16MHz może być.
    No chyba że to będzie ATMega168, to wtedy tak. Bo ATMega168 ma preskaler głównego zegara.

    Jak chcesz 10us, to tylko assembler i kwarc 16MHz.

    0
  • #9 30 Wrz 2009 13:00
    karolczyzycki

    Poziom 20  

    Ale mogę pisać to w bascomie a zrobić gdzie trzeba wstawki z asm?
    Czy cały progrma w asm?

    0
  • Pomocny post
    #10 30 Wrz 2009 13:09
    atom1477
    Poziom 43  

    Wystarczy wstawka. Samo przerwanie w asm.

    0
  • #11 30 Wrz 2009 13:53
    karolczyzycki

    Poziom 20  

    Przerwanie czyli to co procesor ma wykonać w czasie jednego cyklu?
    Tzn to wszystko: inf, then, tą pętlę zamienic na kod asm?
    Bo rozumiem że to są komendy które zajmują kilka cykli?

    0
  • Pomocny post
    #12 30 Wrz 2009 16:09
    atom1477
    Poziom 43  

    Przerwanie czyli to co masz pomięrzy Sygnal1: a Return.
    To raczej zajmie więcej cykli ;p
    Mniej więcej trzeba zrobić tak jak piszesz.

    0
  • Pomocny post
    #13 30 Wrz 2009 16:44
    landy13
    Poziom 29  

    karolczyzycki napisał:

    A np. logiczne zero w NECu to 560us wysoki i 560us niski.
    Żeby mieć liczbę całkowitą, to muszę użyć 10us.

    Czemu nie można ustawić przerwania od razu co 560µs?

    0
  • #14 30 Wrz 2009 16:50
    karolczyzycki

    Poziom 20  

    ale u mnie jest problem w tym że przesunięcie występuje jeszcze przed etykietą signal.
    Tzn. jak laduje do licznika liczbę 65376 (zeby procesor wykonal 160 cykli, dla 10us) to nawet bez IF, już na oscyloskopie widać że to nie jest dokładnie 10us.


    Skoro wg Ciebie przesunięcie powodują komendy po signal, to taki kod powinien wygenereować "1" na 10us.
    Dobrze?

    Code:
    $regfile = "m16def.dat" 
    
    $crystal = 16000000                                     

    Config Timer1 = Timer , Prescale = 1 : Enable Interrupts : Enable Timer1 : On Timer1 Sygnal1

    PortB.0 = 0

    Do
    Loop
    End

    Sygnal1:
    Timer1 = 65376   'laduje do timera 65376 dla jednostki 10us (160 cylki x 0,0625us) 
     PortB.0 = 1
    goto koniec                           
    Return

    koniec:
    portb.0 = 0
    end


    landy13 -> 560us to tylko przy "0"
    np. logiczna jedynka to 560us wysoki i 1690us niski

    A to juz jest problem bo nie da się podzielić 1690 przez 560 bez reszty...
    Dlatego jedyna największa jednostką jaką mogę używac to 10us.
    Mnożąc 10us razy 56 mam 560, razy 169, mam 1690 itd

    0
  • Pomocny post
    #15 30 Wrz 2009 17:14
    landy13
    Poziom 29  

    karolczyzycki napisał:

    A to juz jest problem bo nie da się podzielić 1690 przez 560 bez reszty...
    Dlatego jedyna największa jednostką jaką mogę używac to 10us.
    Mnożąc 10us razy 56 mam 560, razy 169, mam 1690 itd


    3*560=1680 To tylko 0,5% mniej od 1690. Każdy odbiornik to łyknie.

    0
  • #16 30 Wrz 2009 17:19
    karolczyzycki

    Poziom 20  

    Ale mam tam napisane że to ma być częstotliwość 36kHz.
    Nie bardzo to rozumiem, czyli mam nadawać stan wysoki z częstotliwością 36kHz przez 560us?

    0
  • Pomocny post
    #17 30 Wrz 2009 17:23
    landy13
    Poziom 29  

    karolczyzycki napisał:
    czyli mam nadawać stan wysoki z częstotliwością 36kHz przez 560us?

    Otóż to. Tylko nie stan wysoki a nośną 36 kHz.

    0
  • Pomocny post
    #18 30 Wrz 2009 18:15
    atom1477
    Poziom 43  

    A nie lepiej zapuścić Timer w trybie CTC żeby generował nośną 36kHz na swoim pinie OCxx?
    I jakimś innym Timerem albo nawet programem głównym za pomocą Waitms-ów włączać i wyłącza pin OCxx?
    Prostsze i łatwiejsze do zrobienia. I tak właśnie się zwykle robi.

    0
  • Pomocny post
    #19 30 Wrz 2009 18:47
    landy13
    Poziom 29  

    I jeszcze jedno. Napisał Ci atom1477:

    Cytat:
    Wychodzisz z przerwania za pomocą GoTo. To jest problem.

    to go słuchaj, bo to mądry człowiek jest. Powtórzyłeś ten błąd we wszystkich programach w tym temacie.

    0
  • Pomocny post
    #20 30 Wrz 2009 19:23
    epoxer
    Poziom 12  

    Karol, miałem Ci napisać :P przez komunikator.. :D ale pisze tu.. może się przydać komuś :) pierwsze co to podam Ci pętle na 1us :) przy 16MHz w kodzie ASM

    Code:

    $asm
      ldi R21, 0
      delay_1us:
        inc R21             
        cpi R21, 4       
      brlo delay_1us
    $end asm


    lub pisany kod z głowy :P ale jeszcze do udoskonalenia... :P całego przerwania na podstawie ostatniego Twojego skrawka kodu... :P

    na Pinie 0 w porcie B pojawi się stan wysoki na dokładnie 9us :)

    UWAGA! to kod dostosowany do 16MHz :P
    Code:

    $asm
    ;gdzies po za przerwaniem
    ; Rejestr r22 ma wartosć 0
    clr R22
    ldi R20, 0xff
    out DDRB, R20 ; ustawienie Portu B jako wyjscia

    ;nastepnie wstawka w przerwaniu... :)
    cpi R22, 0          ; sprawdzam czy r22 = 255 (1 cykl)
    brlo zero             ;jezeli mniejsze to skocz do zero (2 cykle)
               ;w przeciwnym razie pomin skok i jedziemy dalej... ;P (1 cykl)
    ldi R20, (1<<PINB0) ;podnosimy stan pinu 0 na wysoki (1 cykl)
    out PORTB, R20      ; przesyłamy na port B (1 cykl)
    ser R22               ;ustawienie 255 w r22, na to co u Ciebie w Bascomie oznaczone jako B :P
    clr R21               ;zerowanie rejestru R21 (1 cykl)
    delay_us:
      inc R21                 ;zwiększenie R21 o jeden  (1 cykl)
      cpi R21, 35            ;porównanie bajta w R21 z liczbą 35 (1 cykl)
    brlo delay_us         ; jezeli mniejsze od 35 to inkrementujemy (2 cykle)

    nop                     ;pusta instrukcja (1 cykl = 0,06us)
    nop                     ; dopelnienie do 9us petli bo będzie brakować :P :)

    zero:
      ldi R20, (0<<PINB0) ; stan pinu 0 opuszczamy do zera :P (1 cykl)
      out PORTB, R20      ; przesyłamy na port B (1 cykl)

    endtim:
     reti ;wyjscie z przerwania
    $end asm

    Zapewne ktoś dopatrzy się błędów :D
    Jednak z mojej strony powiem, że Atom1477 dobrze kombinuje i warto sprawdzić jego przemyślenia... ;)
    Pozdrawiam
    :)

    0
  • #21 01 Paź 2009 12:37
    karolczyzycki

    Poziom 20  

    Na forum znalasłem program do odczytu kodów klawiszy do pilota NEC.
    Z tego co widzę to autor nie przejmował się zbyt dokłądnością.
    Nie wszystko tutaj rozumiem, mógłby ktoś w kilku słowach opisać jak to działa?

    Przepełnienie występuje co 96us
    co 96us wykonuje się etykieta tikers (nie wiem po co ta pętla 1200), to jest czas w którym powinien zostać odebrany cały sygnał? i jeśli ten czas minie, zmienne są zerowane i wraca do stanu początkowego?
    w momencie przerwania, (stan 0 na nóżce int0) program skacze do irfared
    I teraz:
    startuje licznik
    Nie wiem po co jest to:

    Code:
    If Tik >= 139 And Tik < 150 Then  

    to jest przedział czasu w jaki procesor ma czekać na nagłówek?
    I dalej w jaki sposób jest odczytywana jedynka?

    Code:
    '*******************************************************************************
    
    '* Filename    : IR NEC by http://www.sbprojects.com/knowledge/ir/ir.htm
    '* Revision    : 1.0
    '* Controller  : ATMEGA8
    '* Compiler    : BASCOM-AVR 1.11.8.3 DEMO
    '* Author      : Rubashka Vasiliy , Ukraine , 2007
    '* WWW         : http://ledeffects.net
    '* Mail        : info(malpa)ledeffects.net
    '* Thank you   : Aheir, aheir(malpa)radiokot.ru
    '*******************************************************************************
    $regfile = "m16def.dat"
    $crystal = 800000                                           'âíóo?aííeé aaía?aoî?
    '$lib "lcd4.lbx"
    Config Lcdpin = Pin , Rs = Portb.2 , E = Portb.3 , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7       'standard
    Config Lcd = 16 * 2
    Portb .1 = 1
    Config Pind.2 = Input
    Config Portc.2 = Output
    Config Timer0 = Timer , Prescale = 256                      '8000000/256=31250 Hz
    Config Int0 = Falling                                       'I?a?uâaíea iî niaäó
    Stop Timer0                                                 'înoaíaâëeâaai oaéia?
    Enable Timer0                                               '?aç?aoaai ?aáîoó oaéia?a0
    Enable Int0                                                 '?aç?aoaai ?aáîoó i?a?uâaíey0




    Enable Interrupts                                           '?aç?aoaai i?a?uâaíey

    On Timer0 Tikers                                            '?aáîoa iî oaéia?ó
    On Int0 Infrared                                            '?aáîoa iî i?a?uâaíe?

    Dim Tik As Word                                             'n÷¸o÷ee oeeîâ oaéia?a
    Dim Byt As Byte                                             'n÷¸o÷ee i?eíyouo áeo
    Dim Repeat_flag As Bit                                      'ôëaa iîâoî?a
    Dim Start_flag As Bit                                       'ôëaa noa?oîâîaî ónëîâey
    Dim Address As Byte                                         'áaéo aä?ana
    Dim Command As Byte                                         'áaéo eîiaíäu
    Dim Address_1 As Byte                                       'i?yiîé áaéo aä?ana
    Dim Command_1 As Byte                                       'i?yiîé áaéo eîiaíäu
    Dim Address_0 As Byte                                       'eíâa?níué áaéo aä?ana
    Dim Command_0 As Byte                                       'eíâa?níué áaéo eîiaíäu
    Dim Summa As Word


    Cls                                                         '*******************************************************************************

    Do                                                          'Îníîâíîé öeeë

                                                           'Î÷enoeoü AEE
    Cursor Off
    Locate 2 , 1                                                'Âueë?÷eoü eó?nî?
    Lcd Address ; " " ; Command                                 'Âuâanoe ía AEE AÄ?AN e EÎIIAÍÄÓ
    If Command = 8 Then Portc.2 = 1                             'Anëe íaaaoa eëaâeoa "P+" - âeë?÷eoü nâaoîäeîä
    If Command = 240 Then Portc.2 = 0                           'Anëe íaaaoa eëaâeoa "P-" - âueë?÷eoü nâaoîäeîä                                                 'Çaäa?aea 10 in
    Loop
    End                                                         'Eîíaö îníîâíîaî öeeëa

    '*******************************************************************************

     Tikers:                                                    '?aáîoa iî oaéia?ó

     Timer0 = 253                                               '31250/(256-253)=10416,66 Hz (96 ien)
                                                                 '254 - TV SAMSUNG, 253 - DVD SAMSUNG e ä?óaea NEC
     Incr Tik
     If Tik >= 1200 Then                                        'anëe ían÷eoaëe 1200 oeeîâ, ná?îneëe ân¸ â enoîäíîa nînoîyíea
     Tik = 0
     Repeat_flag = 0
     Start_flag = 0
     Address_1 = 0
     Command_1 = 0
     Address_0 = 0
     Command_0 = 0
     Command = 0
     Address = 0
     Stop Timer0                                                'înoaíaâëeâaai oaéia?
     End If

      Return
    '*******************************************************************************

     Infrared:                                                  '?aáîoa iî i?a?uâaíe?

      Start Timer0                                              'çaióneaai oaéia?

      If Tik >= 139 And Tik < 150 Then                          'anëe nëó÷eëînü îo 139 äî 150 oeeîâ - "NOA?O"
      Address = 1
      Repeat_flag = 0
      Start_flag = 1
      Address_1 = 0
      Command_1 = 0
      Address_0 = 0
      Command_0 = 0
      End If

      If Tik >= 116 And Tik < 139 Then                          'anëe nëó÷eëînü îo 116 äî 138 oeeîâ - "IÎÂOÎ?"
      Address = 2
      Repeat_flag = 1
      Start_flag = 0
      End If

      If Tik >= 22 And Tik < 116 And Start_flag = 1 Then        'anëe nëó÷eëînü îo 22 äî 115 oeeîâ - i?eíyëe "1"
       Incr Byt

        If Byt < 9 Then
         Shift Address_1 , Left
         Address_1 = Address_1 + 1
        End If

        If Byt >= 9 And Byt < 17 Then
         Shift Address_0 , Left
         Address_0 = Address_0 + 1
        End If

        If Byt >= 17 And Byt < 25 Then
         Shift Command_1 , Left
         Command_1 = Command_1 + 1
        End If

        If Byt >= 25 Then
         Shift Command_0 , Left
         Command_0 = Command_0 + 1
        End If
      End If

      If Tik >= 10 And Tik < 22 And Start_flag = 1 Then         'anëe nëó÷eëînü îo 10 äî 21 oeea - i?eíyëe "0"
       Incr Byt

        If Byt < 9 Then
         Shift Address_1 , Left
        End If

        If Byt >= 9 And Byt < 17 Then
         Shift Address_0 , Left
        End If

        If Byt >= 17 And Byt < 25 Then
         Shift Command_1 , Left
        End If

        If Byt >= 25 Then
         Shift Command_0 , Left
        End If
      End If

     Tik = 0

      If Byt = 32 Then                                          'anëe i?eíyëe 4 áaéoa, i?îâa?yai i?aâeëüíînoü i?e¸ia eîiaíäu
                                                                 'anëe aä?an eëe eîiaíäa 16-?e÷íua, i?îâa?ea ía i?îoîäeo, iîýoîió çaeîiiaíoe?îâaíî
        'Summa = Address_0 + Address_1
        'If Summa = 255 Then
        Address = Address_1
        'Else
        'Address = 0
        'End If

        'Summa = Command_0 + Command_1
        'If Summa = 255 Then
        Command = Command_1
        'Else
        'Command = 0
        'End If
      Byt = 0
      Repeat_flag = 0
      Start_flag = 0
      Stop Timer0                                               'înoaíaâëeâaai oaéia?
      End If

     Return

    0
  • #22 05 Paź 2009 08:36
    karolczyzycki

    Poziom 20  

    Witam.

    Napisałem taki najprostszy program bez żadnych pętli tylko kolejny stany.
    Na oscyloskopie czasy mniej więcej są dokładne (wiadomo że waitms nie jest takie precyzyjne) ale i tak coś nie działa.
    Mierząc oscyloskopem na diodzie nadawczej, przebieg jest OK.
    Ale na odbiorniku już sygnał jest zniekształcony, czasy przesynięte.


    Odbiornik NEC powinien pokazać 20DF 10EF, a pokazuje jakieś inne komendy dopiero, jak diodę przyłoże do odbiornika na 1mm.
    Czego brakuje w tym programie?

    Code:
    $regfile = "m16def.dat"
    
    $crystal = 8000000

    config portc.7 = output
    portc.7 = 0

    start2:
    Do
    Waitms 100
    goto Send_Transmit
    Loop
    End



    Send_Transmit:

    '*****************HEADER*****************************
         Portc.7 = 1
         waitms 9

         Portc.7 = 0
         waitus 4500

    '*****************ADDRESS*****************************

    '20
         Portc.7 = 1                                            ' 0
         waitus 600
         Portc.7 = 0
         waitus 600
         Portc.7 = 1                                            ' 0
         waitus 600
         Portc.7 = 0
         waitus 600
         Portc.7 = 1                                            ' 1
         waitus 600
         Portc.7 = 0
         waitus 1730
         Portc.7 = 1                                            ' 0
         waitus 600
         Portc.7 = 0
         waitus 600
         Portc.7 = 1                                            ' 0
         waitus 600
         Portc.7 = 0
         waitus 600
         Portc.7 = 1                                            ' 0
         waitus 600
         Portc.7 = 0
         waitus 600
         Portc.7 = 1                                            ' 0
         waitus 600
         Portc.7 = 0
         waitus 600
         Portc.7 = 1                                            ' 0
         waitus 600
         Portc.7 = 0
         waitus 600


    'DF


         Portc.7 = 1                                            ' 1
         waitus 600
         Portc.7 = 0
         waitus 1730
         Portc.7 = 1                                            ' 1
         waitus 600
         Portc.7 = 0
         waitus 1730
         Portc.7 = 1                                            ' 0
         waitus 600
         Portc.7 = 0
         waitus 600
         Portc.7 = 1                                            ' 1
         waitus 600
         Portc.7 = 0
         waitus 1730
         Portc.7 = 1                                            ' 1
         waitus 600
         Portc.7 = 0
         waitus 1730
          Portc.7 = 1                                           ' 1
         waitus 600
         Portc.7 = 0
         waitus 1730
          Portc.7 = 1                                           ' 1
         waitus 600
         Portc.7 = 0
         waitus 1730
          Portc.7 = 1                                           ' 1
         waitus 600
         Portc.7 = 0
         waitus 1730

    '*****************COMMAND***********************************

    '10
         Portc.7 = 1                                            ' 0
         waitus 600
         Portc.7 = 0
         waitus 600
         Portc.7 = 1                                            ' 0
         waitus 600
         Portc.7 = 0
         waitus 600
         Portc.7 = 1                                            ' 0
         waitus 600
         Portc.7 = 0
         waitus 600
         Portc.7 = 1                                            ' 1
         waitus 600
         Portc.7 = 0
         waitus 1730
          Portc.7 = 1                                            ' 0
         waitus 600
         Portc.7 = 0
         waitus 600
         Portc.7 = 1                                            ' 0
         waitus 600
         Portc.7 = 0
         waitus 600
          Portc.7 = 1                                            ' 0
         waitus 600
         Portc.7 = 0
         waitus 600
          Portc.7 = 1                                            ' 0
         waitus 600
         Portc.7 = 0
         waitus 600



         'EF

          Portc.7 = 1                                            ' 1
         waitus 600
         Portc.7 = 0
         waitus 1730
          Portc.7 = 1                                            ' 1
         waitus 600
         Portc.7 = 0
         waitus 1730
          Portc.7 = 1                                            ' 1
         waitus 600
         Portc.7 = 0
         waitus 1730
          Portc.7 = 1                                            ' 0
         waitus 600
         Portc.7 = 0
         waitus 600
          Portc.7 = 1                                            ' 1
         waitus 600
         Portc.7 = 0
         waitus 1730
          Portc.7 = 1                                            ' 1
         waitus 600
         Portc.7 = 0
         waitus 1730
          Portc.7 = 1                                            ' 1
         waitus 600
         Portc.7 = 0
         waitus 1730
          Portc.7 = 1                                            ' 1
         waitus 600
         Portc.7 = 0
         waitus 1730









      '***********************************************************


         Portc.7 = 1                                            ' koniec
         waitus 600
         Portc.7 = 0
         waitms 3100

      GOTO START2

    0
  • Pomocny post
    #23 05 Paź 2009 09:26
    landy13
    Poziom 29  

    Cytat:
    Czego brakuje w tym programie?

    Nośnej. Dla NECa 38kHz.

    0
  • #24 06 Paź 2009 00:04
    karolczyzycki

    Poziom 20  

    Napisałem kod generowania nośnej, na oscyloskopie okres to 37us więc częstotliwość to 26kHz: (próbowałem już na różne sposoby ale nie dało się zwiększyć)

    Code:
    $regfile = "attiny2313.dat"
    
    $crystal = 8000000
    Config Pinb.3 = Output
    Config Timer0 = Timer , Prescale = 1
    dim takt as integer
    Enable Interrupts : Enable Timer0 : On Timer0 przerwanie : Timer0 = 255
    takt = 0

    Do
      if takt = 300 then
      takt = 0
      portb.3 = 0
      waitms 200
      goto ir
    Loop
    End

    przerwanie:
    Timer0 = 255
    Toggle Portb.3
    incr takt
    Return


    Nie wiem teraz gdzie wstawić to włączanie i wyłączanie portu B.3.
    Zrobić to na IF, THEN?
    Próbowałem wstawić przykładową przerwę 200ms w pętlę DO, LOOP,(jak wyżej), ale nie działa.
    Jeśli zacznę wstawiać za dużo komend w etykietę "przerwanie" to znów czas się rozjedzie.

    0
  • Pomocny post
    #25 06 Paź 2009 09:29
    landy13
    Poziom 29  

    Proponuję następujące zmiany:
    Dla zegara 8MHz

    Code:
    Config Timer0 = Timer , Prescale = 8 

    wtedy jeden cykl = 1us - łatwo się liczy.
    Następnie w przerwaniu:


    Code:
    Przerwanie:
    
          Timer0 = Timer0 + 213
          If Flaga = 1 Then
              Toggle Portc.7
            Else
              Portc.7 = 0
          End If
      Return

    Dalej w podprogramie "Send_transmit" zamiast:
    Code:
    Portc.7 = 1
    napisz:
    Code:
    Flaga = 1
    a zamiast:
    Code:
    Portc.7 = 0   
    napisz:
    Code:
    Flaga = 0 
    Powinno działać.

    Jeśli chodzi o ostatni program, to:
    Cytat:
    Próbowałem wstawić przykładową przerwę 200ms w pętlę DO, LOOP,(jak wyżej), ale nie działa.
    Jak sprawdzasz czy działa? Przecież to się nawet nie skompiluje.

    0
  • #26 06 Paź 2009 21:05
    karolczyzycki

    Poziom 20  

    landy13 -> Poprzedni kod źle wkleiłem na forum, sprawdzam kompilując i programując.

    Przerobiłem kod, wysyła,ale jest problem z czasem...
    Atm16,Bascom. Jak zrealizować kilkakrotną zmianę stanu portu

    1. Fusebity są OK (załączam dla pewności)
    Atm16,Bascom. Jak zrealizować kilkakrotną zmianę stanu portu

    2. W kodzie zmieniłem na 8MHz (kod)

    Code:
    $regfile = "attiny2313.dat"
    
    $crystal = 8000000
    Config Pinb.3 = Output
    Config Timer0 = Timer , Prescale = 8
    dim flaga as byte
    Enable Interrupts : Enable Timer0 : On Timer0 przerwanie : Timer0 = Timer0 + 213
    Do
    '*****************HEADER*****************************
         flaga = 1
         waitms 9
     Flaga = 0
         waitus 4500
    '*****************ADDRESS*****************************
    ...
    ...
    ...
    Loop
    End

    Przerwanie:
      Timer0 = Timer0 + 213
          If Flaga = 1 Then
              Toggle Portb.3
            Else
              Portb.3 = 0
          End If
    Return

    0
  • Pomocny post
    #27 06 Paź 2009 21:37
    landy13
    Poziom 29  

    Cytat:
    To powinno mieć 9ms
    A ile ma? (nie znam się na takich oscyloskopach)

    0
  • #28 06 Paź 2009 21:54
    karolczyzycki

    Poziom 20  

    Jak dla mnie to 15ms
    Atm16,Bascom. Jak zrealizować kilkakrotną zmianę stanu portu

    0
  • Pomocny post
    #29 06 Paź 2009 22:14
    landy13
    Poziom 29  

    15ms do niczego nie pasuje. Wklej kod bezpośrednio z Bascoma, przepisywany może zawierać błędy.

    0
  • #30 06 Paź 2009 22:32
    karolczyzycki

    Poziom 20  

    Ja już siedze nad tym kolejny dzień i ciągle mam problem z tymi czasami.
    Próbowałem przejść na ATMEGę 32 ale to samo.
    Nigdy nie ma 9ms, wiem że jakaś mała różnica może być, bo to wewn. zegar.
    Ale chyba nie aż taka (4ms)

    To jest kod który wgrywam.

    Code:

    $regfile = "attiny2313.dat"
    $crystal = 8000000
    Config Pinb.3 = Output
    Config Timer0 = Timer , Prescale = 8

    dim flaga as byte
    Enable Interrupts : Enable Timer0 : On Timer0 przerwanie : Timer0 = Timer0 + 213


    Do


     '*****************HEADER*****************************
         flaga = 1
         waitms 9
     Flaga = 0
         waitus 4500
    '*****************ADDRESS*****************************
    '20
     Flaga = 1
         waitus 600
     Flaga = 0
         waitus 600
     Flaga = 1                                                  ' 0
         waitus 600
     Flaga = 0
         waitus 600
     Flaga = 1                                                  ' 1
         waitus 600
     Flaga = 0
         waitus 1730
     Flaga = 1                                                  ' 0
         waitus 600
     Flaga = 0
         waitus 600
     Flaga = 1                                                  ' 0
         waitus 600
     Flaga = 0
         waitus 600
     Flaga = 1                                                  ' 0
         waitus 600
     Flaga = 0
         waitus 600
     Flaga = 1                                                  ' 0
         waitus 600
     Flaga = 0
         waitus 600
     Flaga = 1                                                  ' 0
         waitus 600
     Flaga = 0
         waitus 600
    'DF
     Flaga = 1                                                  ' 1
         waitus 600
     Flaga = 0
         waitus 1730
     Flaga = 1                                                  ' 1
         waitus 600
     Flaga = 0
         waitus 1730
     Flaga = 1                                                  ' 0
         waitus 600
     Flaga = 0
         waitus 600
     Flaga = 1                                                  ' 1
         waitus 600
     Flaga = 0
         waitus 1730
     Flaga = 1                                                  ' 1
         waitus 600
     Flaga = 0
         waitus 1730
      Flaga = 1                                                 ' 1
         waitus 600
     Flaga = 0
         waitus 1730
      Flaga = 1                                                 ' 1
         waitus 600
     Flaga = 0
         waitus 1730
      Flaga = 1                                                 ' 1
         waitus 600
     Flaga = 0
         waitus 1730
    '*****************COMMAND***********************************
    '10
     Flaga = 1                                                  ' 0
         waitus 600
     Flaga = 0
         waitus 600
     Flaga = 1                                                  ' 0
         waitus 600
     Flaga = 0
         waitus 600
     Flaga = 1                                                  ' 0
         waitus 600
     Flaga = 0
         waitus 600
     Flaga = 1                                                  ' 1
         waitus 600
     Flaga = 0
         waitus 1730
      Flaga = 1                                                 ' 0
         waitus 600
     Flaga = 0
         waitus 600
     Flaga = 1                                                  ' 0
         waitus 600
     Flaga = 0
         waitus 600
      Flaga = 1                                                 ' 0
         waitus 600
     Flaga = 0
         waitus 600
      Flaga = 1                                                 ' 0
         waitus 600
     Flaga = 0
         waitus 600

         'EF

      Flaga = 1                                                 ' 1
         waitus 600
     Flaga = 0
         waitus 1730
      Flaga = 1                                                 ' 1
         waitus 600
     Flaga = 0
         waitus 1730
      Flaga = 1                                                 ' 1
         waitus 600
     Flaga = 0
         waitus 1730
      Flaga = 1                                                 ' 0
         waitus 600
     Flaga = 0
         waitus 600
      Flaga = 1                                                 ' 1
         waitus 600
     Flaga = 0
         waitus 1730
      Flaga = 1                                                 ' 1
         waitus 600
     Flaga = 0
         waitus 1730
      Flaga = 1                                                 ' 1
         waitus 600
     Flaga = 0
         waitus 1730
      Flaga = 1                                                 ' 1
         waitus 600
     Flaga = 0
         waitus 1730

      '***********************************************************
     Flaga = 1                                                  ' koniec
         waitus 600
     Flaga = 0
         waitms 3100

    Loop
    End



    Przerwanie:
      Timer0 = Timer0 + 213
          If Flaga = 1 Then
              Toggle Portb.3
            Else
              Portb.3 = 0
          End If
    Return

    0