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

[AT90S2323][ASM] odbiornik RC5 - dziala niestabilnie

01 Kwi 2009 13:59 2361 5
  • Poziom 10  
    Witam,

    Zrobilem sobie prosty uklad na at90s2323. Schemat ponizej.

    [AT90S2323][ASM] odbiornik RC5 - dziala niestabilnie

    Kod aplikacji bazuje na przykladzie atmela AVR410.asm

    Oto i sam kod.

    Code:


    ;***************************************************************************
    ;
    ;   IR-Switch
    ;
    ; AT90S2323 at 4 MHz with external oscillator
    ;
    ; RC5 code is based on Atmel's Application note AVR410.asm file.
    ;
    ;***************************************************************************

    .include "2323def.inc"

    .equ    POWER       =0  ;PB0 is connected the transistor, to power-On/Off relay
    .equ   INPUT      =1   ;PB1 is connected the TSOP1736 Infrared Receiver IC.
    .equ   SW         =2   ;PB2 is switch
    .equ   SYS_ADDR   =0   ;The system address - Philips TV set
    .equ   on_key      =7   ;key 7 - device ON
    .equ   off_key      =9   ;key 9 - device OFF

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

    .def   temp   =R16
    .def   temp2   =R26

    .def   timerL   =R17
    .def   timerH   =R16

    .def   system   =R19
    .def   command   =R20

    .def   bitcnt   =R21
    .def   counter =R25

    .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




    ;=================================================================
    ;       initiallizing Timer and PortB and enables interrupts.
    ;=================================================================

    reset:
          ldi     temp,low(RAMEND)   ;Initialize stackpointer
          out      SPL,temp         
       
          ldi      temp,1            ;Timer/Counter 0 clocked at CK
          out      TCCR0,temp

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

          ldi    temp,0b00000001    ;PB0 output
          out    DDRB,temp

          ldi    temp,0b00000100    ;pull-up resistor on PB2
          out    PORTB,temp

          sei                     ;Enable global iterrupt


    ;=================================================================
    ;               Main program
    ;=================================================================



    main:

          rcall   delayTime       
          sbis   PINB,SW            ;is button pressed?
          rcall   switchRelay         ;yes -> switch (invert) relay

          rcall   detect            ;Call RC5 detect routine

          cpi      system,SYS_ADDR      ;Respponds only at the specified address (philips TV)
          brne   release

          andi   command,0x3F      ;Remove control bit
       
          cpi      command,on_key      ; command = on_key (7)  ?
          brne   release            ;no -> jump to release
          sbi      PORTB,POWER         ;yes -> switch device ON

          rjmp   main



    release:
          cpi      command,off_key      ; command = off_key (9)  ?
          brne   release_sub         ;no -> jump to release_sub
          cbi      PORTB,POWER         ;yes -> switch device OFF
    release_sub:
          clr      command
          rjmp   main


    ;********************************************************************
    ;* "detect" - RC5 decode routine
    ;*
    ;* This subroutine decodes the RC5 bit stream applied on PORTB
    ;* 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   PINB,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   PINB,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   PINB,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   PINB,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   PINB,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   PINB,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   PINB,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


    ;=================================================================
    ;               delay routine
    ;=================================================================

    delayTime:

             ldi      counter,255
    delay:
             dec      counter
             brne   delay

             ret


    ;=================================================================
    ;               switch Relay (invert state) routine
    ;=================================================================

    switchRelay:
             sbis   PINB,POWER      ;pomin nastepna linie jesli 1
             rjmp   SetRelayON      ;nie 1 -> SetRelayON
             cbi      PORTB,POWER      ;wyczysc bit (przekaznik OFF)
             ret

    SetRelayON:
             sbi      PORTB,POWER      ;ustaw bit (przekaznik ON)
             ret






    Problem polega na tym, ze uklad "nie zawsze dziala". Czasami wlacza / wylacza sie bez problemu innym razem musze kilkakrtonie nacisnac przycisk pilota, aby spowodowac zalaczenie / wylaczenie urzadzenia.

    Czy ktos moglby mnie naprowadzic na wlasciwy kierunek?

    Pozdrawiam
  • Poziom 38  
    Wyczyszczenie "pilota" spirytusem daje często zbawienne skutki.
    A wymiana "gumek"...
  • Poziom 10  
    dzieki za chec pomocy, ale to nie to :(

    pilot noweczka Logitech Harmony 885, "nauczony" z oryginalnego pilota philipsa
    nadajnik ma duzo mocniejszy niz oryginalny, sygnal spokojnie odbija sie od sufitu, scian i innych przedmiotow, kiedy oryginal trzeba "wcelowac" w odbiornik

    pozdrawiam
  • Poziom 27  
    A policz ile cykli zajmuje prockowi procedura odbioru. Może się nie wyrabia ? Miałem podobny problem z PIC12 i programowo realizowanym SPI. Zanim skończył odbierać bit, to już pojawiał się następny i układ gubił czasem bity.
  • Poziom 10  
    OK, to jest jakis trop!
    dzieki

    a mam takze dodatkowe info, ktore powiem szczerze "zdziwilo" mnie lekko

    otoz wgralem sobie do komorki program irRemote, ktory pozwala na sterowanie urzadzeniami "robiac" z komorki pilota
    z bazy danych urzadzen wybralem swoj TV i O DZIWO !!??!! komorka wlacza wylacza moje urzadzenie za kazdym razem !!!
    nie ma najmniejszego problemu, wlasciwie z kazdej odleglosci

    kurcze, o co tu chodzi ?

    mam jakies swoje "przemyslenia" i ciekawi mnie co o tym sadzicie:

    Odbiornik ir TSOP1736, moze to jakis "klon" ktory nie ma jednak 36kHz, ale np. 38kHz. Komorka nie ma "prawdziwego" nadajnika IR, ale jakis modul IrDA, ktory byc moze pracuje "blizej" tego odbiornika i dlatego za kazdym razem zalacza/wylacza urzadzenie.

    Czy tak moze byc? Czy moze za bardzo kombinuje?

    EDIT:

    wlasnie "nauczylem" mojego harmony komed z komorki i nadal to samo, wiec to co powyzej napisalem to chyba raczej nie ma sensu :(

    pozdrawiam
  • Poziom 10  
    dodatkowe info

    podlaczylem oscyloskop zeby zobaczyc co sie dzieje z tym moim urzadzeniem i tak to wyglada:

    pilot logitech harmony (klawisz 7):
    [AT90S2323][ASM] odbiornik RC5 - dziala niestabilnie
    nokia e51 (w programie irRemote, symulacja pilota philipsa, klawisz 7):
    [AT90S2323][ASM] odbiornik RC5 - dziala niestabilnie

    harmony (klawisz 9):
    [AT90S2323][ASM] odbiornik RC5 - dziala niestabilnie
    nokia (klawisz 9):
    [AT90S2323][ASM] odbiornik RC5 - dziala niestabilnie


    z obrazkow widac, ze sygnal z nokii jest bardziej skompresowany niz z harmony
    ale nie rozumiem dlaczego tak jest, skoro harmony zostal "nauczony" wlasnie z nokii !!

    ktos pomoze ??

    pozdrawiam