;------------------------------------------------------------------------------- ; FILE: EUSART Asynchronous Serial Transmit ; AUTH: Ed's Projects ; DATE: 23/07/2016 ; DESC: Recieves data serially specifying time period and number of measurements ; analogue is read and sent back to the master chip using serial ;------------------------------------------------------------------------------- LIST P=16F887, R=DEC ; All numbers Decimal format unless otherwise stated. include ; Define configurations, registers, etc. __CONFIG _CONFIG1, _DEBUG_OFF & _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOREN_ON & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDTE_OFF & _HS_OSC ;------------------------------------------------------------------------------- ;----------------------------- Port Definitions ------------------------------ ;------------------------------------------------------------------------------- ; PORTA - Input - RA0 - Pin 2 - AN0 ; PORTA - Input - RA1 - Pin 3 - AN1 ; PORTA - Input - RA2 - Pin 4 - AN2 ; PORTA - Input - RA4 - Pin 5 - AN3 ; PORTA - Input - RA5 - Pin 7 - AN4 ; PORTE - Input - RE0 - Pin 8 - AN5 ; PORTE - Input - RE1 - Pin 9 - AN6 ; PORTE - Input - RE2 - Pin 10 - AN7 ; PORTC - Output - RC6 - Pin 25 - TX ; PORTC - Input - RC7 - Pin 26 - RX ;------------------------------------------------------------------------------- ;-------------------------------- Variables ---------------------------------- ;------------------------------------------------------------------------------- cblock h'20' micro200f micro50f ms2delayf ms2delayg dly0 ; Number of 2ms delays clrtemp ; For clearing FSR RAM tempdig ; The temp variable to aid splitting 3 nibbles orgdig ; The variable to be split into 3 nibbles digit3 ; High nibble digit2 ; Middle nibble digit1 ; Low nibble temp1 ; Indicates parameters received temp2 ; Part of receive program numeas ; Number of measurements to be made inctemp ; Time period between measurements Adc_low ; ADC low byte Adc_high ; ADC high byte adcinc ; Increment ADC / FSR inttemp ; Interrupt temp - 100ms increments counter endc ;------------------------------------------------------------------------------- ;--------------------- Indirect Addressing Variables ------------------------- ;------------------------------------------------------------------------------- ; A0 - A7 ; analogue temporary ;------------------------------------------------------------------------------- ;------------------------------- Program Code -------------------------------- ;------------------------------------------------------------------------------- ORG 0 goto Init ;------------------------------------------------------------------------------- ;---------------------------- Interrupt Address ------------------------------ ;------------------------------------------------------------------------------- ORG 04 goto Interrupt ;------------------------------------------------------------------------------- ;-------------------------- Initialisation of Ports -------------------------- ;------------------------------------------------------------------------------- Init bcf STATUS,RP0 ; Set RP0 to 0 bcf STATUS,RP1 ; Set RP1 to 0 ; Bank 0 Selected movlw b'00110000' movwf T1CON ; Set Timer1 to prescale 8, internal clock clrf ADCON0 ; Turn off ADC bsf STATUS,RP0 ; Set RP0 to 1 ; Bank 1 Selected bsf INTCON, PEIE ; Turn on peripheral Interrupts bsf PIE1, TMR1IE ; Turn on Timer1 Interrupt bsf INTCON, GIE ; Turn on global interrupts movlw b'00000000' movwf ADCON1 ; Set Left justified data output - ADC clrf VRCON ; Set Vref to off clrf TRISC ; Set all PortC as Output clrf TRISD ; Set all PortD as Output movlw b'00101111' movwf TRISA movlw b'00000111' movwf TRISE ; Set RE0, 1 and 2 to inputs - for ADC movlw b'11110000' ; Load 11110000 to working register movwf TRISB ; Set bits 0-3 as outputs, rest inputs bsf STATUS,RP1 ; Set RP0 to 1 ; Bank 3 Selected movlw d'255' movwf ANSEL ; Set AN0 to AN7 as analogue clrf ANSELH ; Set all high analogue inputs to digital bcf STATUS,RP0 ; Set RP0 to 0 ; Bank 2 Selected clrf CM1CON0 ; Turn off comparator 1 clrf CM2CON0 ; Turn off comparator 2 bcf STATUS,RP0 ; Set RP0 to 0 bcf STATUS,RP1 ; Set RP1 to 0 ; Bank 0 Selected clrf PORTA clrf PORTB clrf PORTC clrf PORTD clrf PORTE clrf micro200f clrf ms2delayf clrf ms2delayg clrf dly0 ; Number of 2ms delay loops clrf temp1 clrf temp2 movlw h'A0' ; This section will clear the first 64 movwf FSR ; blocks of RAM in bank 1 clrram clrf INDF incf FSR, f incf clrtemp, f btfss clrtemp, 6 goto clrram ; Clear variables and output ports ;------------------------------------------------------------------------------- ;--------- Asynchronous Serial Transmit and Receive Initialisation ------------ ;------------------------------------------------------------------------------- Inits bsf STATUS, RP0 ; Set RP0 to 1 bsf STATUS, RP1 ; Set RP1 to 1 ; Bank 3 Selected bsf BAUDCTL, BRG16 ; Sets 16-bit baud generator bcf STATUS, RP1 ; Set RP1 to 0 ; Bank 1 Selected bsf TRISC, 6 ; Both serial input and output must bsf TRISC, 7 ; be set as inputs. bsf TXSTA, BRGH ; Set high baud rate movlw d'8' movwf SPBRG movlw d'2' ; Set baud rate to 9600 movwf SPBRGH bcf TXSTA, SYNC ; Set to asynchronous mode bcf STATUS, RP0 ; Set RP0 to 0 ; Bank 0 Selected bsf RCSTA, SPEN ; Enable Serial Port bsf STATUS, RP0 ; Set RP0 to 1 ; Bank 1 Selected bsf TXSTA, TXEN ; Enable Transmission bcf STATUS, RP0 ; Set RP0 to 0 ; Bank 0 Selected bsf RCSTA, CREN ; Turns on receive movf RCREG, w movf RCREG, w movf RCREG, w ; Clears Interrupt flag goto Start ;------------------------------------------------------------------------------- ;---------------------------- Loops 2ms Delay -------------------------------- ;------------------------------------------------------------------------------- delay movwf dly0 delayloop call ms2delay decfsz dly0, f goto delayloop return ;------------------------------------------------------------------------------- ;------------------------------- 2ms Delay ----------------------------------- ;------------------------------------------------------------------------------- ms2delay movlw d'8' movwf ms2delayg ms2delayc movlw d'250' movwf ms2delayf ms2delaya nop ;0.2us nop ;0.2us decfsz ms2delayf,f ;0.2us goto ms2delaya ;0.4us ;total 250us ms2delayb decfsz ms2delayg,f ;0.2us goto ms2delayc ;0.4us return ;return from call ;------------------------------------------------------------------------------- ;------------------------------- 200us Delay --------------------------------- ;------------------------------------------------------------------------------- micro200 movlw d'200' movwf micro200f micro200a nop ;0.2us nop ;0.2us decfsz micro200f,f ;0.2us goto micro200a ;0.4us return ;return from call ;------------------------------------------------------------------------------- ;------------------------------- 50us Delay --------------------------------- ;------------------------------------------------------------------------------- micro50 movlw d'50' movwf micro50f micro50a nop ;0.2us nop ;0.2us decfsz micro50f,f ;0.2us goto micro50a ;0.4us return ;return from call ;------------------------------------------------------------------------------- ;-------------------------------- ADC Read ----------------------------------- ;------------------------------------------------------------------------------- ADCread movlw h'A0' movwf adcinc movlw b'10000001' ; Set conversion speed to highest movwf ADCON0 ; 1/32 and select AN0 call micro200 ; Allows channel time to adjust call ADCreada call ADCconv movlw b'10000101' ; Set conversion speed to highest movwf ADCON0 ; 1/32 and select AN1 call micro200 ; Allows channel time to adjust call ADCreada call ADCconv movlw b'10001001' ; Set conversion speed to highest movwf ADCON0 ; 1/32 and select AN2 call micro200 ; Allows channel time to adjust call ADCreada call ADCconv movlw b'10001101' ; Set conversion speed to highest movwf ADCON0 ; 1/32 and select AN3 call micro200 ; Allows channel time to adjust call ADCreada call ADCconv movlw b'10010001' ; Set conversion speed to highest movwf ADCON0 ; 1/32 and select AN4 call micro200 ; Allows channel time to adjust call ADCreada call ADCconv movlw b'10010101' ; Set conversion speed to highest movwf ADCON0 ; 1/32 and select AN5 call micro200 ; Allows channel time to adjust call ADCreada call ADCconv movlw b'10011001' ; Set conversion speed to highest movwf ADCON0 ; 1/32 and select AN6 call micro200 ; Allows channel time to adjust call ADCreada call ADCconv movlw b'10011101' ; Set conversion speed to highest movwf ADCON0 ; 1/32 and select AN7 call micro200 ; Allows channel time to adjust call ADCreada call ADCconv return ADCconv ; Move ADC values to RAM movf adcinc, w movwf FSR movf Adc_high, w movwf INDF incf adcinc, f return ADCreada bsf ADCON0, GO ; Convert analogue to digital btfsc ADCON0, GO ; Check to see if complete goto $-1 ; If not loop to above instruction movf ADRESH, w movwf Adc_high ; Move to variable bsf STATUS, RP0 ; Set RP0 to 1 ; Bank 1 Selected movf ADRESL, w bcf STATUS, RP0 ; Set RP0 to 0 ; Bank 0 Selected movwf Adc_low ; Move to variable return ;------------------------------------------------------------------------------- ;---------------------------- Interrupt Program ------------------------------ ;------------------------------------------------------------------------------- Interrupt bcf PIR1, TMR1IF ; Clear Interrupt bit bcf T1CON, 0 ; Stop timer1 movlw b'00001011' movwf TMR1H movlw b'11110100' ; Load timer1 with 3060, total of 62500 movwf TMR1L ; increments. bsf T1CON, 0 ; Start timer1 incf inttemp, f movf inttemp, w xorwf inctemp, w btfss STATUS, Z retfie bsf inttemp, 7 ; When looped 10 times retfie ;------------------------------------------------------------------------------- ;------------------------------- Main Program -------------------------------- ;------------------------------------------------------------------------------- Start btfsc PIR1, RCIF call receive btfss temp1, 0 ; Check if parameters have been set goto Start goto Main receive btfsc temp2, 0 goto receive2 movf RCREG, w movwf numeas decf numeas, f bsf temp2, 0 return receive2 movf RCREG, w movwf inctemp bcf temp2, 0 bsf temp1, 0 return Main bcf RCSTA, CREN ; Turns off receive clrf inttemp call timerstart call ADCread call sendserial maina btfss inttemp, 7 ; When looped "X" times goto maina clrf inttemp call ADCread call sendserial decfsz numeas, f goto maina bcf T1CON, 0 ; Stop timer1 clrf temp1 clrf temp2 movlw d'250' call delay movf RCREG, w movf RCREG, w movf RCREG, w ; Clears Interrupt flag bsf RCSTA, CREN ; Turns on receive goto Start ;------------------------------------------------------------------------------- ;----------------------------- Serial Transmit ------------------------------- ;------------------------------------------------------------------------------- sendserial movlw h'A0' movwf FSR label1 bsf STATUS, RP0 ; Bank 1 btfss TXSTA, TRMT goto $-1 bcf STATUS, RP0 ; Bank 0 movf INDF, w movwf TXREG incf FSR, f movf FSR, w xorlw h'A8' btfss STATUS, Z goto label1 return ;------------------------------------------------------------------------------- ;----------------------------------- Timer ----------------------------------- ;------------------------------------------------------------------------------- timerstart movlw b'00001011' ; This first delay is to allow enough time movwf TMR1H ; to read ADC. movlw b'11110100' ; Load timer1 with 3060, total of 62500 movwf TMR1L ; increments. bsf T1CON, 0 ; Start timer1 return end