;********************************************************************** ; * ; Filename: sunboi1.asm * ; Date: 02-10-2007 * ; File Version: Display unit for sunboiler * ; PCB: Displayunit LZB (Luigjes ZonneBoiler) * ; processor: PIC16F913 * ; SET VELLEMAN PROGRAMMER TO: PIC16F876 * ; Author: * ; * ;********************************************************************** ; NOTES ; ; - Incoming serial data from sunboiler will be displayed on LCD ; - PIC16F913, clock frequency: 4 MHz ,= 1MHz internal clock oscillator ; - EA-DOGM162 Display-routines from German internet forum..... ; - Bestand gehaald van forum: http://www.mikrocontroller.net/topic/19480 ; Wolfram Hildebrandt ; ; - ; - Display shows COL: ... PMP: OFF ; - BOI: ... HRS: .... ; -Collectortemparature Pump On or off ; -Boilertemperature Number of hours run ; ; Received strings from ATAG-Luigjes HR zonnegascombi: ; ; Luigjes Delta-T ; Col:... Boi: .. ; PMP:... ; ...-YCOL...-YBOI ; PMP: ..... UREN ; ; ; ; - WDT enabled ; ; ; PIC ports used: ; ; RC0-3 outputs: drives LCD D4-D7 (4 bit parallel data transfer, LCD model= EA DOGM162) ; RC6 = UART-Tx for transmitting serial data to sunboiler (optional) TRANSMITTING NOT POSSIBLE!! ; No serial data is transmitted; RC6=highimpedance, RC5 connected to RC6 to make line low/high ; RC7 = UART-Rx for receiving serial data from sunboiler ; RA0 = RS Display ; RA1 = R/W Display ; RA2 = E Display ; RB4 = LED backlight 1 via 220R resistor ; set = on ; RB5 = LED backlight 2 via 220R resistor ; set = on ; inputs: ; RB2 = key - pushbutton (optional) ; RB7 = only used for ICSP PGD ; RB6 = only used for ICSP PGC ;********************************************************************** list p=16f913, R=DEC ; using decimal system #include "p16f913.inc" ;#include ;; #include ;#include ; #include "picmac1.inc" __CONFIG _DEBUG_OFF & _FCMEN_OFF & _IESO_OFF & _BOD_ON & _CPD_OFF & _CP_OFF & _PWRTE_ON & _WDT_ON & _MCLRE_OFF & _INTRC_OSC_NOCLKOUT cblock 0x20 ; start of general purpose registers loops loops2 command counter temp dataL ; used in UART communication routine BOI_1 ; sign that comes before boiler temp BOI_MSD ; first digit of boiler temperature BOI_LSD ; second digit of boiler temperature COL_1 ; sign that comes before collector temp COL_MSD ; first digit of collector temperature COL_LSD ; second digit of collector temperature PMP_1 ; first digit of pump PMP_2 ; second digit of pump PMP_3 ; third digit of pump HRS_1 ; first digit of hours HRS_2 ; second digit of hours HRS_3 ; third digit of hours HRS_4 ; fourth digit of hours temp_data ; temporary storage of received character COUNT1 ; Used by delay routines ; and "prescaler flush" COUNT2 ; Timing (100ms) FLAG ; STATUS_TEMP ; for temporary storage of STATUS contence during interrupt W_TEMP ; for temporary storage of w-contence during interrupt VALUE ; to get value from table count1 ; used in delay routine counta ; used in delay routine countb count dcnt0 ; delay counter 0 dcnt1 ; delay counter 1 dcnt2 ; delay counter 2 counter2 ; to keep track of when character 16 has been received EOS_FLAG ; End Of String FLAG CHR1 CHR2 CHR3 CHR4 CHR5 CHR6 CHR7 CHR8 CHR9 CHR10 CHR11 CHR12 CHR13 CHR14 CHR15 CHR16 CHR17 CHR18 CHR19 CHR20 CHR21 CHR22 CHR23 CHR24 CHR25 CHR26 CHR27 CHR28 CHR29 CHR30 CHR31 CHR32 CHR33 CHR34 CHR35 CHR36 endc #define RS PORTA,0 ; line RS to LCD #define E PORTA,2 ; line E to LCD #define RW PORTA,1 ; line R/W to LCD #define LED_BL1 PORTB,5 ; backlight led1 #define LED_BL2 PORTB,4 ; backlight led2 D4 EQU 0 ; line D4 to LCD D5 EQU 1 ; line D5 to LCD D6 EQU 2 ; line D6 to LCD D7 EQU 3 ; line D7 to LCD pushbutton EQU 2 ; vectors ORG 0x000 goto INIT nop nop nop goto INTERRUPT ORG 0x005 ; *************************************************************************** INIT ; initialisation starts here movlw OSCCON movwf FSR movlw b'11100111' ; internal oscillator, 4 MHz movwf INDF movlw T1CON ; movwf FSR ; movlw b'00110000' ; timer 1 OFF, prescaler 1:8 movwf INDF ; movlw PORTB movwf FSR movlw b'00000000' ; movwf INDF movlw PORTC movwf FSR movlw b'01000000' ; RC6 = 1 (Tx) movwf INDF movlw T2CON ; Timer 2 off movwf FSR ; clrw movwf INDF ; movlw OPTION_REG ; bit7 zero ; WPUB on movwf FSR ; movlw b'01111111' movwf INDF ; movlw WPUB ; portB2 WPU on movwf FSR ; movlw b'00000100' movwf INDF ; movlw TRISA ; port A movwf FSR ; all movlw b'00000000' ; out- movwf INDF ; puts movlw TRISB movwf FSR movlw b'00000100' ; pb2 input movwf INDF movlw TRISC movwf FSR movlw b'11000000' ; pc0-5 output, PC6 input!! movwf INDF ; pc7 = input Rx BCF STATUS,RP0 ;Bank 0 BCF STATUS,RP1 ; CLRF PORTA ;Init PORTA BSF STATUS,RP0 ;Bank 1 BCF STATUS,RP1 ; MOVLW 07h ;Set RA<2:0> to MOVWF CMCON0 ;digital I/O CLRF ANSEL ;Make all PORTA I/O MOVLW b'11110000' ;Set RA<7:4> as inputs MOVWF TRISA ;and set RA<3:0> ; as outputs BANKSEL LCDCON clrw movwf LCDCON BANKSEL WDTCON movlw b'00010001' ; enable WDT; 1:8192 ( 40 sec) movwf WDTCON BCF STATUS,RP0 ;Bank 0 BCF STATUS,RP1 ; ;*************** init_lcd ;*************** bsf LED_BL1 ; light backlight led1 bsf LED_BL2 ; light backlight led2 movlw .40 ; wait for movwf loops ; LCD call WAIT ; to startup movlw B'00000011' movwf command call send_n_chk movlw .2 movwf loops call WAIT movlw B'00000011' movwf command call send_n_chk call delay_30us movlw B'00000011' movwf command call send_n_chk call delay_30us call check_busy movlw B'00000010' movwf command call send_n_chk ; function set call delay_30us movlw B'10010010' movwf command call send_command ; function set call delay_30us movlw B'11000001' movwf command ; bias call send_command call delay_30us movlw B'00100101' movwf command ; power control call send_command call delay_30us movlw B'10010110' movwf command ; follower control call send_command call delay_30us movlw B'11110111' ; changed; was B'01000111' movwf command ; contrast call send_command call delay_30us movlw B'11000000' movwf command ; display on call send_command call delay_30us movlw B'00010000' movwf command ; display clear, home call send_command call delay_30us movlw B'01100000' movwf command ; entry mode call send_command call delay_30us ; --------------------------------------------- ; UART---SET BAUD RATE TO COMMUNICATE WITH ATAG ; --------------------------------------------- ; Boot Baud Rate = 9600, No Parity, 1 Stop Bit ; bsf STATUS,RP0 ; Bank1 movlw b'00011001' ; 0x19=9600 bps movwf SPBRG movlw b'00000100' ; brgh = high (2) movwf TXSTA ; DISABLE Async Transmission, set brgh bcf STATUS,RP0 ; RAM PAGE 0 movlw b'10010000' ; enable Async Reception movwf RCSTA ; ; ------------------------------------ ; PROVIDE A SETTLING TIME FOR START UP ; ------------------------------------ ; clrf dataL settle decfsz dataL,F goto settle movf RCREG,W movf RCREG,W movf RCREG,W ; flush receive buffer clrf PIR1 ; set interrupts vor UART receiver movlw PIE1 ; movwf FSR ; set movlw b'00100000' ; RCIE movwf INDF ; bsf INTCON,PEIE bsf INTCON,GIE movLW CHR1 ; init pointer; get address of string1 movwf FSR ; and put in FSR ;********************************************************************************** ;********************************************************************************* ;MAIN PROGRAM ;********************************************************************************* MAIN ; 1 Mhz intern ; ea dogm 162 display ; PORTC: D7-4 = PC3-0 ; steuerleitungen an PORTA port_display equ PORTC tris_display equ TRISC ;********************************************************************************** show movLw 'C' movwf command call send_data movLw 'O' movwf command call send_data movLw 'L' movwf command call send_data movLw ':' movwf command call send_data movfw COL_1 movwf command call send_data movfw COL_MSD movwf command call send_data movfw COL_LSD movwf command call send_data movLw b'11011111' movwf command call send_data movLw 'C' movwf command call send_data movLw ' ' movwf command call send_data movLw 'P' movwf command call send_data movLw 'O' movwf command call send_data movLw ':' movwf command call send_data movfw PMP_1 movwf command call send_data movfw PMP_2 movwf command call send_data movfw PMP_3 movwf command call send_data movlw B'00001100' movwf command ; second line call send_command call delay_30us movLw 'B' movwf command call send_data movLw 'O' movwf command call send_data movLw 'I' movwf command call send_data movLw ':' movwf command call send_data movLw ' ' movwf command call send_data movfw BOI_MSD movwf command call send_data movfw BOI_LSD movwf command call send_data movLw b'11011111' ; degree movwf command call send_data movLw 'C' movwf command call send_data movLw ' ' movwf command call send_data movLw 'U' movwf command call send_data movLw 'R' movwf command call send_data movLw ':' movwf command call send_data movfw HRS_2 movwf command call send_data movfw HRS_3 movwf command call send_data movfw HRS_4 movwf command call send_data movlw B'00001000' movwf command ; back to line 1 call send_command call delay_30us bsf PORTC,5 ; RC5 is connected to RC6 and will call WAIT ; be set to give pulse to switch-line bcf PORTC,5 call WAIT call WAIT call WAIT call WAIT ;***************************************************** ; Find out which infoline has been send and store info ;***************************************************** test btfss EOS_FLAG,0 ; wait until string is complete goto test movlw CHR1 ; reset pointer movwf FSR movf RCREG,W movf RCREG,W movf RCREG,W ; flush receive buffer movf CHR1,w sublw b'01000011' ; C (dec67) btfss STATUS,Z ; is first chr a "C" goto next1 ; no ;; bsf FLAG,2 ; set flag line2(=Col:.... Boi:....) movf CHR5,w movwf COL_1 movf CHR6,w movwf COL_MSD movf CHR7,w movwf COL_LSD movf CHR13,w movwf BOI_1 movf CHR14,w movwf BOI_MSD movf CHR15,w movwf BOI_LSD next1 movf CHR1,w sublw b'01001100' ; L (dec76) btfss STATUS,Z ; is first chr a "L" goto next2 ; no ;; bsf FLAG,1 ; set flag line1(=Luigjes Delta-T) next2 movf CHR14,w sublw b'00100000' ; (dec32) btfss STATUS,Z ; is fourteenth chr a "space" goto next3 ; no ;; bsf FLAG,3 ; set flag line3(=PMP:UIT ) movf CHR5,w movwf PMP_1 movf CHR6,w movwf PMP_2 movf CHR7,w movwf PMP_3 next3 movf CHR5,w sublw b'01011001' ; Y (dec89) btfss STATUS,Z ; is fifth chr a "Y" goto next4 ; no ;; bsf FLAG,4 ; set flag line4(=....YCOL....YBOI) next4 movf CHR12,w sublw b'01010101' ; U (dec85) btfss STATUS,Z ; is twelfth chr a "U" goto next5 ; no ;; bsf FLAG,5 ; set flag line5(=PMP:......UREN ) movf CHR7,w movwf HRS_1 movf CHR8,w movwf HRS_2 movf CHR9,w movwf HRS_3 movf CHR10,w movwf HRS_4 next5 clrwdt ; reset watchdogtimer bcf EOS_FLAG,0 ; reset flag btfsc PORTB,2 ; test pushbutton goto show ; not pushed... ; If pushbutton is pushed, incoming lines wil be displayed ; unchanged, a new line every 2 seconds until watchdog ends this... showline movlw B'00001000' ; set display to movwf command ; first line call send_command call delay_30us bsf PORTC,5 ; RC5 is connected to RC6 and will call WAIT ; be set to give pulse to switch-line bcf PORTC,5 movfw CHR1 movwf command call send_data movfw CHR2 movwf command call send_data movfw CHR3 movwf command call send_data movfw CHR4 movwf command call send_data movfw CHR5 movwf command call send_data movfw CHR6 movwf command call send_data movfw CHR7 movwf command call send_data movfw CHR8 movwf command call send_data movfw CHR9 movwf command call send_data movfw CHR10 movwf command call send_data movfw CHR11 movwf command call send_data movfw CHR12 movwf command call send_data movfw CHR13 movwf command call send_data movfw CHR14 movwf command call send_data movfw CHR15 movwf command call send_data movfw CHR16 movwf command call send_data movlw B'00001100' ; set LCD to movwf command ; line 2 call send_command call delay_30us movLw ' ' movwf command call send_data movLw ' ' movwf command call send_data movLw ' ' movwf command call send_data movLw ' ' movwf command call send_data movLw ' ' movwf command call send_data movLw ' ' movwf command call send_data movLw ' ' movwf command call send_data movLw ' ' movwf command call send_data movLw ' ' movwf command call send_data movLw ' ' movwf command call send_data movLw ' ' movwf command call send_data movLw ' ' movwf command call send_data movLw ' ' movwf command call send_data movLw ' ' movwf command call send_data movLw ' ' movwf command call send_data movLw ' ' movwf command call send_data movlw B'00001000' ; LCD movwf command ; back to line 1 call send_command call delay_30us call WAIT ; delay call WAIT ; to call WAIT ; show call WAIT ; new call WAIT ; infoline call WAIT ; every call WAIT ; 2 call WAIT ; seconds call WAIT call WAIT call WAIT call WAIT call WAIT call WAIT call WAIT btfss PORTB,2 ; test pushbutton goto show goto showline ;----------------------------------------------------------- ; LCD Subroutine send_data ;*********************************************************** send_data call check_busy rrf command,1 ; bit 7-4 rrf command,1 ; have to be rrf command,1 ; shifted to rrf command,1 ; place 3-0 movlw 0x0F ; clear MS nibble andwf command,0 movwf port_display ; and sent to display bsf RS bcf RW bsf E nop ; important, this time is nop ; needed for the display to write register !! bcf E rrf command,1 ; shift 5 times rrf command,1 ; so result is again rrf command,1 ; equal rrf command,1 ; to rrf command,1 ; original movlw 0x0F ; clear MS nibble andwf command,0 movwf port_display ; and sent to display bsf RS bcf RW bsf E nop nop bcf E retlw .0 ;----------------------------------------------------------- ;LCD Subroutine send_command ;********************************************************** send_command call check_busy movlw 0x0F andwf command,0 movwf port_display bcf RS bcf RW bsf E nop nop bcf E swapf command,1 send_n_chk movlw 0x0F ; andwf command,0 movwf port_display bcf RS bcf RW bsf E nop nop bcf E retlw .0 ;----------------------------------------------------------- ; LCD Subroutine check_busy ;********************************************************* check_busy bsf STATUS,5 movlw 0x0F movwf tris_display bcf STATUS,5 chk bcf RS bsf RW bsf E nop nop movf port_display, w movwf temp bcf E nop nop bsf E nop nop bcf E btfsc temp, 3 goto chk bsf STATUS,5 movlw 0x00 movwf tris_display bcf STATUS,5 retlw .0 ;********************************************************** ; LCD Wait-loop subroutines ; Warteschleife 1 ms für einen 4MHz-PIC-Takt ;********************************************************** WAIT Wai movlw .110 ; Zeitkonstante für 1ms movwf loops2 Wai2 nop ; nop nop nop nop nop decfsz loops2, F ; 1 ms vorbei? goto Wai2 ; nein, noch nicht ; decfsz loops, F ; 250 ms vorbei? goto Wai ; nein, noch nicht retlw .0 ; das Warten hat ein Ende delay_30us movlw .10 movwf counter del decfsz counter,f ; 1 Befehl goto del ; 2 Befehle retlw .0 ; End of LCD communication block ;********************************************************************************* ; UART ;********************************************************************************* ; ; ------------------------------------------------------------ ; INTERRUPT ROUTINE RECEIVE CHARACTER FROM UART AND STORE IN W ; ------------------------------------------------------------ ; ; INTERRUPT movwf W_TEMP ; save swapf STATUS,W ; contence clrf STATUS ; of movwf STATUS_TEMP ; STATUS and W clrf STATUS movf RCREG,W ; move received data in W movwf temp_data ; store received character clrf PIR1 ; reset flag subLW b'0001101' ; is received character a CR ? btfsc STATUS,Z ; goto base_data ; yes, so go reset pointer goto next ; no, next character next movf temp_data,w ; get received character movwf INDF ; and store into RAM incf counter2,1 ; set counter 1 higher incf FSR,1 ; set pointer 1 higher for next chr movf counter2,w ; check if end of string sublw .16 ; when number of bytes is received, end of datastring btfsc STATUS,Z ; bsf EOS_FLAG,0 ; set flag End Of String movf RCREG,W ; flush receive buffer goto STOP base_data movLW CHR1 ; get address of string1 movwf FSR ; and put in FSR clrf counter2 ; reset counter STOP SWAPF STATUS_TEMP,W ; restore MOVWF STATUS ; old contence SWAPF W_TEMP,F ; of STATUS and SWAPF W_TEMP,W ; W RETFIE ; Done ;********************************************************************************** END ;********************************************************************************** ;**********************************************************************************