Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- list p=PIC12F1822
- include <p12F1822.inc>
- ; PIC12F1822 Configuration Bit Settings
- ; ASM source line config statements
- #include "p12F1822.inc"
- ; CONFIG1
- ; __config 0x7A4
- __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
- ; CONFIG2
- ; __config 0x1FFF
- __CONFIG _CONFIG2, _WRT_OFF & _PLLEN_ON & _STVREN_ON & _BORV_LO & _LVP_OFF
- ;*******************************************************************************
- ;*******************************************************************************
- ; *
- ; Programnavn: Interface for Smart Alpha radio modul *
- ; *
- ; Dato: 17/3 2018 *
- ; programversion: 2 *
- ; *
- ; Udvikler: Per Gaarde-Nissen *
- ; Organisation: D&Pe undervisning på RTG *
- ; *
- ; Funktion: Kommunikerer med Smart Alpha via fire signaler: *
- ; - CTS: Smart Alpha signalerer at der er data klar *
- ; - RTS: µP signalere at nu skal der kommunikeres *
- ; - RX: Data fra Smart Alpha til µP *
- ; - TX: Data fra µP til Smart Alpha *
- ; *
- ; Kommunikationen sker via µP's UART ved 9600 Baud *
- ; CTS og RTS er handshake signaler *
- ; *
- ; Versioner: Da PIC12F1822 kun har 8 ben, er der ikke mulighed for *
- ; at implementerer alle funktioner på een gang i samme *
- ; komponent. *
- ; Derfor udføres programmet i to versioner: *
- ; *
- ; RX-versionen modtager serielle data fra radiomodulet *
- ; SmartAlpha og omsætter disse data til PWM signaler på *
- ; ben RA2 og RA5 skiftevis. *
- ; *
- ; TX-versionen modtager analoge signaler på RA2 og RA4 *
- ; og AD-konverterer signalerne og sender dem serielt via *
- ; radiomodulet. *
- ; *
- ;*******************************************************************************
- ;
- ; AD-konverteringer og udgående RS232 kommunikation sker styret af interrupt.
- ; Derfor placeres AD-konverteringerne og udgående RS232 i interruptrutinen.
- ;
- ; Indgående RS232 sker asynkront bestemt af senderen, som styres udefra.
- ; Derfor placeres check for indgående RS232 kommunikation og fortolkning af
- ; kommandoer i VENT-løkken
- ;
- ; Sidenumre henviser til PIC12F1822 datablad DS40001413E 2010-2015.
- ;
- ;*******************************************************************************
- ; TX_2AD_SMA (Dette program)
- ; PIC12F1822 Microprocessor
- ; Version: Analog ind
- ; Seriel ud via SmartAlpha
- ; ----------
- ; Vdd |1 8| Vss
- ; digital handshake ud RTS <- RA5 |2 7| RA0 -> TXD digital ud
- ; analog ind AN3 -> RA4 |3 6| RA1 <- RXD digital ind
- ; digital handshake ind CTS -> RA3 |4 5| RA2 <- AN2 analog ind
- ; ----------
- ;*******************************************************************************
- ; RX_2AD_SMA (Det modsvarende tvillinge program)
- ; PIC12F1822 Microprocessor
- ; Version: Seriel ind via SmartAlpha
- ; Analog ud
- ; ----------
- ; Vdd |1 8| Vss
- ; analog ud PWM <- RA5 |2 7| RA0 -> TXD digital ud
- ; digital handshake ud RTS <- RA4 |3 6| RA1 <- RXD digital ind
- ; digital handshake ind CTS -> RA3 |4 5| RA2 -> PWM analog ud
- ; ----------
- ;*******************************************************************************
- ;
- ;-------------------------------------------------------------------------------
- ; Definering af konstanter (ikke strengt nødvendigt, men øger læsbarheden)
- ;-------------------------------------------------------------------------------
- #define SMA_COM a'+' ; SmartAlpha sættes i kommando mode med ´+++´
- #define SMA_TAD 0x7E ; SmartAlpha sender til adressen 7E7E7E7E
- #define SMA_TADI 0x7E ; Sidste byte kan sættes til noget andet
- #define SMA_RAD 0x7E ; SmartAlpha modtager på adressen 7E7E7E7E
- #define SMA_RADI 0x7E ; Sidste byte kan sættes til noget andet
- #define SMA_FRQH 0x06 ; Indstiller SmartAlpha's radiofrekvens
- #define SMA_FRQL 0x40 ; Indstiller SmartAlpha's radiofrekvens
- #define SMA_PWR 0x00 ; Indstiller laveste SmartAlpha sendestyrke
- #define SMA_BAUD 0x23 ; Indstiller SmartAlpha's baudrate til 9600
- #define SMA_NORM a'-' ; SmartAlpha sættes i normal mode med ´---´
- ;------------------------------------------------------------------------------
- ; Definering af variable (ikke strengt nødvendigt, men øger læsbarheden)
- ;------------------------------------------------------------------------------
- AD2OUT equ 0x20 ; Lagerplads for resultat af AD-konvertering
- AD3OUT equ 0x21 ; Lagerplads for resultat af AD-konvertering
- IT equ 0x22 ; Interrupttæller
- BT equ 0x23 ; Bytetæller
- ;*******************************************************************************
- ; Programafviklingen starter automatisk på adressen 0x0000 efter reset eller
- ; tilslutning af forsyningsspænding.
- ; Derfor lægger vi koden så den begynder i adresse 0x0000
- org 0x0000 ; Besked til compileren om at starte her
- goto SETUP ; Hop straks til SETUP rutinen
- ;*******************************************************************************
- org 0x0004 ; Besked til compileren om at lægge den følgende
- ; kode fra adresse 0004, som er den adresse hvor
- ; INTERRUPT rutinen skal ligge.
- INTER
- BANKSEL 0
- decfsz IT,F ;
- goto II ; Spring over hvis IT>0
- movlw 0x05 ;
- movwf IT ; Reload IT
- call SAMPLE2 ; Kald AD-konvertering af AN2, ben 5
- call SAMPLE3 ; Kald AD-konvertering af AN3, ben 3
- call SMA_TX ; Send resultatet af AD-konverteringerne
- II
- BANKSEL TMR0
- movlw 0x13 ; Med denne værdi kan man finjustere sample-
- movwf TMR0 ; frekvensen til 25Hz (brug ben 2 og PICOSCOPE)
- BANKSEL INTCON
- bcf INTCON,TMR0IF ; Afslut INTERRUPT med at cleare det flag, som
- ; var årsag til at der blev et interrupt.
- retfie ; Afslut med den særlige instruktion, som
- ; rydder op og bringer programmet tilbage til
- ; hvor det var, da interruptet blev kaldt
- ;*******************************************************************************
- ; For at indstille processoren behøves nogle kodelinier.
- ; De kan passende lægges i en subrutine i begyndelsen af programmet.
- SETUP
- ;-------------------------------------------------------------------------------
- ; Konfigurering af oscillator
- ;-------------------------------------------------------------------------------
- ;OSCCON ; Processoren kan fungere med en indbygget
- ; oscillator. Det vælger vi i stedet for at
- ; benytte et eksternt krystal. Det er muligt
- ; at indstille den interne klokfrekvens til
- ; mange forskellige værdier efter behov.
- ; Oscillatoren er beskrevet i databladets
- ; kapitel 5 og det kontrolregister, vi bruger
- ; (OSCCON) er beskrevet på side 65 i databladet.
- ; Vi vælger at lade processoren køre så hurtigt
- ; som muligt i denne anvendelse.
- ; 1----x-- ; PLL on, i virkeligheden har vi bestemt dette
- ; i konfigurationen (_PLLEN_ON)
- ; -1110x-- ; Internal oscillator er 8MHz*4 (PLL on)
- ; -----x00 ; Klok bestemt i konfigurationen (FOSC_INTOSC)
- movlw b'11110000'
- BANKSEL OSCCON
- movwf OSCCON
- ;-------------------------------------------------------------------------------
- ; Konfigurering af porte, digitale og analoge
- ;-------------------------------------------------------------------------------
- ;PORTA ; PORTA er et RAM-register, som har direkte
- ; forbindelse til de fysiske ben på komponenten.
- ; Læs om porte i databladets kapitel 12 som
- ; begynder på side 112.
- BANKSEL PORTA
- clrf PORTA ; Set alle ben til 0Volt
- movlw b'00010100' ; Sæt RA2 og RA4 som analogt input
- BANKSEL ANSELA ; ANSELA registeret bestemmer hvilke ben, der
- movwf ANSELA ; skal være analoge. Læs i databladet side 118.
- ; TRISA registeret bestemmer hvilke ben, der
- ; skal være input og hvilke ben, der skal være
- ; output. Læs i databladet side 117.
- ; xx0----- ; RA5 er digitalt output (RTS)
- ; xx-1---- ; RA4 er digitalt input (overtrumfes af ANSELA)
- ; xx--1--- ; RA3 er input (CTS)
- ; xx---1-- ; RA2 er digitalt input (overtrumfes af ANSELA)
- ; xx----1- ; RA1 er digitalt input (RXD)
- ; xx-----0 ; RA0 er digitalt output (TXD)
- movlw b'00011110'
- BANKSEL TRISA
- movwf TRISA
- ;-------------------------------------------------------------------------------
- ; Konfigurering af AD-konverter
- ;-------------------------------------------------------------------------------
- ;AD-konverter ; AD konverteren kan tage sit input fra flere
- ; forskellige ben.
- ; Vi skal skifte mellem AN2 og AN3.
- ; Læs om AD konverteren i databladet, side 130.
- BANKSEL ADCON0 ; Læs om ADCON0 i databladet, side 136.
- ; x00000-- ; Vælg ingen kanal før senere
- ; x-----0- ; Start ikke konverteringen endnu
- ; x------1 ; Enable AD konverteren
- movlw b'00000001' ;
- movwf ADCON0
- BANKSEL ADCON1 ; Læs om ADCON1 i databladet, side 137.
- ; 0---xx-- ; Resultatet justeres til venstre, side 133.
- ; -110xx-- ; Konverterings klok = Fosc/64, side 137.
- ; ----xx00 ; Referencen Vref+ = AVdd (forsyningsspændingen)
- movlw b'01100000'
- movwf ADCON1
- ;-------------------------------------------------------------------------------
- ; Konfigurering af Timer0, som bruges til at generere interrupt
- ;-------------------------------------------------------------------------------
- ;TIMER0 ; TIMER0 sætter et flag hver gang den går fra
- ; 255 til 0 (overflow). Dette flag kan bruges
- ; til at generere et interrupt, se side 163.
- ; TIMER0 tæller på instruktionsklokken,
- ; eventuelt med en indskudt prescaler, se side
- ; 162 i databladet.
- ; Bemærk, at TIMER0 altid er enabled, det vi
- ; kan indstille er hvordan den bruges.
- ; TIMER0 kan tælle på input fra et ben eller på
- ; den interne klok. Dette bestemmes af
- ; bit TMR0CS i OPTION_REG. Se side 164.
- ; TIMER0 indstilles via OPTION registeret, vi
- ; behøver kun gøre noget ved bit 0..3 og 5:
- BANKSEL OPTION_REG
- bcf OPTION_REG,TMR0CS; Tæl på intern klok. Se side 164.
- bcf OPTION_REG,PSA ; Clear PSA-bit for at tage prescaleren i brug
- bsf OPTION_REG,0 ; Timer0's prescaler sættes til 256 og vi
- bsf OPTION_REG,1 ; preloader ikke TIMER0 ved interrupt, men lader
- bsf OPTION_REG,2 ; blot timereren løbe.
- ; Det giver en interruptfrekvens på
- ; Finterrupt = ((32000000/4)/256)/256 = 122Hz
- ; Bemærk at frekvensen kan øges ved at preloade
- ; TIMER0 inde i interrupt-rutinen.
- ; Desuden kan en lavere frekvens opnås ved at
- ; springe en vis andel af interruptene over
- BANKSEL TMR0
- clrf TMR0 ; Nulstiller TIMER0 og dens prescaler, men
- ; stopper ikke TIMER0
- BANKSEL INTCON
- bcf INTCON,TMR0IF ; Clear eventuel flag der er sat tidligere.
- bcf INTCON,TMR0IE ; Slet flag, der tillader TIMER0 interrupt
- bcf INTCON,GIE ; Slet flag, der globalt tillader interrupts
- ;-------------------------------------------------------------------------------
- ; Konfigurering af Timer1, som bruges til at generere timeouts i TIMER
- ;-------------------------------------------------------------------------------
- BANKSEL T1CON ; Læs side 173 i databladet
- ; 00----x- ; Timer1 clock source is FOSC/4 (32MHz/4)
- ; --11--x- ; Timer1 prescale = 1:8
- ; ----0-x- ; Timer1 oscillator bruges ikke
- ; -----1x- ; Synkroniseres ikke
- ; ------x0 ; Timer1 startes ikke endnu
- movlw b'00110100' ;
- movwf T1CON ;
- ; Timer1 genererer overflow i løbet af
- ; 65536/(8000000/8) = 65,5msek
- BANKSEL T1GCON
- bcf T1GCON,TMR1GE ; Brug ikke gate funktioner
- ;-------------------------------------------------------------------------------
- ; Konfigurering af UART, seriel kommunikation - RS232
- ;-------------------------------------------------------------------------------
- ; Læs om RS232 i kapitel 26, side 268
- BANKSEL TXSTA
- bcf TXSTA,TX9 ; TX9 =0, vi bruger 8 bit transmission
- bsf TXSTA,TXEN ; TXEN=1, enable transmission
- bcf TXSTA,SYNC ; SYNC=0, asynkron transmission
- bcf TXSTA,BRGH ; BRGH=0, low Baud rate
- BANKSEL RCSTA
- bsf RCSTA,SREN ;
- bcf RCSTA,RX9 ; RX9 =0, vi bruger 8 bit modtagelse
- bsf RCSTA,SPEN ; SPEN=1, enable seriel port
- bsf RCSTA,CREN ; CREN=1, enable modtager
- BANKSEL BAUDCON
- bsf BAUDCON,BRG16 ; BRG16=1, benyt 16bit Baud rate tæller
- ; movlw 0x00 ; Vi vælger baudrate = 38400
- ; BANKSEL SPBRGH ; Læs om baudrate fra side 260 og frem til 284.
- ; movwf SPBRGH ; Det får vi med BRGH = 0 og SYNC =0 (i TXSTA)
- ; movlw 0x33 ; og BRG16 = 1 (i BAUDCON)
- ; BANKSEL SPBRGL
- ; movwf SPBRGL ; og SPBRGL = 51 (SPBRGH = 0, SPBRGL = 51)
- ; BR = 32000000/(16*(51+1)) = 38462
- movlw 0x00 ; Vi vælger baudrate = 9600
- BANKSEL SPBRGH ; Læs om baudrate fra side 260 og frem til 284.
- movwf SPBRGH ; Det får vi med BRGH = 0 og SYNC =0 (i TXSTA)
- movlw 0xCF ; og BRG16 = 1 (i BAUDCON)
- BANKSEL SPBRGL
- movwf SPBRGL ; og SPBRGL = 207 (SPBRGH = 0, SPBRGL = 207)
- ; BR = 32000000/(16*(207+1)) = 9615
- BANKSEL RCSTA
- movf RCSTA,W ; Læs eventuelle flag
- BANKSEL RCREG
- movf RCREG,W ; Læs eventuelt modtagne byte for at cleare RCIF
- ;-------------------------------------------------------------------------------
- ; Konfigurering af Interrupt
- ;-------------------------------------------------------------------------------
- ;INTERRUPT ; Der er utallige mulige kilder til interrupt.
- ; Som udgangspunkt er ingen af disse kilder
- ; aktiverede, men her skal vi anvende TIMER0
- ; og derfor skal vi aktivere (enable) denne
- ; mulighed. Læs om interrupt side 80.
- ; Signalflaget fra TIMER0 er TMR0IF.
- ; Kontrollen af om dette TIMER0 må generere
- ; interrupt styres af TMR0IE.
- ; Kontrollen af om der i det hele taget kan
- ; reageres på interrupts, uanset kilde, styres
- ; af GIE.
- ; Disse to flag findes i registeret INTCON.
- ; Inden vi enabler interrupt fra TIMER0 er det
- ; en god ide at cleare TIMER0, så der bliver
- ; lidt tid at løbe på inden første interrupt:
- BANKSEL TMR0
- clrf TMR0 ; Nulstiller TIMER0 og dens prescaler, men
- ; stopper ikke TIMER0
- BANKSEL INTCON ; Disable alle interrupts
- bcf INTCON,TMR0IF ; Clear eventuel flag der er sat tidligere.
- bcf INTCON,TMR0IE ; Slet flag, der tillader TIMER0 interrupt
- bcf INTCON,GIE ; Slet flag, der globalt tillader interrupts
- ;*******************************************************************************
- ; Programafviklingen starter med at radiomodulet SmartAlpha initieres.
- ;*******************************************************************************
- START ; SmartAlpha behøver ca 150ms til at varme op.
- ; Derfor venter vi 3*65,5ms før initialiseringen
- call TIMEOUT ; Start TIMER1 som timeout timer 65,5ms maks
- BANKSEL PIR1
- btfss PIR1,TMR1IF ; Bit sat hvis timeout
- goto $-1 ; Vent på overflow
- call TIMEOUT ; Start TIMER1 som timeout timer 65,5ms maks
- BANKSEL PIR1
- btfss PIR1,TMR1IF ; Bit sat hvis timeout
- goto $-1 ; Vent på overflow
- call TIMEOUT ; Start TIMER1 som timeout timer 65,5ms maks
- BANKSEL PIR1
- btfss PIR1,TMR1IF ; Bit sat hvis timeout
- goto $-1 ; Vent på overflow
- call SMA_INI ; Initialiserer SmartAlpha
- movf WREG,W ; W=0 betyder OK, W<>0 betyder fejl i initiering
- btfss STATUS,Z ; W=0 => Z=1 og det betyder OK at gå videre
- goto START ; Forfra hvis ikke OK
- BANKSEL 0
- movlw 0x05 ;
- movwf IT ; Startværdi for IT
- BANKSEL INTCON ; Enable interrupt fra TIMER0
- bcf INTCON,TMR0IF ; Clear eventuel flag der er sat tidligere.
- bsf INTCON,TMR0IE ; Sæt flag, der tillader TIMER0 interrupt
- bsf INTCON,GIE ; Sæt flag, der globalt tillader interrupts
- ;*******************************************************************************
- VENT ; Her står programmet blot og kører i ring uden
- ; at foretage sig andet end at vente på
- ; interrupt.
- ; Imens tælles TIMER0 op og på et tidspunkt
- ; sker der et overflow i TIMER0 hvilket giver
- ; et interrupt, hvorved interrupt rutinen bliver
- ; kaldt.
- ; Når interrupt rutinen er færdig returnerer
- ; programmet til at stå og vente her på næste
- ; gang TIMER0 har overflow.
- goto VENT ;
- ;*******************************************************************************
- SAMPLE2 ; Denne rutine udfører AD konvertering af AN2
- ; Når den er færdig overføres ADRESH til AD2OUT
- ; ADRESL bruges ikke
- BANKSEL ADCON0 ; Læs om ADCON0 i databladet, side 136.
- ; x00010-- ; Vælg kanal AN2, ben 5
- ; x-----0- ; Start ikke konverteringen endnu
- ; x------1 ; Enable AD konverteren
- movlw b'00001001' ;
- movwf ADCON0
- movlw d'20' ; Forsinkelse så AD-multiplexeren kan følge med
- decfsz WREG,F
- goto $-1
- bsf ADCON0,GO ; Start AD konverteringen
- btfsc ADCON0,GO ; Test om konverteringen er færdig
- goto $-1 ; Ellers vent og test igen
- BANKSEL ADRESH
- movf ADRESH,W ;
- BANKSEL AD2OUT
- movwf AD2OUT ; AD2OUT = resultat af konverteringen
- return
- ;*******************************************************************************
- SAMPLE3 ; Denne rutine udfører AD konvertering af AN3
- ; Når den er færdig overføres ADRESH til AD3OUT
- ; ADRESL bruges ikke
- BANKSEL ADCON0 ; Læs om ADCON0 i databladet, side 136.
- ; x00011-- ; Vælg kanal AN3, ben 3
- ; x-----0- ; Start ikke konverteringen endnu
- ; x------1 ; Enable AD konverteren
- movlw b'00001101' ;
- movwf ADCON0
- movlw d'20' ; Forsinkelse så AD-multiplexeren kan følge med
- decfsz WREG,F
- goto $-1
- bsf ADCON0,GO ; Start AD konverteringen
- btfsc ADCON0,GO ; Test om konverteringen er færdig
- goto $-1 ; Ellers vent og test igen
- BANKSEL ADRESH
- movf ADRESH,W ;
- BANKSEL AD3OUT
- movwf AD3OUT ; AD3OUT = resultat af konverteringen
- return
- ;*******************************************************************************
- SMA_TX ; SMA_TX skal sende 2 bytes: AD2OUT og AD3OUT
- BANKSEL LATA
- bcf LATA,5 ; Sæt RTS lav
- BANKSEL AD2OUT
- movf AD2OUT,W ; WREG = AD2OUT
- call SEND ; Send første byte
- BANKSEL AD3OUT
- movf AD3OUT,W ; WREG = AD3OUT
- call SEND ; Send anden byte
- BANKSEL TXSTA
- btfss TXSTA,TRMT
- goto $-1 ; Vent til alt er sendt
- BANKSEL LATA
- bsf LATA,5 ; Sæt RTS høj
- return ;
- ;*******************************************************************************
- ; Subrutinen "SEND" checker om UARTen er klar til næste byte og
- ; skriver derefter indholdet af W til senderegisteret.
- ; UARTen vil derefter automatisk sende denne byte selvom SEND-routinen
- ; returnerer med det samme.
- ; Bemærk! Programmet bliver hængende i denne routine indtil forrige
- ; byte er igang med at blive sendt eller allerede er sendt. Dette er
- ; normalt intet problem.
- ; Hvis senderen ikke har gang i noget i forvejen kan man skrive to bytes til
- ; sendebufferen lige efter hinanden. Læs herom i kapitel 26, side 268.
- ;*******************************************************************************
- SEND
- BANKSEL PIR1
- btfss PIR1,TXIF ; Klar til at sende ny byte? (bit = 1)
- goto SEND ; - ellers vent
- BANKSEL TXREG
- movwf TXREG ; Skriv indholdet af W til senderegister
- return ;
- ;*******************************************************************************
- ; Når man skriver et program, der kommunikerer med en anden enhed, som man ikke
- ; har fuld kontrol over (måske er den ikke monteret eller fungerer ikke) er det
- ; nyttigt at have en metode til at undgå at komme til at vente i det uendelige
- ; på et respons, som måske aldrig kommer.
- ; En egnet måde er at benytte en tæller til at generere et timeout signal, hvis
- ; det varer for længe med et eller andet.
- ; Lidt som at bruge et stopur, så man ikke sover for længe.
- ;*******************************************************************************
- TIMEOUT ; Vi benytter Timer1 som timeout timer, så
- ; programmet ikke risikerer at blive hængende
- ; i al evighed. Se side 173 i databladet.
- ; Timer1 er sat op til at generere overflow i
- ; løbet af 65,5msek.
- ; Timer1 overflow benyttes som timeout.
- BANKSEL PIR1
- bcf PIR1,TMR1IF ; Sørg for at Timer1 interrupt flag er clearet
- BANKSEL T1CON
- bcf T1CON,TMR1ON ; Stop Timer1
- BANKSEL TMR1H
- clrf TMR1H ; Clear Timer1, det vil sige start forfra
- BANKSEL TMR1L
- clrf TMR1L ; Clear Timer1, det vil sige start forfra
- BANKSEL T1CON
- bsf T1CON,TMR1ON ; Start Timer1
- return
- ;*******************************************************************************
- ; Den følgende rutine sammenligner de konfigurations data, der ligger i lageret
- ; fra adresse 0x0070 og frem med den ønskede konfiguration, som er defineret i
- ; begyndelsen af programmet som konstanter.
- ; Hvis alt stemmer returnerer rutinen med WREG=0
- ; Hvis der konstateres en forskel returnerer rutinen med WREG<>0
- ;*******************************************************************************
- CHECKCONFIG
- clrf FSR0H ; Sæt FSR0 til at pege på adresse 0x0070
- movlw 0x70 ;
- movwf FSR0L ;
- moviw INDF0++ ;
- sublw SMA_TAD ; Sammenlig med første sende-adresse-byte
- btfss STATUS,Z ; Hvis match så er Z-flag sat
- goto MISMATCH ; Gå til fejl hvis mismatch
- moviw INDF0++ ;
- sublw SMA_TAD ; Sammenlig med anden sende-adresse-byte
- btfss STATUS,Z ; Hvis match så er Z-flag sat
- goto MISMATCH ; Gå til fejl hvis mismatch
- moviw INDF0++ ;
- sublw SMA_TAD ; Sammenlig med tredje sende-adresse-byte
- btfss STATUS,Z ; Hvis match så er Z-flag sat
- goto MISMATCH ; Gå til fejl hvis mismatch
- moviw INDF0++ ;
- sublw SMA_TADI ; Sammenlig med fjerde sende-adresse-byte
- btfss STATUS,Z ; Hvis match så er Z-flag sat
- goto MISMATCH ; Gå til fejl hvis mismatch
- moviw INDF0++ ;
- sublw SMA_RAD ; Sammenlig med første modtage-adresse-byte
- btfss STATUS,Z ; Hvis match så er Z-flag sat
- goto MISMATCH ; Gå til fejl hvis mismatch
- moviw INDF0++ ;
- sublw SMA_RAD ; Sammenlig med anden modtage-adresse-byte
- btfss STATUS,Z ; Hvis match så er Z-flag sat
- goto MISMATCH ; Gå til fejl hvis mismatch
- moviw INDF0++ ;
- sublw SMA_RAD ; Sammenlig med tredje modtage-adresse-byte
- btfss STATUS,Z ; Hvis match så er Z-flag sat
- goto MISMATCH ; Gå til fejl hvis mismatch
- moviw INDF0++ ;
- sublw SMA_RADI ; Sammenlig med fjerde modtage-adresse-byte
- btfss STATUS,Z ; Hvis match så er Z-flag sat
- goto MISMATCH ; Gå til fejl hvis mismatch
- moviw INDF0++ ;
- sublw SMA_FRQH ; Sammenlig med første radiofrekvens-byte
- btfss STATUS,Z ; Hvis match så er Z-flag sat
- goto MISMATCH ; Gå til fejl hvis mismatch
- moviw INDF0++ ;
- sublw SMA_FRQL ; Sammenlig med anden radiofrekvens-byte
- btfss STATUS,Z ; Hvis match så er Z-flag sat
- goto MISMATCH ; Gå til fejl hvis mismatch
- moviw INDF0++ ;
- sublw SMA_PWR ; Sammenlig med sendestyrke-byte
- btfss STATUS,Z ; Hvis match så er Z-flag sat
- goto MISMATCH ; Gå til fejl hvis mismatch
- moviw INDF0++ ;
- sublw SMA_BAUD ; Sammenlig med baudrate-byte
- btfss STATUS,Z ; Hvis match så er Z-flag sat
- goto MISMATCH ; Gå til fejl hvis mismatch
- retlw 0x00 ; Hvis alt passer returneres med WREG=0
- MISMATCH
- retlw 0x01 ; Hvis mismatch returneres med WREG<>0
- ;*******************************************************************************
- ; Subrutinen SMA_INI initiliserer radiomodulet SmartAlpha
- ; SmartAlpha kan være i "Normal Mode" eller i "Configuration Mode"
- ; "Normal Mode" benyttes når radiomodulet skal bruges til at kommunikere
- ; "Configuration Mode" benyttes til at indstille måden radiomodulet fungerer
- ; Læs om indstillingsmulighederne i databladet for SmartAlpha, afsnit 3.
- ; Normalt vil vi kun have behov for at justere adresserne.
- ; SmartAlpha kan sættes i "Configuration Mode" ved at sende '+++' til modulet.
- ; SmartAlpha kan sættes i "Normal Mode" ved at sende '---' til modulet.
- ;
- ; Fremgangsmåden i initialiserings rutinen er følgende:
- ; 1: Skift til "Configuration Mode"
- ; 2: Aflæs hvordan SmartAlpha aktuelt er konfigureret
- ; 3: Sammenlign med den ønskede konfiguration
- ; 4: Gå til punkt 8 hvis der ikke er behov for ændring
- ; 5: Skriv den nye ønskede konfiguration til SmartAlpha
- ; 6: Vent på at SmartAlpha installerer den nye konfiguration i hukommelsen
- ; 7: Gå til punkt 2 for at se om ændringen er gennemført
- ; 8: Skift til "Normal Mode"
- ; 9: Vent på at SmartAlpha gennemfører skiftet til "Normal Mode"
- ;
- ; Undervejs benyttes de to handshake signaler RTS og CTS til at kontrollere
- ; hvornår der kommunikeres.
- ; RTS er måden vi beder SmartAlpha om at få opmærksomhed (skrive og læse)
- ; CTS er måden SmartAlpha signalerer at modulet er optaget af at gøre noget
- ;*******************************************************************************
- SMA_INI ;-----------------------------------------------------------------------
- ; Først fortæller vi SmartAlpha, at vi vil kommunikere
- ; Det gøres ved at sætte RTS signalet lavt
- ; Mens RTS er lav kan radiomodulet ikke modtage radiosignaler
- ;-----------------------------------------------------------------------
- BANKSEL LATA
- bcf LATA,5 ; Sæt RTS lav
- ; Trin 1
- ;-----------------------------------------------------------------------
- ; Send 3 gange '+' for at sætte SmartAlpha i configuration mode
- ;-----------------------------------------------------------------------
- BANKSEL LATA
- bcf LATA,5 ; Sæt RTS lav
- movlw SMA_COM ; Send 3 gange '+'
- call SEND ; for at sætte SmartAlpha i kommando mode
- movlw SMA_COM ;
- call SEND ;
- movlw SMA_COM ;
- call SEND ;
- BANKSEL TXSTA
- btfss TXSTA,TRMT ; Vent til alle bytes er sendt
- goto $-1 ;
- ; BANKSEL PORTA ;!!!!!!!!!!
- ; bcf PORTA,4 ;!!!!!!!!!!
- ; Trin 2
- ;-----------------------------------------------------------------------
- ; SmartAlpha svarer med at sende sin nuværende konfiguration
- ; Vi gemmer konfigurationen på adresserne fra og med 0x0070
- ;-----------------------------------------------------------------------
- clrf FSR0H ; Sæt FSR0 til at pege på adresse 0x0070
- movlw 0x70 ;
- movwf FSR0L ;
- BANKSEL 0 ; Vi venter at modtage 12 bytes fra SmartAlpha
- movlw 0x0C ;
- movwf BT ; Sæt bytetæller til 12
- BANKSEL RCSTA
- btfsc RCSTA,OERR ; Kontrollér om der er overrun fejl
- goto RESTART ; Restart UART hvis fejl
- btfss RCSTA,FERR ; Kontrollér om der er framing fejl
- goto U_OK ; Fortsæt hvis ingen fejl
- RESTART bcf RCSTA,SPEN ; SPEN=0, disable seriel port
- bcf RCSTA,CREN ; CREN=0, disable modtager
- bsf RCSTA,SREN ;
- bcf RCSTA,RX9 ; RX9 =0, vi bruger 8 bit modtagelse
- bsf RCSTA,SPEN ; SPEN=1, enable seriel port
- bsf RCSTA,CREN ; CREN=1, enable modtager
- U_OK call TIMEOUT ; Start TIMER1 som timeout timer 65,5ms maks
- VIN
- BANKSEL PIR1
- movfw PIR1
- btfsc WREG,TMR1IF ; Bit sat hvis timeout
- goto SMA_TO ; Afslut hvis timeout
- btfss WREG,RCIF ; Bit er sat hvis der er input
- goto VIN ; Ellers prøv igen
- BANKSEL RCREG
- movf RCREG,W ; Hent ciffer fra RCREG
- movwi INDF0++ ; Gem i lager peget på af FSR0H:FSR0L, tæl op
- BANKSEL 0
- decfsz BT,F ; Tæl bytetæller ned
- goto VIN ; en gang til hvis BT>0
- ; Trin 3
- ;-----------------------------------------------------------------------
- ; Herefter kontrolleres om den modtagne konfiguration passer med
- ; den ønskede konfiguration
- ;-----------------------------------------------------------------------
- call CHECKCONFIG
- movf WREG,W ; W=0 betyder OK, W<>0 betyder opdater værdierne
- btfsc STATUS,Z ; W=0 => Z=1 og det betyder OK at gå videre
- ; Trin 4
- goto SMA_OK ; Spring ny konfiguration over hvis OK
- ; Trin 5
- ;-----------------------------------------------------------------------
- ; Hvis den modtagen konfiguration ikke passer sendes den ønskede
- ; konfiguration til SmartAlpha
- ;-----------------------------------------------------------------------
- SETCONF
- movlw SMA_TAD ; Send 4 gange 7E
- call SEND ; for at definere sendeadressen
- movlw SMA_TAD ;
- call SEND ;
- movlw SMA_TAD ;
- call SEND ;
- movlw SMA_TADI ; Her kan stå en anden individuel værdi
- call SEND ;
- movlw SMA_RAD ; Send 4 gange 7E
- call SEND ; for at definere modtageadressen
- movlw SMA_RAD ;
- call SEND ;
- movlw SMA_RAD ;
- call SEND ;
- movlw SMA_RADI ; Her kan stå en anden individuel værdi
- call SEND ;
- movlw SMA_FRQH ; Indstiller SmartAlphas's radiofrekvens
- call SEND ;
- movlw SMA_FRQL ;
- call SEND ;
- movlw SMA_PWR ; Indstiller SmartAlpha's sendestyrke
- call SEND ;
- movlw SMA_BAUD ; Indstiller SmartAlpha's baudrate
- call SEND ;
- ; Trin 6
- ;-----------------------------------------------------------------------
- ; SmartAlpha bruger noget tid på at gemme den nye konfiguration.
- ; Først går CTS høj og senere, når SmartAlpha er færdig, går CTS lav
- ;-----------------------------------------------------------------------
- call TIMEOUT
- CTSH1
- BANKSEL PIR1
- movfw PIR1
- btfsc WREG,TMR1IF ; Bit sat hvis timeout
- goto SMA_TO ; Afslut hvis timeout
- BANKSEL PORTA ; Vent på at CTS går høj
- btfss PORTA,3
- goto CTSH1
- CTSL1
- BANKSEL PIR1
- movfw PIR1
- btfsc WREG,TMR1IF ; Bit sat hvis timeout
- goto SMA_TO ; Afslut hvis timeout
- BANKSEL PORTA ; Vent på at CTS går lav
- btfsc PORTA,3
- goto CTSL1
- ; Trin 7
- ;-----------------------------------------------------------------------
- ; Når programmet kommer her er det fordi konfigurationen er opdateret.
- ; Derfor skal vi lige checke, at den nu er i orden.
- ;-----------------------------------------------------------------------
- goto SMA_INI ; Forfra for at checke
- ; Trin 8
- ;-----------------------------------------------------------------------
- ; SmartAlpha sættes tilbage til normal mode ved at sende 3 gange '-'
- ;-----------------------------------------------------------------------
- SMA_OK
- movlw SMA_NORM ; Send 3 gange '-'
- call SEND ; for at sætte SmartAlpha i kommando mode
- movlw SMA_NORM ;
- call SEND ;
- movlw SMA_NORM ;
- call SEND ;
- BANKSEL TXSTA
- btfss TXSTA,TRMT ; Vent til alle bytes er sendt
- goto $-1 ;
- ; Trin 9
- ;-----------------------------------------------------------------------
- ; SmartAlpha bruger noget tid på at skifte til "Normal Mode".
- ; Først går CTS høj og senere, når SmartAlpha er færdig, går CTS lav
- ;-----------------------------------------------------------------------
- call TIMEOUT
- CTSH2
- BANKSEL PIR1
- movfw PIR1
- btfsc WREG,TMR1IF ; Bit sat hvis timeout
- goto SMA_TO ; Afslut hvis timeout
- BANKSEL PORTA ; Vent på at CTS går høj
- btfss PORTA,3
- goto CTSH2
- CTSL2
- BANKSEL PIR1
- movfw PIR1
- btfsc WREG,TMR1IF ; Bit sat hvis timeout
- goto SMA_TO ; Afslut hvis timeout
- BANKSEL PORTA ; Vent på at CTS går lav
- btfsc PORTA,3
- goto CTSL2
- ;-----------------------------------------------------------------------
- ; Til sidst sættes SmartAlpha fri igen ved at sætte RTS høj
- ;-----------------------------------------------------------------------
- clrf WREG ; Rutinen returnerer med WREG=0 hvis alt OK
- BANKSEL PORTA
- bsf PORTA,5 ; Sæt RTS høj
- return
- SMA_TO movlw 0x01 ; Rutinen returnerer med WREG>0 hvis fejl
- BANKSEL PORTA
- bsf PORTA,5 ; Sæt RTS høj
- return
- ;*******************************************************************************
- END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement