; --------------------------------------------------------- ; LED level meter. ; serial data inport ; --------------------------------------------------------- ; programed by rerofumi ; --------------------------------------------------------- list p=16f876a include P16F876A.INC ; ----- configuration __CONFIG _HS_OSC & _CP_OFF & _CPD_OFF & _WDT_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_OFF & _DEBUG_OFF ; ----- define LCDCPORT EQU PORTB LCDPORT EQU PORTB LCD_RS EQU 5 LCD_RW EQU 6 LCD_E EQU 7 LCDHALFTMP EQU 07fh LCDDISPTMP EQU 07eh LCDTABLETMP EQU 07dh ; --- Serial Interrupt RECEIVE EQU 020h PUSH_W EQU 021h PUSH_STATUS EQU 022h PUSH_FSR EQU 023h PUSH_PCLATH EQU 024h ; LED level meter DISPLEVEL EQU 028h AIMLEVEL EQU 029h WAITL EQU 02ah WAITH EQU 02bh ; led work LEDBANK EQU 02ch LEDTMP EQU 02dh LEDSEG EQU 02eh LED1 EQU 02fh LED2 EQU 030h LED3 EQU 031h LED4 EQU 032h LED5 EQU 033h LED6 EQU 034h LED7 EQU 035h LED8 EQU 036h ; --------------------------------------------------------- ; vector address ; --------------------------------------------------------- ; ------------------------------ ; cold start ; ------------------------------ org 000h goto Main ; ------------------------------ ; interuppt ; ------------------------------ org 004h goto IntStart ; --------------------------------------------------------- ; interrupt ; --------------------------------------------------------- IntStart ; push starus movwf PUSH_W movf STATUS, w movwf PUSH_STATUS movf FSR, w movwf PUSH_FSR movf PCLATH, w movwf PUSH_PCLATH ; ; ----- Serial receive ; bank 0 bcf STATUS, RP1 bcf STATUS, RP0 ; check receive interrupt btfss PIR1, RCIF goto IntEnd ; receive movf RCREG, w movwf RECEIVE ; next interrupt bcf PIR1, RCIF ; ; ----- return work IntEnd ; pop status movf PUSH_PCLATH, w movwf PCLATH movf PUSH_FSR, w movwf FSR movf PUSH_STATUS, w movwf STATUS swapf PUSH_W, f swapf PUSH_W, w ; retfie ; --------------------------------------------------------- ; ; LCD control subroutine ; ; --------------------------------------------------------- ; -------------------------- ; --- LCD Initialize LcdInit4bit ; --- boot up wait movlw 0c0h ; 19.2ms call LcdSubTm0Wait ; --- 8 bit mode request (for stat) movlw 0f0h andwf LCDPORT, f movlw 003h iorwf LCDPORT, f bcf LCDCPORT, LCD_RS bcf LCDCPORT, LCD_RW bsf LCDCPORT, LCD_E nop nop bcf LCDCPORT, LCD_E movlw d'30' call LcdSubTm0Wait movlw 0f0h andwf LCDPORT, f movlw 003h iorwf LCDPORT, f bsf LCDCPORT, LCD_E nop nop bcf LCDCPORT, LCD_E movlw 001h call LcdSubTm0Wait movlw 0f0h andwf LCDPORT, f movlw 003h iorwf LCDPORT, f bsf LCDCPORT, LCD_E nop nop bcf LCDCPORT, LCD_E movlw 001h call LcdSubTm0Wait ; --- 4 bit mode request and initialize movlw 002h movwf LCDPORT bcf LCDCPORT, LCD_RS bcf LCDCPORT, LCD_RW bsf LCDCPORT, LCD_E nop nop bcf LCDCPORT, LCD_E movlw 010h call LcdSubTm0Wait ; setup movlw 02ch ; 2 line, 5x10 font call LcdCmdRequest movlw 008h ; display off (non cursor) call LcdCmdRequest movlw 00ch ; display on (non cursor) call LcdCmdRequest movlw 006h ; entry mode call LcdCmdRequest ; return ; -------------------------- ; --- Send Command to LCD ; w = send data (8bit) LcdCmdRequest ; 8bit store movwf LCDHALFTMP ; -- RAM bank 0 bcf STATUS, RP0 bcf STATUS, RP1 ; - higher 4bit movlw 0f0h andwf LCDPORT, f swapf LCDHALFTMP, w andlw 00fh iorwf LCDPORT, f ; RS=0 bcf LCDCPORT, LCD_RS ; R/W=0 command request bcf LCDCPORT, LCD_RW ; E = high nop nop nop bsf LCDCPORT, LCD_E nop nop nop ; E = low bcf LCDCPORT, LCD_E ; nop nop nop ; - lower 4bit movlw 0f0h andwf LCDPORT, f movf LCDHALFTMP, w andlw 00fh iorwf LCDPORT, f ; E = high bsf LCDCPORT, LCD_E nop nop nop ; E = low bcf LCDCPORT, LCD_E ; busy wait call LcdSubBusyWait return ; -------------------------- ; --- Send Data to LCD ; w = send data (8bit) LcdPutChar ; 8bit store movwf LCDHALFTMP ; -- RAM bank 0 bcf STATUS, RP0 bcf STATUS, RP1 ; - higher 4bit movlw 0f0h andwf LCDPORT, f swapf LCDHALFTMP, w andlw 00fh iorwf LCDPORT, f ; RS=1 bsf LCDCPORT, LCD_RS ; R/W=0 command request bcf LCDCPORT, LCD_RW ; E = high nop nop nop bsf LCDCPORT, LCD_E nop nop nop ; E = low bcf LCDCPORT, LCD_E ; nop nop nop ; - lower 4bit movlw 0f0h andwf LCDPORT, f movf LCDHALFTMP, w andlw 00fh iorwf LCDPORT, f ; E = high bsf LCDCPORT, LCD_E nop nop nop ; E = low bcf LCDCPORT, LCD_E ; busy wait call LcdSubBusyWait return ; -------------------------- ; --- Set cursor position on LCD ; w = position ; line1 00h - ; line2 40h - LcdCursor iorlw 080h goto LcdCmdRequest ; -------------------------- ; --- display hex number on LCD ; w = data (8bit) LcdPutHex movwf LCDDISPTMP swapf LCDDISPTMP, w call LcdSubGetHex call LcdPutChar movf LCDDISPTMP, w call LcdSubGetHex call LcdPutChar return ; --------------------------------------- ; LCD internal subroutine ; --------------------------------------- ; -------------------------- ; --- Busy check and wait LcdSubBusyWait clrf LCDHALFTMP ; PORT-C 0-4 is INPUT bsf STATUS, RP0 movlw b'00011111' movwf TRISB bcf STATUS, RP0 ; status read bcf LCDCPORT, LCD_RS ; RS = 0 bsf LCDCPORT, LCD_RW ; R/W = 1 (read) nop nop nop bsf LCDCPORT, LCD_E ; E = high nop nop nop movf LCDPORT, w ; read status high bcf LCDCPORT, LCD_E ; E = low nop nop nop andlw 00fh movwf LCDHALFTMP swapf LCDHALFTMP, f bsf LCDCPORT, LCD_E ; E = high nop nop nop movf LCDPORT, w ; read status low bcf LCDCPORT, LCD_E ; E = low ;andlw 00fh ;iorwf LCDHALFTMP, f ; busy check btfsc LCDHALFTMP, 7 goto LcdSubBusyWait ; ; PORT-C 4 is INPUT bsf STATUS, RP0 movlw b'00010000' movwf TRISB bcf STATUS, RP0 bcf LCDCPORT, 1 ; R/W = 0 (write) ; return ; -------------------------- ; --- timer wait ; w = wait count (0.1ms) LcdSubTm0Wait bcf INTCON, T0IF sublw 0ffh movwf TMR0 tm0wait_loop1 btfss INTCON, T0IF goto tm0wait_loop1 bcf INTCON, T0IF movwf TMR0 tm0wait_loop2 btfss INTCON, T0IF goto tm0wait_loop2 bcf INTCON, T0IF return ; -------------------------- ; --- int to hex ascii ; w = data (4bit) ; warn! ; lookup table into same segment LcdSubGetHex movwf LCDTABLETMP movlw high(LcdSubGetHexTable) movwf PCLATH movf LCDTABLETMP, w andlw 00fh addwf PCL, f LcdSubGetHexTable retlw a'0' retlw a'1' retlw a'2' retlw a'3' retlw a'4' retlw a'5' retlw a'6' retlw a'7' retlw a'8' retlw a'9' retlw a'A' retlw a'B' retlw a'C' retlw a'D' retlw a'E' retlw a'F' ; --------------------------------------------------------- ; ; LED control subroutine ; ; --------------------------------------------------------- LedLevel movf LEDBANK, w btfss STATUS, Z goto LedDisp ; -------------- ; segment data movf DISPLEVEL, w movwf LEDTMP clrf LEDSEG movlw d'12' LedSegLoop subwf LEDTMP, f btfss STATUS, C goto LedSegEnd incf LEDSEG, f goto LedSegLoop ; LedSegEnd clrf LED1 clrf LED2 clrf LED3 clrf LED4 call LedGetBank movwf FSR call LedGetPortC movwf INDF movlw b'00011111' incf FSR, f movwf INDF incf FSR, f movwf INDF incf FSR, f movwf INDF ; -------------- ; disp led LedDisp movlw b'00111111' iorwf PORTC call LedGetPortA movwf PORTA ; movf LEDBANK, w addlw LED1 movwf FSR movf INDF, w andwf PORTC ; -------------- ; done LedEnd incf LEDBANK, f movlw 003h andwf LEDBANK, f return LedGetPortA movlw high(LedGetPortATable) movwf PCLATH movf LEDBANK, w addwf PCL, f LedGetPortATable retlw b'00000001' retlw b'00000010' retlw b'00000100' retlw b'00001000' LedGetPortC movlw high(LedGetPortCTable) movwf PCLATH movf LEDSEG, w addwf PCL, f LedGetPortCTable retlw b'11111111' retlw b'11111110' retlw b'11111100' retlw b'11111000' retlw b'11110000' retlw b'11111111' retlw b'11111110' retlw b'11111100' retlw b'11111000' retlw b'11110000' retlw b'11111111' retlw b'11111110' retlw b'11111100' retlw b'11111000' retlw b'11110000' retlw b'11111111' retlw b'11111110' retlw b'11111100' retlw b'11111000' retlw b'11110000' retlw b'11111111' retlw b'11111111' LedGetBank movlw high(LedGetBankTable) movwf PCLATH movf LEDSEG, w addwf PCL, f LedGetBankTable retlw LED1 retlw LED1 retlw LED1 retlw LED1 retlw LED1 retlw LED2 retlw LED2 retlw LED2 retlw LED2 retlw LED2 retlw LED3 retlw LED3 retlw LED3 retlw LED3 retlw LED3 retlw LED4 retlw LED4 retlw LED4 retlw LED4 retlw LED4 retlw LED5 retlw LED5 ; --------------------------------------------------------- ; main routine ; --------------------------------------------------------- Main ; ------------------------------ ; initalize ; ------------------------------ bcf STATUS, RP1 ; -- RAM bank 1 bsf STATUS, RP0 ; IO setting movlw b'00010000' movwf TRISB movlw b'00000110' movwf ADCON1 clrf TRISA movlw b'10000000' movwf TRISC ; Timer0 bcf OPTION_REG, T0CS bcf OPTION_REG, PSA ; Sirial port movlw d'51' ; 16Mhz 19.2kbps movwf SPBRG bsf TXSTA, BRGH bsf TXSTA, TXEN ; -- RAM bank 0 bcf STATUS, RP0 ; port clear clrf PORTB bcf RCSTA, 7 ; Sirial port bsf RCSTA, SPEN bsf RCSTA, CREN ; --- LCD initialize call LcdInit4bit ; --- enable interrupt bcf STATUS, RP0 bsf INTCON, GIE bsf INTCON, PEIE bsf STATUS, RP0 ; serial receive interrupt bsf PIE1, RCIE ; bcf STATUS, RP0 ; ------------------------------ ; LCD disp ; ------------------------------ ; com clear movlw 01h call LcdCmdRequest ; movlw 00h call LcdCursor movlw 'R' call LcdPutChar ; movlw 05h call LcdCursor movlw 'D' call LcdPutChar clrf DISPLEVEL clrf AIMLEVEL clrf LEDBANK clrf WAITL ; ------------------------------ ; loop work ; ------------------------------ MainWorkLoop ; --- command from pc movf RECEIVE, w movwf AIMLEVEL ; --- move disp level ; wait incf WAITL movlw 0ffh andwf WAITL, w btfss STATUS, Z goto MainLedDrive ; incf WAITH movlw 001h andwf WAITH, w btfss STATUS, Z goto MainLedDrive ; ; no work at same movf AIMLEVEL, w subwf DISPLEVEL, w btfsc STATUS, Z goto MainLedDrive ; sub or add btfsc STATUS, C goto MainDispSub incf DISPLEVEL goto MainDispLcd MainDispSub decf DISPLEVEL ; LCD information MainDispLcd movlw 01h call LcdCursor movf AIMLEVEL, w call LcdPutHex movlw 06h call LcdCursor movf DISPLEVEL, w call LcdPutHex ; --- LED control MainLedDrive call LedLevel ; MainNext goto MainWorkLoop ; --- code end end