Advertisement
Guest User

Untitled

a guest
Dec 11th, 2018
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.     list    p=PIC12F1822
  2.     include <p12F1822.inc>
  3. ; PIC12F1822 Configuration Bit Settings
  4. ; ASM source line config statements
  5. #include "p12F1822.inc"
  6.  
  7. ; CONFIG1
  8. ; __config 0x7A4
  9.  __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
  10. ; CONFIG2
  11. ; __config 0x1FFF
  12.  __CONFIG _CONFIG2, _WRT_OFF & _PLLEN_ON & _STVREN_ON & _BORV_LO & _LVP_OFF
  13.  
  14. ;*******************************************************************************
  15. ;*******************************************************************************
  16. ;                                                                              *
  17. ;   Programnavn:        Interface for Smart Alpha radio modul                  *
  18. ;                                                                              *
  19. ;   Dato:               17/3 2018                                               *
  20. ;   programversion:     2                                                      *
  21. ;                                                                              *
  22. ;   Udvikler:           Per Gaarde-Nissen                                      *
  23. ;   Organisation:       D&Pe undervisning på RTG                               *
  24. ;                                                                              *
  25. ;   Funktion:           Kommunikerer med Smart Alpha via fire signaler:        *
  26. ;                       - CTS: Smart Alpha signalerer at der er data klar      *
  27. ;                       - RTS: µP signalere at nu skal der kommunikeres        *
  28. ;                       - RX:  Data fra Smart Alpha til µP                     *
  29. ;                       - TX:  Data fra µP til Smart Alpha                     *
  30. ;                                                                              *
  31. ;                       Kommunikationen sker via µP's UART ved 9600 Baud       *
  32. ;                       CTS og RTS er handshake signaler                       *
  33. ;                                                                              *
  34. ;   Versioner:          Da PIC12F1822 kun har 8 ben, er der ikke mulighed for  *
  35. ;                       at implementerer alle funktioner på een gang i samme   *
  36. ;                       komponent.                                             *
  37. ;                       Derfor udføres programmet i to versioner:              *
  38. ;                                                                              *
  39. ;                       RX-versionen modtager serielle data fra radiomodulet   *
  40. ;                       SmartAlpha og omsætter disse data til PWM signaler på  *
  41. ;                       ben RA2 og RA5 skiftevis.                              *
  42. ;                                                                              *
  43. ;                       TX-versionen modtager analoge signaler på RA2 og RA4   *
  44. ;                       og AD-konverterer signalerne og sender dem serielt via *
  45. ;                       radiomodulet.                                          *
  46. ;                                                                              *
  47. ;*******************************************************************************
  48. ;
  49. ; AD-konverteringer og udgående RS232 kommunikation sker styret af interrupt.
  50. ; Derfor placeres AD-konverteringerne og udgående RS232 i interruptrutinen.
  51. ;
  52. ; Indgående RS232 sker asynkront bestemt af senderen, som styres udefra.
  53. ; Derfor placeres check for indgående RS232 kommunikation og fortolkning af
  54. ; kommandoer i VENT-løkken
  55. ;
  56. ; Sidenumre henviser til PIC12F1822 datablad DS40001413E 2010-2015.
  57. ;
  58. ;*******************************************************************************
  59. ; TX_2AD_SMA (Dette program)
  60. ; PIC12F1822 Microprocessor
  61. ; Version:      Analog ind
  62. ;               Seriel ud via SmartAlpha
  63. ;                                   ----------
  64. ;                               Vdd |1      8| Vss
  65. ; digital handshake ud   RTS <- RA5 |2      7| RA0 -> TXD       digital ud
  66. ; analog ind             AN3 -> RA4 |3      6| RA1 <- RXD       digital ind
  67. ; digital handshake ind  CTS -> RA3 |4      5| RA2 <- AN2       analog ind
  68. ;                                   ----------
  69. ;*******************************************************************************  
  70. ; RX_2AD_SMA (Det modsvarende tvillinge program)
  71. ; PIC12F1822 Microprocessor
  72. ; Version:      Seriel ind via SmartAlpha
  73. ;               Analog ud
  74. ;                                   ----------
  75. ;                               Vdd |1      8| Vss
  76. ; analog ud              PWM <- RA5 |2      7| RA0 -> TXD       digital ud
  77. ; digital handshake ud   RTS <- RA4 |3      6| RA1 <- RXD       digital ind
  78. ; digital handshake ind  CTS -> RA3 |4      5| RA2 -> PWM       analog ud
  79. ;                                   ----------
  80. ;*******************************************************************************
  81. ;  
  82. ;-------------------------------------------------------------------------------
  83. ; Definering af konstanter (ikke strengt nødvendigt, men øger læsbarheden)
  84. ;-------------------------------------------------------------------------------
  85.  
  86. #define     SMA_COM     a'+'    ; SmartAlpha sættes i kommando mode med ´+++´
  87. #define     SMA_TAD     0x7E    ; SmartAlpha sender til adressen 7E7E7E7E
  88. #define     SMA_TADI    0x7E    ; Sidste byte kan sættes til noget andet
  89. #define     SMA_RAD     0x7E    ; SmartAlpha modtager på adressen 7E7E7E7E
  90. #define     SMA_RADI    0x7E    ; Sidste byte kan sættes til noget andet                                
  91. #define     SMA_FRQH    0x06    ; Indstiller SmartAlpha's radiofrekvens
  92. #define     SMA_FRQL    0x40    ; Indstiller SmartAlpha's radiofrekvens  
  93. #define     SMA_PWR     0x00    ; Indstiller laveste SmartAlpha sendestyrke
  94. #define     SMA_BAUD    0x23    ; Indstiller SmartAlpha's baudrate til 9600
  95. #define     SMA_NORM    a'-'    ; SmartAlpha sættes i normal mode med ´---´                                                                
  96.                                                                
  97. ;------------------------------------------------------------------------------
  98. ; Definering af variable (ikke strengt nødvendigt, men øger læsbarheden)
  99. ;------------------------------------------------------------------------------                                
  100. AD2OUT  equ     0x20            ; Lagerplads for resultat af AD-konvertering  
  101. AD3OUT  equ     0x21            ; Lagerplads for resultat af AD-konvertering
  102. IT      equ     0x22            ; Interrupttæller
  103. BT      equ     0x23            ; Bytetæller      
  104.        
  105. ;*******************************************************************************
  106. ; Programafviklingen starter automatisk på adressen 0x0000 efter reset eller
  107. ; tilslutning af forsyningsspænding.
  108. ; Derfor lægger vi koden så den begynder i adresse 0x0000          
  109.                                
  110.         org 0x0000              ; Besked til compileren om at starte her
  111.         goto SETUP              ; Hop straks til SETUP rutinen
  112. ;*******************************************************************************
  113.         org 0x0004              ; Besked til compileren om at lægge den følgende
  114.                                 ; kode fra adresse 0004, som er den adresse hvor
  115.                                 ; INTERRUPT rutinen skal ligge.
  116. INTER                                  
  117.         BANKSEL 0
  118.         decfsz  IT,F            ;
  119.         goto    II              ; Spring over hvis IT>0
  120.         movlw   0x05            ;
  121.         movwf   IT              ; Reload IT
  122.         call    SAMPLE2         ; Kald AD-konvertering af AN2, ben 5
  123.         call    SAMPLE3         ; Kald AD-konvertering af AN3, ben 3
  124.         call    SMA_TX          ; Send resultatet af AD-konverteringerne            
  125. II      
  126.         BANKSEL TMR0
  127.         movlw   0x13            ; Med denne værdi kan man finjustere sample-
  128.         movwf   TMR0            ; frekvensen til 25Hz (brug ben 2 og PICOSCOPE)
  129.         BANKSEL INTCON
  130.         bcf     INTCON,TMR0IF   ; Afslut INTERRUPT med at cleare det flag, som
  131.                                 ; var årsag til at der blev et interrupt.
  132.         retfie                  ; Afslut med den særlige instruktion, som
  133.                                 ; rydder op og bringer programmet tilbage til
  134.                                 ; hvor det var, da interruptet blev kaldt
  135.                
  136. ;*******************************************************************************        
  137. ; For at indstille processoren behøves nogle kodelinier.  
  138. ; De kan passende lægges i en subrutine i begyndelsen af programmet.
  139.                                        
  140. SETUP  
  141. ;-------------------------------------------------------------------------------
  142. ; Konfigurering af oscillator
  143. ;-------------------------------------------------------------------------------
  144.         ;OSCCON                 ; Processoren kan fungere med en indbygget
  145.                                 ; oscillator.  Det vælger vi i stedet for at
  146.                                 ; benytte et eksternt krystal.  Det er muligt
  147.                                 ; at indstille den interne klokfrekvens til
  148.                                 ; mange forskellige værdier efter behov.
  149.                                 ; Oscillatoren er beskrevet i databladets
  150.                                 ; kapitel 5 og det kontrolregister, vi bruger
  151.                                 ; (OSCCON) er beskrevet på side 65 i databladet.
  152.                                 ; Vi vælger at lade processoren køre så hurtigt
  153.                                 ; som muligt i denne anvendelse.
  154.                                
  155.         ;         1----x--      ; PLL on, i virkeligheden har vi bestemt dette
  156.                                 ; i konfigurationen (_PLLEN_ON)
  157.         ;         -1110x--      ; Internal oscillator er 8MHz*4 (PLL on)
  158.         ;         -----x00      ; Klok bestemt i konfigurationen (FOSC_INTOSC)
  159.         movlw   b'11110000'        
  160.         BANKSEL OSCCON
  161.         movwf   OSCCON                
  162.        
  163. ;-------------------------------------------------------------------------------
  164. ; Konfigurering af porte, digitale og analoge
  165. ;-------------------------------------------------------------------------------
  166.         ;PORTA                  ; PORTA er et RAM-register, som har direkte
  167.                                 ; forbindelse til de fysiske ben på komponenten.
  168.                                 ; Læs om porte i databladets kapitel 12 som
  169.                                 ; begynder på side 112.
  170.                                                                                
  171.         BANKSEL PORTA
  172.         clrf    PORTA           ; Set alle ben til 0Volt                                
  173.                                                        
  174.         movlw   b'00010100'     ; Sæt RA2 og RA4 som analogt input
  175.         BANKSEL ANSELA          ; ANSELA registeret bestemmer hvilke ben, der
  176.         movwf   ANSELA          ; skal være analoge.  Læs i databladet side 118.
  177.        
  178.                                 ; TRISA registeret bestemmer hvilke ben, der
  179.                                 ; skal være input og hvilke ben, der skal være
  180.                                 ; output.  Læs i databladet side 117.
  181.         ;         xx0-----      ; RA5 er digitalt output (RTS)
  182.         ;         xx-1----      ; RA4 er digitalt input (overtrumfes af ANSELA)
  183.         ;         xx--1---      ; RA3 er input (CTS)
  184.         ;         xx---1--      ; RA2 er digitalt input (overtrumfes af ANSELA)
  185.         ;         xx----1-      ; RA1 er digitalt input (RXD)
  186.         ;         xx-----0      ; RA0 er digitalt output (TXD)
  187.         movlw   b'00011110'
  188.         BANKSEL TRISA
  189.         movwf   TRISA
  190.        
  191. ;-------------------------------------------------------------------------------
  192. ; Konfigurering af AD-konverter
  193. ;-------------------------------------------------------------------------------        
  194.         ;AD-konverter           ; AD konverteren kan tage sit input fra flere
  195.                                 ; forskellige ben.
  196.                                 ; Vi skal skifte mellem AN2 og AN3.
  197.                                 ; Læs om AD konverteren i databladet, side 130.
  198.                                
  199.         BANKSEL ADCON0          ; Læs om ADCON0 i databladet, side 136.
  200.         ;         x00000--      ; Vælg ingen kanal før senere
  201.         ;         x-----0-      ; Start ikke konverteringen endnu
  202.         ;         x------1      ; Enable AD konverteren
  203.         movlw   b'00000001'     ;
  204.         movwf   ADCON0
  205.        
  206.         BANKSEL ADCON1          ; Læs om ADCON1 i databladet, side 137.
  207.         ;         0---xx--      ; Resultatet justeres til venstre, side 133.
  208.         ;         -110xx--      ; Konverterings klok = Fosc/64, side 137.
  209.         ;         ----xx00      ; Referencen Vref+ = AVdd (forsyningsspændingen)
  210.         movlw   b'01100000'
  211.         movwf   ADCON1
  212.        
  213. ;-------------------------------------------------------------------------------
  214. ; Konfigurering af Timer0, som bruges til at generere interrupt
  215. ;-------------------------------------------------------------------------------
  216.         ;TIMER0                 ; TIMER0 sætter et flag hver gang den går fra
  217.                                 ; 255 til 0 (overflow).  Dette flag kan bruges
  218.                                 ; til at generere et interrupt, se side 163.
  219.                                 ; TIMER0 tæller på instruktionsklokken,
  220.                                 ; eventuelt med en indskudt prescaler, se side
  221.                                 ; 162 i databladet.
  222.                                 ; Bemærk, at TIMER0 altid er enabled, det vi
  223.                                 ; kan indstille er hvordan den bruges.
  224.                                 ; TIMER0 kan tælle på input fra et ben eller på
  225.                                 ; den interne klok.  Dette bestemmes af
  226.                                 ; bit TMR0CS i OPTION_REG.  Se side 164.
  227.                                 ; TIMER0 indstilles via OPTION registeret, vi
  228.                                 ; behøver kun gøre noget ved bit 0..3 og 5:
  229.         BANKSEL OPTION_REG      
  230.         bcf     OPTION_REG,TMR0CS; Tæl på intern klok.  Se side 164.
  231.         bcf     OPTION_REG,PSA  ; Clear PSA-bit for at tage prescaleren i brug
  232.         bsf     OPTION_REG,0    ; Timer0's prescaler sættes til 256 og vi
  233.         bsf     OPTION_REG,1    ; preloader ikke TIMER0 ved interrupt, men lader
  234.         bsf     OPTION_REG,2    ; blot timereren løbe.
  235.                                 ; Det giver en interruptfrekvens på
  236.                                 ; Finterrupt = ((32000000/4)/256)/256 = 122Hz
  237.                                 ; Bemærk at frekvensen kan øges ved at preloade
  238.                                 ; TIMER0 inde i interrupt-rutinen.
  239.                                 ; Desuden kan en lavere frekvens opnås ved at
  240.                                 ; springe en vis andel af interruptene over
  241.        
  242.         BANKSEL TMR0                        
  243.         clrf    TMR0            ; Nulstiller TIMER0 og dens prescaler, men
  244.                                 ; stopper ikke TIMER0
  245.                                
  246.         BANKSEL INTCON                        
  247.         bcf     INTCON,TMR0IF   ; Clear eventuel flag der er sat tidligere.
  248.         bcf     INTCON,TMR0IE   ; Slet flag, der tillader TIMER0 interrupt
  249.         bcf     INTCON,GIE      ; Slet flag, der globalt tillader interrupts                        
  250.        
  251. ;-------------------------------------------------------------------------------
  252. ; Konfigurering af Timer1, som bruges til at generere timeouts i TIMER
  253. ;-------------------------------------------------------------------------------                    
  254.         BANKSEL T1CON           ; Læs side 173 i databladet
  255.         ;         00----x-      ; Timer1 clock source is FOSC/4 (32MHz/4)
  256.         ;         --11--x-      ; Timer1 prescale = 1:8
  257.         ;         ----0-x-      ; Timer1 oscillator bruges ikke
  258.         ;         -----1x-      ; Synkroniseres ikke
  259.         ;         ------x0      ; Timer1 startes ikke endnu
  260.         movlw   b'00110100'     ;
  261.         movwf   T1CON           ;
  262.                                 ; Timer1 genererer overflow i løbet af
  263.                                 ; 65536/(8000000/8) = 65,5msek
  264.         BANKSEL T1GCON                        
  265.         bcf     T1GCON,TMR1GE   ; Brug ikke gate funktioner                        
  266.        
  267. ;-------------------------------------------------------------------------------
  268. ; Konfigurering af UART, seriel kommunikation - RS232  
  269. ;-------------------------------------------------------------------------------
  270.                                 ; Læs om RS232 i kapitel 26, side 268
  271.         BANKSEL TXSTA
  272.         bcf     TXSTA,TX9       ; TX9 =0, vi bruger 8 bit transmission
  273.         bsf     TXSTA,TXEN      ; TXEN=1, enable transmission
  274.         bcf     TXSTA,SYNC      ; SYNC=0, asynkron transmission
  275.         bcf     TXSTA,BRGH      ; BRGH=0, low Baud rate
  276.  
  277.         BANKSEL RCSTA
  278.         bsf     RCSTA,SREN      ;
  279.         bcf     RCSTA,RX9       ; RX9 =0, vi bruger 8 bit modtagelse
  280.         bsf     RCSTA,SPEN      ; SPEN=1, enable seriel port
  281.         bsf     RCSTA,CREN      ; CREN=1, enable modtager
  282.        
  283.         BANKSEL BAUDCON
  284.         bsf     BAUDCON,BRG16   ; BRG16=1, benyt 16bit Baud rate tæller
  285.        
  286. ;        movlw  0x00            ; Vi vælger baudrate = 38400
  287. ;        BANKSEL SPBRGH         ; Læs om baudrate fra side 260 og frem til 284.
  288. ;        movwf  SPBRGH          ; Det får vi med BRGH = 0 og SYNC =0 (i TXSTA)
  289. ;        movlw  0x33            ; og BRG16 = 1 (i BAUDCON)
  290. ;        BANKSEL SPBRGL
  291. ;        movwf  SPBRGL          ; og SPBRGL = 51 (SPBRGH = 0, SPBRGL = 51)
  292.                                 ; BR = 32000000/(16*(51+1)) = 38462
  293.                                
  294.         movlw   0x00            ; Vi vælger baudrate = 9600
  295.         BANKSEL SPBRGH          ; Læs om baudrate fra side 260 og frem til 284.
  296.         movwf   SPBRGH          ; Det får vi med BRGH = 0  og SYNC =0 (i TXSTA)
  297.         movlw   0xCF            ; og BRG16 = 1 (i BAUDCON)
  298.         BANKSEL SPBRGL
  299.         movwf   SPBRGL          ; og SPBRGL = 207 (SPBRGH = 0, SPBRGL = 207)
  300.                                 ; BR = 32000000/(16*(207+1)) = 9615                        
  301.                                
  302.         BANKSEL RCSTA
  303.         movf    RCSTA,W         ; Læs eventuelle flag
  304.         BANKSEL RCREG
  305.         movf    RCREG,W         ; Læs eventuelt modtagne byte for at cleare RCIF        
  306.        
  307. ;-------------------------------------------------------------------------------
  308. ; Konfigurering af Interrupt
  309. ;-------------------------------------------------------------------------------
  310.         ;INTERRUPT              ; Der er utallige mulige kilder til interrupt.
  311.                                 ; Som udgangspunkt er ingen af disse kilder
  312.                                 ; aktiverede, men her skal vi anvende TIMER0
  313.                                 ; og derfor skal vi aktivere (enable) denne
  314.                                 ; mulighed.  Læs om interrupt side 80.
  315.                                 ; Signalflaget fra TIMER0 er TMR0IF.
  316.                                 ; Kontrollen af om dette TIMER0 må generere
  317.                                 ; interrupt styres af TMR0IE.                                
  318.                                 ; Kontrollen af om der i det hele taget kan
  319.                                 ; reageres på interrupts, uanset kilde, styres
  320.                                 ; af GIE.
  321.                                 ; Disse to flag findes i registeret INTCON.
  322.                                 ; Inden vi enabler interrupt fra TIMER0 er det
  323.                                 ; en god ide at cleare TIMER0, så der bliver
  324.                                 ; lidt tid at løbe på inden første interrupt:
  325.         BANKSEL TMR0                        
  326.         clrf    TMR0            ; Nulstiller TIMER0 og dens prescaler, men
  327.                                 ; stopper ikke TIMER0
  328.         BANKSEL INTCON          ; Disable alle interrupts              
  329.         bcf     INTCON,TMR0IF   ; Clear eventuel flag der er sat tidligere.
  330.         bcf     INTCON,TMR0IE   ; Slet flag, der tillader TIMER0 interrupt
  331.         bcf     INTCON,GIE      ; Slet flag, der globalt tillader interrupts
  332.                
  333. ;*******************************************************************************
  334. ; Programafviklingen starter med at radiomodulet SmartAlpha initieres.        
  335. ;*******************************************************************************
  336. START                           ; SmartAlpha behøver ca 150ms til at varme op.
  337.                                 ; Derfor venter vi 3*65,5ms før initialiseringen
  338.         call    TIMEOUT         ; Start TIMER1 som timeout timer 65,5ms maks
  339.         BANKSEL PIR1
  340.         btfss   PIR1,TMR1IF     ; Bit sat hvis timeout
  341.         goto    $-1             ; Vent på overflow        
  342.         call    TIMEOUT         ; Start TIMER1 som timeout timer 65,5ms maks
  343.         BANKSEL PIR1
  344.         btfss   PIR1,TMR1IF     ; Bit sat hvis timeout
  345.         goto    $-1             ; Vent på overflow      
  346.         call    TIMEOUT         ; Start TIMER1 som timeout timer 65,5ms maks
  347.         BANKSEL PIR1
  348.         btfss   PIR1,TMR1IF     ; Bit sat hvis timeout
  349.         goto    $-1             ; Vent på overflow      
  350.         call    SMA_INI         ; Initialiserer SmartAlpha
  351.        
  352.         movf    WREG,W          ; W=0 betyder OK, W<>0 betyder fejl i initiering
  353.         btfss   STATUS,Z        ; W=0 => Z=1 og det betyder OK at gå videre
  354.         goto    START           ; Forfra hvis ikke OK
  355.        
  356.         BANKSEL 0
  357.         movlw   0x05            ;
  358.         movwf   IT              ; Startværdi for IT
  359.        
  360.         BANKSEL INTCON          ; Enable interrupt fra TIMER0              
  361.         bcf     INTCON,TMR0IF   ; Clear eventuel flag der er sat tidligere.
  362.         bsf     INTCON,TMR0IE   ; Sæt flag, der tillader TIMER0 interrupt
  363.         bsf     INTCON,GIE      ; Sæt flag, der globalt tillader interrupts
  364.        
  365. ;*******************************************************************************    
  366. VENT                            ; Her står programmet blot og kører i ring uden
  367.                                 ; at foretage sig andet end at vente på
  368.                                 ; interrupt.
  369.                                 ; Imens tælles TIMER0 op og på et tidspunkt
  370.                                 ; sker der et overflow i TIMER0 hvilket giver
  371.                                 ; et interrupt, hvorved interrupt rutinen bliver
  372.                                 ; kaldt.
  373.                                 ; Når interrupt rutinen er færdig returnerer
  374.                                 ; programmet til at stå og vente her på næste
  375.                                 ; gang TIMER0 har overflow.                                
  376.         goto    VENT            ;
  377.  
  378. ;*******************************************************************************        
  379. SAMPLE2                         ; Denne rutine udfører AD konvertering af AN2
  380.                                 ; Når den er færdig overføres ADRESH til AD2OUT
  381.                                 ; ADRESL bruges ikke
  382.        
  383.         BANKSEL ADCON0          ; Læs om ADCON0 i databladet, side 136.
  384.         ;         x00010--      ; Vælg kanal AN2, ben 5
  385.         ;         x-----0-      ; Start ikke konverteringen endnu
  386.         ;         x------1      ; Enable AD konverteren
  387.         movlw   b'00001001'     ;
  388.         movwf   ADCON0
  389.        
  390.         movlw   d'20'           ; Forsinkelse så AD-multiplexeren kan følge med
  391.         decfsz  WREG,F
  392.         goto    $-1
  393.        
  394.         bsf     ADCON0,GO       ; Start AD konverteringen
  395.         btfsc   ADCON0,GO       ; Test om konverteringen er færdig
  396.         goto    $-1             ; Ellers vent og test igen
  397.                                
  398.         BANKSEL ADRESH
  399.         movf    ADRESH,W        ;
  400.         BANKSEL AD2OUT
  401.         movwf   AD2OUT          ; AD2OUT = resultat af konverteringen
  402.        
  403.         return                
  404.        
  405. ;*******************************************************************************        
  406. SAMPLE3                         ; Denne rutine udfører AD konvertering af AN3
  407.                                 ; Når den er færdig overføres ADRESH til AD3OUT
  408.                                 ; ADRESL bruges ikke
  409.                                
  410.         BANKSEL ADCON0          ; Læs om ADCON0 i databladet, side 136.
  411.         ;         x00011--      ; Vælg kanal AN3, ben 3
  412.         ;         x-----0-      ; Start ikke konverteringen endnu
  413.         ;         x------1      ; Enable AD konverteren
  414.         movlw   b'00001101'     ;
  415.         movwf   ADCON0  
  416.        
  417.         movlw   d'20'           ; Forsinkelse så AD-multiplexeren kan følge med
  418.         decfsz  WREG,F
  419.         goto    $-1
  420.        
  421.         bsf     ADCON0,GO       ; Start AD konverteringen
  422.         btfsc   ADCON0,GO       ; Test om konverteringen er færdig
  423.         goto    $-1             ; Ellers vent og test igen
  424.                                
  425.         BANKSEL ADRESH
  426.         movf    ADRESH,W        ;
  427.         BANKSEL AD3OUT
  428.         movwf   AD3OUT          ; AD3OUT = resultat af konverteringen
  429.        
  430.         return                
  431.        
  432. ;*******************************************************************************        
  433. SMA_TX                          ; SMA_TX skal sende 2 bytes:  AD2OUT og AD3OUT
  434.         BANKSEL LATA                          
  435.         bcf     LATA,5          ; Sæt RTS lav                
  436.                                
  437.         BANKSEL AD2OUT
  438.         movf    AD2OUT,W        ; WREG = AD2OUT
  439.         call    SEND            ; Send første byte
  440.        
  441.         BANKSEL AD3OUT
  442.         movf    AD3OUT,W        ; WREG = AD3OUT
  443.         call    SEND            ; Send anden byte
  444.        
  445.         BANKSEL TXSTA
  446.         btfss   TXSTA,TRMT
  447.         goto    $-1             ; Vent til alt er sendt
  448.        
  449.         BANKSEL LATA  
  450.         bsf     LATA,5          ; Sæt RTS høj
  451.        
  452.         return                  ;
  453.                            
  454. ;*******************************************************************************
  455. ; Subrutinen "SEND" checker om UARTen er klar til næste byte og
  456. ; skriver derefter indholdet af W til senderegisteret.
  457. ; UARTen vil derefter automatisk sende denne byte selvom SEND-routinen
  458. ; returnerer med det samme.
  459. ; Bemærk! Programmet bliver hængende i denne routine indtil forrige
  460. ; byte er igang med at blive sendt eller allerede er sendt. Dette er
  461. ; normalt intet problem.
  462. ; Hvis senderen ikke har gang i noget i forvejen kan man skrive to bytes til
  463. ; sendebufferen lige efter hinanden.  Læs herom i kapitel 26, side 268.        
  464. ;*******************************************************************************       
  465. SEND    
  466.         BANKSEL PIR1
  467.         btfss   PIR1,TXIF       ; Klar til at sende ny byte? (bit = 1)
  468.         goto    SEND            ; - ellers vent
  469.         BANKSEL TXREG
  470.         movwf   TXREG           ; Skriv indholdet af W til senderegister
  471.         return                  ;
  472.        
  473. ;*******************************************************************************
  474. ; Når man skriver et program, der kommunikerer med en anden enhed, som man ikke
  475. ; har fuld kontrol over (måske er den ikke monteret eller fungerer ikke) er det
  476. ; nyttigt at have en metode til at undgå at komme til at vente i det uendelige
  477. ; på et respons, som måske aldrig kommer.
  478. ; En egnet måde er at benytte en tæller til at generere et timeout signal, hvis
  479. ; det varer for længe med et eller andet.  
  480. ; Lidt som at bruge et stopur, så man ikke sover for længe.
  481. ;*******************************************************************************        
  482. TIMEOUT                         ; Vi benytter Timer1 som timeout timer, så
  483.                                 ; programmet ikke risikerer at blive hængende
  484.                                 ; i al evighed. Se side 173 i databladet.
  485.                                 ; Timer1 er sat op til at generere overflow i
  486.                                 ; løbet af 65,5msek.
  487.                                 ; Timer1 overflow benyttes som timeout.
  488.         BANKSEL PIR1                                        
  489.         bcf     PIR1,TMR1IF     ; Sørg for at Timer1 interrupt flag er clearet
  490.         BANKSEL T1CON
  491.         bcf     T1CON,TMR1ON    ; Stop Timer1
  492.         BANKSEL TMR1H
  493.         clrf    TMR1H           ; Clear Timer1, det vil sige start forfra
  494.         BANKSEL TMR1L
  495.         clrf    TMR1L           ; Clear Timer1, det vil sige start forfra
  496.         BANKSEL T1CON
  497.         bsf     T1CON,TMR1ON    ; Start Timer1
  498.                
  499.         return                  
  500.  
  501. ;*******************************************************************************
  502. ; Den følgende rutine sammenligner de konfigurations data, der ligger i lageret
  503. ; fra adresse 0x0070 og frem med den ønskede konfiguration, som er defineret i
  504. ; begyndelsen af programmet som konstanter.
  505. ; Hvis alt stemmer returnerer rutinen med WREG=0    
  506. ; Hvis der konstateres en forskel returnerer rutinen med WREG<>0        
  507. ;*******************************************************************************        
  508. CHECKCONFIG
  509.         clrf    FSR0H           ; Sæt FSR0 til at pege på adresse 0x0070
  510.         movlw   0x70            ;
  511.         movwf   FSR0L           ;
  512.        
  513.         moviw   INDF0++         ;
  514.         sublw   SMA_TAD         ; Sammenlig med første sende-adresse-byte
  515.         btfss   STATUS,Z        ; Hvis match så er Z-flag sat
  516.         goto    MISMATCH        ; Gå til fejl hvis mismatch
  517.        
  518.         moviw   INDF0++         ;
  519.         sublw   SMA_TAD         ; Sammenlig med anden sende-adresse-byte
  520.         btfss   STATUS,Z        ; Hvis match så er Z-flag sat
  521.         goto    MISMATCH        ; Gå til fejl hvis mismatch
  522.        
  523.         moviw   INDF0++         ;
  524.         sublw   SMA_TAD         ; Sammenlig med tredje sende-adresse-byte
  525.         btfss   STATUS,Z        ; Hvis match så er Z-flag sat
  526.         goto    MISMATCH        ; Gå til fejl hvis mismatch
  527.        
  528.         moviw   INDF0++         ;
  529.         sublw   SMA_TADI        ; Sammenlig med fjerde sende-adresse-byte
  530.         btfss   STATUS,Z        ; Hvis match så er Z-flag sat
  531.         goto    MISMATCH        ; Gå til fejl hvis mismatch
  532.        
  533.         moviw   INDF0++         ;
  534.         sublw   SMA_RAD         ; Sammenlig med første modtage-adresse-byte
  535.         btfss   STATUS,Z        ; Hvis match så er Z-flag sat
  536.         goto    MISMATCH        ; Gå til fejl hvis mismatch
  537.        
  538.         moviw   INDF0++         ;
  539.         sublw   SMA_RAD         ; Sammenlig med anden modtage-adresse-byte
  540.         btfss   STATUS,Z        ; Hvis match så er Z-flag sat
  541.         goto    MISMATCH        ; Gå til fejl hvis mismatch
  542.        
  543.         moviw   INDF0++         ;
  544.         sublw   SMA_RAD         ; Sammenlig med tredje modtage-adresse-byte
  545.         btfss   STATUS,Z        ; Hvis match så er Z-flag sat
  546.         goto    MISMATCH        ; Gå til fejl hvis mismatch
  547.        
  548.         moviw   INDF0++         ;
  549.         sublw   SMA_RADI         ; Sammenlig med fjerde modtage-adresse-byte
  550.         btfss   STATUS,Z        ; Hvis match så er Z-flag sat
  551.         goto    MISMATCH        ; Gå til fejl hvis mismatch
  552.        
  553.         moviw   INDF0++         ;
  554.         sublw   SMA_FRQH        ; Sammenlig med første radiofrekvens-byte
  555.         btfss   STATUS,Z        ; Hvis match så er Z-flag sat
  556.         goto    MISMATCH        ; Gå til fejl hvis mismatch
  557.        
  558.         moviw   INDF0++         ;
  559.         sublw   SMA_FRQL        ; Sammenlig med anden radiofrekvens-byte
  560.         btfss   STATUS,Z        ; Hvis match så er Z-flag sat
  561.         goto    MISMATCH        ; Gå til fejl hvis mismatch
  562.        
  563.         moviw   INDF0++         ;
  564.         sublw   SMA_PWR         ; Sammenlig med sendestyrke-byte
  565.         btfss   STATUS,Z        ; Hvis match så er Z-flag sat
  566.         goto    MISMATCH        ; Gå til fejl hvis mismatch
  567.        
  568.         moviw   INDF0++         ;
  569.         sublw   SMA_BAUD        ; Sammenlig med baudrate-byte
  570.         btfss   STATUS,Z        ; Hvis match så er Z-flag sat
  571.         goto    MISMATCH        ; Gå til fejl hvis mismatch
  572.                
  573.         retlw   0x00            ; Hvis alt passer returneres med WREG=0
  574.        
  575. MISMATCH        
  576.         retlw   0x01            ; Hvis mismatch returneres med WREG<>0
  577.                
  578. ;*******************************************************************************
  579. ; Subrutinen SMA_INI initiliserer radiomodulet SmartAlpha
  580. ; SmartAlpha kan være i "Normal Mode" eller i "Configuration Mode"
  581. ; "Normal Mode" benyttes når radiomodulet skal bruges til at kommunikere
  582. ; "Configuration Mode" benyttes til at indstille måden radiomodulet fungerer  
  583. ; Læs om indstillingsmulighederne i databladet for SmartAlpha, afsnit 3.
  584. ; Normalt vil vi kun have behov for at justere adresserne.
  585. ; SmartAlpha kan sættes i "Configuration Mode" ved at sende '+++' til modulet.
  586. ; SmartAlpha kan sættes i "Normal Mode" ved at sende '---' til modulet.
  587. ;
  588. ; Fremgangsmåden i initialiserings rutinen er følgende:
  589. ; 1: Skift til "Configuration Mode"        
  590. ; 2: Aflæs hvordan SmartAlpha aktuelt er konfigureret
  591. ; 3: Sammenlign med den ønskede konfiguration
  592. ; 4: Gå til punkt 8 hvis der ikke er behov for ændring
  593. ; 5: Skriv den nye ønskede konfiguration til SmartAlpha
  594. ; 6: Vent på at SmartAlpha installerer den nye konfiguration i hukommelsen        
  595. ; 7: Gå til punkt 2 for at se om ændringen er gennemført
  596. ; 8: Skift til "Normal Mode"
  597. ; 9: Vent på at SmartAlpha gennemfører skiftet til "Normal Mode"
  598. ;        
  599. ; Undervejs benyttes de to handshake signaler RTS og CTS til at kontrollere
  600. ; hvornår der kommunikeres.
  601. ; RTS er måden vi beder SmartAlpha om at få opmærksomhed (skrive og læse)
  602. ; CTS er måden SmartAlpha signalerer at modulet er optaget af at gøre noget        
  603. ;*******************************************************************************
  604. SMA_INI ;-----------------------------------------------------------------------
  605.         ; Først fortæller vi SmartAlpha, at vi vil kommunikere
  606.         ; Det gøres ved at sætte RTS signalet lavt
  607.         ; Mens RTS er lav kan radiomodulet ikke modtage radiosignaler
  608.         ;-----------------------------------------------------------------------
  609.         BANKSEL LATA  
  610.         bcf     LATA,5          ; Sæt RTS lav
  611.        
  612.         ; Trin 1
  613.         ;-----------------------------------------------------------------------
  614.         ; Send 3 gange '+' for at sætte SmartAlpha i configuration mode
  615.         ;-----------------------------------------------------------------------
  616.         BANKSEL LATA  
  617.         bcf     LATA,5          ; Sæt RTS lav
  618.         movlw   SMA_COM         ; Send 3 gange '+'
  619.         call    SEND            ; for at sætte SmartAlpha i kommando mode
  620.         movlw   SMA_COM         ;
  621.         call    SEND            ;
  622.         movlw   SMA_COM         ;
  623.         call    SEND            ;
  624.         BANKSEL TXSTA
  625.         btfss   TXSTA,TRMT      ; Vent til alle bytes er sendt
  626.         goto    $-1             ;
  627.        
  628. ;        BANKSEL PORTA           ;!!!!!!!!!!
  629. ;        bcf     PORTA,4         ;!!!!!!!!!!
  630.        
  631.         ; Trin 2
  632.         ;-----------------------------------------------------------------------
  633.         ; SmartAlpha svarer med at sende sin nuværende konfiguration
  634.         ; Vi gemmer konfigurationen på adresserne fra og med 0x0070
  635.         ;-----------------------------------------------------------------------
  636.         clrf    FSR0H           ; Sæt FSR0 til at pege på adresse 0x0070
  637.         movlw   0x70            ;
  638.         movwf   FSR0L           ;
  639.                        
  640.         BANKSEL 0               ; Vi venter at modtage 12 bytes fra SmartAlpha
  641.         movlw   0x0C            ;
  642.         movwf   BT              ; Sæt bytetæller til 12
  643.        
  644.         BANKSEL RCSTA
  645.         btfsc   RCSTA,OERR      ; Kontrollér om der er overrun fejl
  646.         goto    RESTART         ; Restart UART hvis fejl
  647.         btfss   RCSTA,FERR      ; Kontrollér om der er framing fejl
  648.         goto    U_OK            ; Fortsæt hvis ingen fejl
  649. RESTART bcf     RCSTA,SPEN      ; SPEN=0, disable seriel port
  650.         bcf     RCSTA,CREN      ; CREN=0, disable modtager
  651.         bsf     RCSTA,SREN      ;
  652.         bcf     RCSTA,RX9       ; RX9 =0, vi bruger 8 bit modtagelse
  653.         bsf     RCSTA,SPEN      ; SPEN=1, enable seriel port
  654.         bsf     RCSTA,CREN      ; CREN=1, enable modtager
  655.        
  656. U_OK    call    TIMEOUT         ; Start TIMER1 som timeout timer 65,5ms maks
  657.        
  658. VIN        
  659.         BANKSEL PIR1
  660.         movfw   PIR1
  661.         btfsc   WREG,TMR1IF     ; Bit sat hvis timeout
  662.         goto    SMA_TO          ; Afslut hvis timeout
  663.         btfss   WREG,RCIF       ; Bit er sat hvis der er input
  664.         goto    VIN             ; Ellers prøv igen        
  665.         BANKSEL RCREG
  666.         movf    RCREG,W         ; Hent ciffer fra RCREG
  667.         movwi   INDF0++         ; Gem i lager peget på af FSR0H:FSR0L, tæl op
  668.        
  669.         BANKSEL 0
  670.         decfsz  BT,F            ; Tæl bytetæller ned
  671.         goto    VIN             ; en gang til hvis BT>0
  672.        
  673.         ; Trin 3
  674.         ;-----------------------------------------------------------------------
  675.         ; Herefter kontrolleres om den modtagne konfiguration passer med
  676.         ; den ønskede konfiguration
  677.         ;-----------------------------------------------------------------------
  678.         call    CHECKCONFIG
  679.         movf    WREG,W          ; W=0 betyder OK, W<>0 betyder opdater værdierne
  680.         btfsc   STATUS,Z        ; W=0 => Z=1 og det betyder OK at gå videre
  681.         ; Trin 4
  682.         goto    SMA_OK          ; Spring ny konfiguration over hvis OK
  683.        
  684.         ; Trin 5
  685.         ;-----------------------------------------------------------------------
  686.         ; Hvis den modtagen konfiguration ikke passer sendes den ønskede
  687.         ; konfiguration til SmartAlpha
  688.         ;-----------------------------------------------------------------------
  689. SETCONF        
  690.         movlw   SMA_TAD         ; Send 4 gange 7E
  691.         call    SEND            ; for at definere sendeadressen
  692.         movlw   SMA_TAD         ;
  693.         call    SEND            ;
  694.         movlw   SMA_TAD         ;
  695.         call    SEND            ;
  696.         movlw   SMA_TADI        ; Her kan stå en anden individuel værdi
  697.         call    SEND            ;
  698.        
  699.         movlw   SMA_RAD         ; Send 4 gange 7E
  700.         call    SEND            ; for at definere modtageadressen
  701.         movlw   SMA_RAD         ;
  702.         call    SEND            ;
  703.         movlw   SMA_RAD         ;
  704.         call    SEND            ;
  705.         movlw   SMA_RADI        ; Her kan stå en anden individuel værdi
  706.         call    SEND            ;
  707.        
  708.         movlw   SMA_FRQH        ; Indstiller SmartAlphas's radiofrekvens
  709.         call    SEND            ;
  710.         movlw   SMA_FRQL        ;
  711.         call    SEND            ;
  712.        
  713.         movlw   SMA_PWR         ; Indstiller SmartAlpha's sendestyrke
  714.         call    SEND            ;
  715.        
  716.         movlw   SMA_BAUD        ; Indstiller SmartAlpha's baudrate
  717.         call    SEND            ;
  718.        
  719.         ; Trin 6
  720.         ;-----------------------------------------------------------------------
  721.         ; SmartAlpha bruger noget tid på at gemme den nye konfiguration.
  722.         ; Først går CTS høj og senere, når SmartAlpha er færdig, går CTS lav
  723.         ;-----------------------------------------------------------------------
  724.         call    TIMEOUT        
  725. CTSH1
  726.         BANKSEL PIR1
  727.         movfw   PIR1
  728.         btfsc   WREG,TMR1IF     ; Bit sat hvis timeout
  729.         goto    SMA_TO          ; Afslut hvis timeout
  730.         BANKSEL PORTA           ; Vent på at CTS går høj
  731.         btfss   PORTA,3
  732.         goto    CTSH1
  733. CTSL1
  734.         BANKSEL PIR1
  735.         movfw   PIR1
  736.         btfsc   WREG,TMR1IF     ; Bit sat hvis timeout
  737.         goto    SMA_TO          ; Afslut hvis timeout        
  738.         BANKSEL PORTA           ; Vent på at CTS går lav
  739.         btfsc   PORTA,3
  740.         goto    CTSL1
  741.        
  742.         ; Trin 7
  743.         ;-----------------------------------------------------------------------
  744.         ; Når programmet kommer her er det fordi konfigurationen er opdateret.
  745.         ; Derfor skal vi lige checke, at den nu er i orden.
  746.         ;-----------------------------------------------------------------------
  747.         goto    SMA_INI         ; Forfra for at checke
  748.        
  749.         ; Trin 8
  750.         ;-----------------------------------------------------------------------
  751.         ; SmartAlpha sættes tilbage til normal mode ved at sende 3 gange '-'
  752.         ;-----------------------------------------------------------------------
  753. SMA_OK        
  754.         movlw   SMA_NORM        ; Send 3 gange '-'
  755.         call    SEND            ; for at sætte SmartAlpha i kommando mode
  756.         movlw   SMA_NORM        ;
  757.         call    SEND            ;
  758.         movlw   SMA_NORM        ;
  759.         call    SEND            ;
  760.         BANKSEL TXSTA
  761.         btfss   TXSTA,TRMT      ; Vent til alle bytes er sendt
  762.         goto    $-1             ;
  763.        
  764.         ; Trin 9
  765.         ;-----------------------------------------------------------------------
  766.         ; SmartAlpha bruger noget tid på at skifte til "Normal Mode".
  767.         ; Først går CTS høj og senere, når SmartAlpha er færdig, går CTS lav
  768.         ;-----------------------------------------------------------------------
  769.         call    TIMEOUT        
  770. CTSH2
  771.         BANKSEL PIR1
  772.         movfw   PIR1
  773.         btfsc   WREG,TMR1IF     ; Bit sat hvis timeout
  774.         goto    SMA_TO          ; Afslut hvis timeout
  775.         BANKSEL PORTA           ; Vent på at CTS går høj
  776.         btfss   PORTA,3
  777.         goto    CTSH2
  778. CTSL2
  779.         BANKSEL PIR1
  780.         movfw   PIR1
  781.         btfsc   WREG,TMR1IF     ; Bit sat hvis timeout
  782.         goto    SMA_TO          ; Afslut hvis timeout        
  783.         BANKSEL PORTA           ; Vent på at CTS går lav
  784.         btfsc   PORTA,3
  785.         goto    CTSL2
  786.                
  787.         ;-----------------------------------------------------------------------
  788.         ; Til sidst sættes SmartAlpha fri igen ved at sætte RTS høj
  789.         ;-----------------------------------------------------------------------  
  790.         clrf    WREG            ; Rutinen returnerer med WREG=0 hvis alt OK
  791.         BANKSEL PORTA  
  792.         bsf     PORTA,5         ; Sæt RTS høj
  793.         return
  794.        
  795. SMA_TO  movlw   0x01            ; Rutinen returnerer med WREG>0 hvis fejl
  796.         BANKSEL PORTA  
  797.         bsf     PORTA,5         ; Sæt RTS høj
  798.         return
  799.        
  800. ;*******************************************************************************                          
  801.         END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement