; --------------------------------------------------------- ; 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 ; moter position DISPLEVEL EQU 028h AIMLEVEL EQU 029h WAITL EQU 02ah WAITH EQU 02bh ; --------------------------------------------------------- ; vector address ; --------------------------------------------------------- ; ------------------------------ ; cold start ; ------------------------------ org 000h goto Main ; ------------------------------ ; interuppt ; ------------------------------ org 004h goto IntStart ; --------------------------------------------------------- ; interrupt ; --------------------------------------------------------- IntStart ; push starus movwf PUSH_W swapf 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 clrf PCLATH ; check receive interrupt btfss PIR1, RCIF goto IntEnd btfsc RCSTA,FERR goto SirErr1 btfsc RCSTA,OERR goto SirErr2 ; receive movf RCREG, w movwf RECEIVE IntNext ; next interrupt bcf PIR1, RCIF ; ; ----- return work IntEnd ; pop status movf PUSH_PCLATH, w movwf PCLATH movf PUSH_FSR, w movwf FSR swapf PUSH_STATUS, w movwf STATUS swapf PUSH_W, f swapf PUSH_W, w ; retfie ; --- framing error SirErr1 movf RCREG,w goto IntNext ; --- overrun error SirErr2 bcf RCSTA,CREN bsf RCSTA,CREN goto IntNext ; --------------------------------------------------------- ; ; 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' ; --------------------------------------------------------- ; ; moter control subroutine ; ; --------------------------------------------------------- MoterDrive call MoterGetPortA movwf PORTA ; return MoterGetPortA movlw high(LedGetPortATable) movwf PCLATH movf DISPLEVEL, w andlw b'00000011' addwf PCL, f LedGetPortATable retlw b'00001001' retlw b'00000011' retlw b'00000110' retlw b'00001100' ; --------------------------------------------------------- ; 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 PORTA 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 WAITL clrf WAITH ; ------------------------------ ; 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 MainNext ; incf WAITH movlw 00fh andwf WAITH, w btfss STATUS, Z goto MainNext ; ; no work at same movf AIMLEVEL, w subwf DISPLEVEL, w btfsc STATUS, Z goto MainNext ; sub or add btfsc STATUS, C goto MainDispSub incf DISPLEVEL goto MainDispAim MainDispSub decf DISPLEVEL ; LCD information MainDispAim movlw 01h call LcdCursor movf AIMLEVEL, w call LcdPutHex movlw 06h call LcdCursor movf DISPLEVEL, w call LcdPutHex ; --- Moter control MainMoterDrive call MoterDrive ; MainNext goto MainWorkLoop ; --- code end end