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.

[atmega8][asembler]rc5, sterowanie pilotem

KKobi 17 Mar 2009 23:07 3656 10
  • #1 17 Mar 2009 23:07
    KKobi
    Poziom 8  

    Witam,
    Szukałem po forum jakiejś pomocy, ale w archiwum nic nie znalazłem...
    Ze strony producenta atmel ściągnełem skrypt do obsługi rc5.
    Chce poprzez pilota sterować pracą mojego urządzenia, ale na chwile obecną chce zapalac/gasic diode na pinie PB1.
    Do uC podłączony jest odbiornik pod pin PD2 tak jak w programie podano.
    Producent pisze o częstotliwości 4 Mhz gdzie w AVR studio ustawić ten parametr ?
    (Pilot mam od TV a przycisk nr 1 lub dowolny inny moze być.)

    Code:

    ;***************************************************************************
    ;* A P P L I C A T I O N   N O T E   F O R   T H E   A V R   F A M I L Y
    ;*
    ;* Number      : AVR410
    ;* File Name            :"rc5.asm"
    ;* Title                :RC5 IR Remote Control Decoder
    ;* Date                 :97.08.15
    ;* Version              :1.0
    ;* Support telephone    :+47 72 88 43 88 (ATMEL Norway)
    ;* Support fax          :+47 72 88 43 99 (ATMEL Norway)
    ;* Target MCU           :AT90S1200
    ;*
    ;* DESCRIPTION
    ;* This Application note describes how to decode the frequently used
    ;* RC5 IR remote control protocol.
    ;*
    ;* The timing is adapted for 4 MHz crystal
    ;*
    ;***************************************************************************
    .include "m8def.inc"


    .equ   INPUT      =2   ;PD2
    .equ   SYS_ADDR   =0   ;The system address


    .def   S   =R0
    .def   inttemp   =R1
    .def   ref1   =R2
    .def   ref2   =R3

    .def   temp   =R16

    .def   timerL   =R17
    .def   timerH   =R16

    .def   system   =R19
    .def   command   =R20

    .def   bitcnt   =R21


    .cseg
    .org 0
          rjmp   reset

    ;********************************************************************
    ;* "TIM0_OVF" - Timer/counter overflow interrupt handler
    ;*
    ;* The overflow interrupt increments the "timerL" and "timerH"
    ;* every 64us and 16,384us.
    ;*
    ;* Number of words:   7
    ;* Number of cycles:   6 + reti
    ;* Low registers used:   1
    ;* High registers used: 3
    ;* Pointers used:   0




    ;********************************************************************
    .org OVF0addr
    TIM0_OVF:   in   S,sreg
          inc   timerL      ;Updated every 64us
          inc   inttemp
          brne   TIM0_OVF_exit

          inc   timerH

    TIM0_OVF_exit:   out   sreg,S
          reti




    ;********************************************************************
    ;* Example program
    ;*
    ;* Initializes timer, ports and interrupts.
    ;*
    ;* Calls "detect" in an endless loop and puts the result out on
    ;* port B.
    ;*
    ;* Number of words:   16
    ;* Low registers used:   0
    ;* High registers used: 3
    ;* Pointers used:   0
    ;********************************************************************

    reset:      ;ldi     temp,low(RAMEND)   ;Initialize stackpointer
          ;out   SPL,temp         
          ;ldi     temp,high(RAMEND)   ; Commented out since 1200 does not hae SRAM
          ;out   SPH,temp
       
          ldi   temp,1      ;Timer/Counter 0 clocked at CK
          out   TCCR0,temp

          ldi   temp,1<<TOIE0   ;Enable Timer0 overflow interrupt
          out   TIMSK,temp

          ser   temp      ;PORTB as output
          out   DDRB,temp

          sei         ;Enable gobal iterrupt



    main:      rcall   detect      ;Call RC5 detect routine

          cpi   system,0b00000000   ;                         !!!!! tutaj podaje kod urządzenia (Tv)
          brne   release

          cpi command,0b00000001       ;                            !!!!!! tutaj podaj nr przycisku do porownania
          ;andi   command,0x3F   ;Remove control bit
          ldi R22,0b11111111
            out PORTB, R22
            rcall Czekaj250ms
            rcall Czekaj250ms
          ;out   PORTB,command

          rjmp   main


    release:   clr   command      ;Clear PORTB
          out   PORTB,command
          rjmp   main




    ;********************************************************************
    ;* "detect" - RC5 decode routine
    ;*
    ;* This subroutine decodes the RC5 bit stream applied on PORTD
    ;* pin "INPUT".
    ;*
    ;* If successe: The command and system address are
    ;*      returned in "command" and "system".
    ;*      Bit 6 of "command" holds the toggle bit.
    ;*
    ;* If failed:    $FF in both "system" and "command"
    ;*
    ;* Crystal frequency is 4MHz
    ;*
    ;* Number of words:   72
    ;* Low registers used:    3
    ;* High registers used:  6
    ;* Pointers used:    0
    ;********************************************************************
    detect:      clr   inttemp
          clr   timerH

    detect1:   clr   timerL

    detect2:   cpi   timerH,8   ;If line not idle within 131ms
          brlo   dl1
          rjmp   fault      ;  then exit

    dl1:      cpi   timerL,55   ;If line low for 3.5ms
          brge   start1      ;   then wait for start bit

          sbis   PIND,INPUT   ;If line is
          rjmp   detect1      ;   low  - jump to detect1
          rjmp   detect2      ;   high - jump to detect2


    start1:      cpi   timerH,8   ;If no start bit detected
          brge   fault      ;within 130ms then exit

          sbic   PIND,INPUT   ;Wait for start bit
          rjmp   start1


          clr   timerL      ;Measure length of start bit
          
    start2:      cpi   timerL,17   ;If startbit longer than 1.1ms,
          brge   fault      ;   exit
          sbis   PIND,INPUT
          rjmp   start2
                   ;Positive edge of 1st start bit

          mov   temp,timerL   ;timer is 1/2 bit time
          clr   timerL

          mov   ref1,temp
          lsr   ref1
          mov   ref2,ref1
          add   ref1,temp   ;ref1 = 3/4 bit time
          lsl   temp
          add   ref2,temp   ;ref2 = 5/4 bit time


    start3:      cp   timerL,ref1   ;If high periode St2 > 3/4 bit time
          brge   fault      ;   exit
          sbic   PIND,INPUT   ;Wait for falling edge start bit 2
          rjmp   start3

          clr   timerL
          ldi   bitcnt,12   ;Receive 12 bits
          clr   command
          clr   system


    sample:      cp   timerL,ref1   ;Sample INPUT at 1/4 bit time
          brlo   sample

          sbic   PIND,INPUT
          rjmp   bit_is_a_1   ;Jump if line high


    bit_is_a_0:   clc         ;Store a '0'
          rol   command
          rol   system

                   ;Synchronize timing
    bit_is_a_0a:   cp   timerL,ref2   ;If no edge within 3/4 bit time
          brge   fault      ;   exit
          sbis   PIND,INPUT   ;Wait for rising edge
          rjmp   bit_is_a_0a   ;in the middle of the bit

          clr   timerL
          rjmp   nextbit

    bit_is_a_1:   sec         ;Store a '1'
          rol   command
          rol   system
                   ;Synchronize timing
    bit_is_a_1a:   cp   timerL,ref2   ;If no edge within 3/4 bit time
          brge   fault      ;   exit
          sbic   PIND,INPUT   ;Wait for falling edge
          rjmp   bit_is_a_1a   ;in the middle of the bit

          clr   timerL

    nextbit:   dec   bitcnt      ;If bitcnt > 0
          brne   sample      ;   get next bit


    ;All bits sucessfully received!
          mov   temp,command   ;Place system bits in "system"
          rol   temp
          rol   system
          rol   temp
          rol   system

          bst   system,5   ;Move toggle bit
          bld   command,6   ;to "command"

                   ;Clear remaining bits
          andi   command,0b01111111
          andi   system,0x1F

          ret

    fault:      ser   command      ;Both "command" and "system"
          ser   system      ;0xFF indicates failure
          ret

    Czekaj250ms:
     ldi R20, 0
     czekaj250ms_0:
      ldi R21, 0
      czekaj250ms_1:
      inc R21
       cpi R21, 250
       brlo czekaj250ms_1
      inc R20
      cpi R20, 249
      brlo czekaj250ms_0
     ret



    Czy ma ktoś pomysł co jest nie tak ? dlaczego nie działa ?
    Będę wdzięczny za każdą wskazówkę....

    0 10
  • #2 20 Mar 2009 11:54
    KKobi
    Poziom 8  

    Odświeżam temat...
    Przesiedziałem nad tym problemem pare dni i nic nie mogę zmienić....

    0
  • #3 20 Mar 2009 12:36
    Dr_DEAD
    Poziom 28  

    KKobi napisał:

    Producent pisze o częstotliwości 4 Mhz gdzie w AVR studio ustawić ten parametr ?

    No musisz zalutować kwarc o wartości 4,00MHz i odpowiednio ustawić FuseBity tak aby Atmega korzystała z tego kwarcu.

    0
  • #4 20 Mar 2009 13:01
    KKobi
    Poziom 8  

    Ale po co lutować ? Przecież w fusach można zmienić taktowanie i otrzymać 4 Mhz, bez żadnego zewnętrznego oscylatora....

    0
  • #5 20 Mar 2009 13:08
    Dr_DEAD
    Poziom 28  

    KKobi napisał:
    Ale po co lutować ? Przecież w fusach można zmienić taktowanie i otrzymać 4 Mhz, bez żadnego zewnętrznego oscylatora....

    Napisali "4 MHz crystal" i mieli ku temu powody. Jak chcesz żeby działało to go zalutuj.

    0
  • #6 20 Mar 2009 13:19
    KKobi
    Poziom 8  

    Kiedyś już zmontowałem taki układ i działał bez rezonatora.
    Po jakimś czasie przestał działać, a teraz nie wiem jak stworzyć ten program aby działało jak należy.
    Myślę ze rezonator jest tu zbędny.
    Zobacz na schemat:
    http://strony.aster.pl/trojan/img/lampa/schemat.jpg
    inni też go nie potrzebowali...
    Spójrz na program, co może być w nim nie tak ?

    Proszę zwracać uwagę na pisownię - regulamin p.15
    Błędy poprawiłem.
    [zumek]

    0
  • #7 20 Mar 2009 14:43
    zumek
    Poziom 39  

    KKobi napisał:
    ...Spójrz na program, co może być w nim nie tak ?

    A Ty nie możesz tego zrobić :?:
    Na pierwszy rzut oka widać, co należałoby poprawić(podpowiem że usunąć) w kodzie.

    0
  • #8 20 Mar 2009 15:17
    KKobi
    Poziom 8  

    Wiec,
    Po pierwsze podany przeze mnie link nie dotyczy mojego programu i ja uzywam atmega8.
    Poza tym błąd moze być po odebraniu sygnału z przycisku 1.
    jest cpi command,0b00000001 i ewentualnie trzeba by było dodać
    brne main, ale to raczej nic nie zmieni....
    Ja się głowie nad tym problemem juz troche czasu... jezeli wiesz co
    trzeba zmienić to proszę opisz to.
    Dzięki.

    0
  • #9 20 Mar 2009 15:22
    zumek
    Poziom 39  

    a)

    Code:

    .def   temp   =R16

    ;...
    .def   timerH   =R16

    b)
    Code:

    ;...
    reset:      ;ldi     temp,low(RAMEND)   ;Initialize stackpointer
          ;out   SPL,temp         
          ;ldi     temp,high(RAMEND)   ; Commented out since 1200 does not hae SRAM
          ;out   SPH,temp

    Tu widzę błędy.Znajdź je i popraw.

    0
  • #10 20 Mar 2009 16:09
    KKobi
    Poziom 8  

    Jeżeli dobrze poprawiam:
    w a) należy przydzielić inny rejestr, nazwy nie mogą się powtarzać,

    w b) usunąć znaki komentarza ? w atmega8


    a co z tym rezonatorem zewnętrznym ?

    Dodano po 37 [minuty]:

    Sprawdziłem na urządzeniu, i nic się nie zmieniło :/

    0
  • #11 22 Mar 2009 16:13
    KKobi
    Poziom 8  

    Zamieszczam mój gotowy program po przeróbkach, może komuś się
    przyda. Sam go poprawiłem, bez pomocy "znawców"...

    Code:

    ;***************************************************************************
    ;* A P P L I C A T I O N   N O T E   F O R   T H E   A V R   F A M I L Y
    ;*
    ;* Number      : AVR410
    ;* File Name            :"rc5.asm"
    ;* Title                :RC5 IR Remote Control Decoder
    ;* Date                 :97.08.15
    ;* Version              :1.0
    ;* Support telephone    :+47 72 88 43 88 (ATMEL Norway)
    ;* Support fax          :+47 72 88 43 99 (ATMEL Norway)
    ;* Target MCU           :AT90S1200
    ;*
    ;* DESCRIPTION
    ;* This Application note describes how to decode the frequently used
    ;* RC5 IR remote control protocol.
    ;*
    ;* The timing is adapted for 4 MHz crystal
    ;*
    ;***************************************************************************
    .include "m8def.inc"


    .equ   INPUT      =2   ;PD2
    .equ   SYS_ADDR   =0   ;The system address


    .def   S   =R0
    .def   inttemp   =R1
    .def   ref1   =R2
    .def   ref2   =R3

    .def   temp   =R16

    .def   timerL   =R17
    .def   timerH   =R18

    .def   system   =R19
    .def   command   =R20

    .def   bitcnt   =R21


    .cseg
    .org 0
          rjmp   reset

    ;********************************************************************
    ;* "TIM0_OVF" - Timer/counter overflow interrupt handler
    ;*
    ;* The overflow interrupt increments the "timerL" and "timerH"
    ;* every 64us and 16,384us.
    ;*
    ;* Number of words:   7
    ;* Number of cycles:   6 + reti
    ;* Low registers used:   1
    ;* High registers used: 3
    ;* Pointers used:   0
    ;********************************************************************
    .org OVF0addr
    TIM0_OVF:   in   S,sreg
          inc   timerL      ;Updated every 64us
          inc   inttemp
          brne   TIM0_OVF_exit

          inc   timerH

    TIM0_OVF_exit:   out   sreg,S
          reti




    ;********************************************************************
    ;* Example program
    ;*
    ;* Initializes timer, ports and interrupts.
    ;*
    ;* Calls "detect" in an endless loop and puts the result out on
    ;* port B.
    ;*
    ;* Number of words:   16
    ;* Low registers used:   0
    ;* High registers used: 3
    ;* Pointers used:   0
    ;********************************************************************

    reset:      ldi     temp,low(RAMEND)   ;Initialize stackpointer
          out   SPL,temp         
          ldi     temp,high(RAMEND)   ; Commented out since 1200 does not hae SRAM
          out   SPH,temp
       
          ldi   temp,1      ;Timer/Counter 0 clocked at CK
          out   TCCR0,temp

          ldi   temp,1<<TOIE0   ;Enable Timer0 overflow interrupt
          out   TIMSK,temp
          sei         ;Enable gobal iterrupt

    ldi ZL, LOW(LED*2)
    ldi ZH, HIGH(LED*2)
    ldi R27, 0


    main:      rcall   detect      ;Call RC5 detect routine

          cpi   system,0b00000001   ;                         !!!!! tutaj podaje kod urządzenia (Tv)
          breq   release
       
         cpi   command,0b00000011
         breq   zapal

         cpi   command,0b00000001
         breq   zapal1


          rjmp   main


    zapal:
           ldi r23, 0b11111111
          out DDRB, r23
          lpm R0, Z+
           out PORTB, R0
           rcall Czekaj250ms
           rcall Czekaj250ms
          rcall Czekaj250ms
          rcall Czekaj250ms
           rcall Czekaj250ms
          rcall Czekaj250ms
          inc R27
          ldi r23, 0b00000000
          out DDRB, r23
          rjmp main

    zapal1:
           ldi r23, 0b11111111
          out DDRB, r23

    sbiw R31:R30, 1     
    dec R27   
    petla2:
    lpm R0, Z
    sbiw R31:R30, 1
    out PORTB, R0
    rcall Czekaj250
    dec R27
    cpi R27, 0xFF

    brne petla2

    ldi r28,0b11111111
    out PORTB,r28
    rcall Czekaj250
    ldi r28,0b11000000
    out PORTB,r28
    rcall Czekaj250
    ldi r28,0b11111111
    out PORTB,r28
    rcall Czekaj250
    ldi r28,0b11000000
    out PORTB,r28
    rcall Czekaj250
    ldi r28,0b11111111
    out PORTB,r28
    rcall Czekaj250


    ldi r28,0b11111111
    out DDRC,r28
    ldi R22,0b00000000
      out PORTC, R22
      rcall Czekaj250
      rcall Czekaj250
      rcall Czekaj250
      rcall Czekaj250
    ldi r28,0b00000000
    out DDRC,r28

          ldi r23, 0b00000000
          out DDRB, r23
          rjmp main
    release:   
          cpi   command,0b00000011
         breq   zapal

         cpi   command,0b00000011
         breq   zapal1

          rjmp   main

    detect:      clr   inttemp
          clr   timerH

    detect1:   clr   timerL

    detect2:   cpi   timerH,8   ;If line not idle within 131ms
          brlo   dl1
          rjmp   fault      ;  then exit

    dl1:      cpi   timerL,55   ;If line low for 3.5ms
          brge   start1      ;   then wait for start bit

          sbis   PIND,INPUT   ;If line is
          rjmp   detect1      ;   low  - jump to detect1
          rjmp   detect2      ;   high - jump to detect2


    start1:      cpi   timerH,8   ;If no start bit detected
          brge   fault      ;within 130ms then exit

          sbic   PIND,INPUT   ;Wait for start bit
          rjmp   start1


          clr   timerL      ;Measure length of start bit
           
    start2:      cpi   timerL,17   ;If startbit longer than 1.1ms,
          brge   fault      ;   exit
          sbis   PIND,INPUT
          rjmp   start2
                   ;Positive edge of 1st start bit

          mov   temp,timerL   ;timer is 1/2 bit time
          clr   timerL

          mov   ref1,temp
          lsr   ref1
          mov   ref2,ref1
          add   ref1,temp   ;ref1 = 3/4 bit time
          lsl   temp
          add   ref2,temp   ;ref2 = 5/4 bit time


    start3:      cp   timerL,ref1   ;If high periode St2 > 3/4 bit time
          brge   fault      ;   exit
          sbic   PIND,INPUT   ;Wait for falling edge start bit 2
          rjmp   start3

          clr   timerL
          ldi   bitcnt,12   ;Receive 12 bits
          clr   command
          clr   system


    sample:      cp   timerL,ref1   ;Sample INPUT at 1/4 bit time
          brlo   sample

          sbic   PIND,INPUT
          rjmp   bit_is_a_1   ;Jump if line high


    bit_is_a_0:   clc         ;Store a '0'
          rol   command
          rol   system

                   ;Synchronize timing
    bit_is_a_0a:   cp   timerL,ref2   ;If no edge within 3/4 bit time
          brge   fault      ;   exit
          sbis   PIND,INPUT   ;Wait for rising edge
          rjmp   bit_is_a_0a   ;in the middle of the bit

          clr   timerL
          rjmp   nextbit

    bit_is_a_1:   sec         ;Store a '1'
          rol   command
          rol   system
                   ;Synchronize timing
    bit_is_a_1a:   cp   timerL,ref2   ;If no edge within 3/4 bit time
          brge   fault      ;   exit
          sbic   PIND,INPUT   ;Wait for falling edge
          rjmp   bit_is_a_1a   ;in the middle of the bit

          clr   timerL

    nextbit:   dec   bitcnt      ;If bitcnt > 0
          brne   sample      ;   get next bit


    ;All bits sucessfully received!
          mov   temp,command   ;Place system bits in "system"
          rol   temp
          rol   system
          rol   temp
          rol   system

          bst   system,5   ;Move toggle bit
          bld   command,6   ;to "command"

                   ;Clear remaining bits
          andi   command,0b01111111
          andi   system,0x1F

          ret

    fault:      ser   command      ;Both "command" and "system"
          ser   system      ;0xFF indicates failure
          ret

    Czekaj250ms:
     ldi R20, 0
     czekaj250ms_0:
      ldi R21, 0
      czekaj250ms_1:
      inc R21
       cpi R21, 250
       brlo czekaj250ms_1
      inc R20
      cpi R20, 249
      brlo czekaj250ms_0
     ret



     Czekaj250:
     ldi R20, 0
     czekaj250_0:
      ldi R21, 0
      czekaj250_1:
        ldi R18,0
        czekaj250_2:
      inc R18
      cpi R18, 5
      brlo czekaj250_2
      inc R21
       cpi R21, 250
      brlo czekaj250_1
      inc R20
      cpi R20, 249
      brlo czekaj250_0
     ret

    LED:
    .db 0b11000000, 0b11111001 ;0, 1
    .db 0b10100100, 0b10110000 ;2, 3
    .db 0b10011001, 0b10010010 ;4, 5
    .db 0b10000010, 0b11111000 ;6, 7
    .db 0b10000000, 0b10010000 ;8, 9

    0