;******************************************************************
; *
; Filename: 12F683 595 LCD RB.asm *
; Author: Mike McLaren, K8LH *
; Date: 03-Nov-11 *
; *
; *
; Raj Bhatt's 12F683 + 74HC595 + LCD Circuit Experiment *
; *
; MPLab: 8.80 (tabs = 8) *
; MPAsm: 5.43 *
; *
;******************************************************************
processor PIC12F683
include "P12F683.inc"
list st=off ; suppress LST file symbol table
errorlevel -302 ; suppress bank warning messages
radix dec
__CONFIG _MCLRE_OFF & _WDT_OFF & _INTOSCIO
;
; variables
;
cblock 0x20
work ; low level lcd work variable
delayhi ; DelayCy() work variable
endc
;
; defines
;
#define clk_pin GPIO,1 ; to 74HC595 CLK & LAT pins
#define dat_pin GPIO,5 ; to 74HC595 DAT pin
#define ena_pin GPIO,2 ; to LCD 'E' pin
;******************************************************************
; K8LH DelayCy() subsystem macro generates four instructions *
;******************************************************************
radix dec
clock equ 8 ; 4, 8, 12, 16, 20 (MHz), etc.
usecs equ clock/4 ; cycles/microsecond multiplier
msecs equ clock/4*1000 ; cycles/millisecond multiplier
DelayCy macro delay ; 11..327690 cycle range
movlw high((delay-11)/5)+1
movwf delayhi
movlw low ((delay-11)/5)
call uDelay-((delay-11)%5)
endm
;******************************************************************
; reset vector *
;******************************************************************
org 0x0000
v_reset
clrf STATUS ; force bank 0, IRP = 0 |B0
goto init ; |B0
;******************************************************************
; interrupt vector *
;******************************************************************
org 0x0004
v_int
;******************************************************************
; subroutines *
;******************************************************************
PutCMD
clrc ; C = RS = 0 (command) |B0
skpnc ; skip |B0
PutDAT
setc ; C = RS = 1 (data) |B0
movwf work ; save data |B0
call PutNyb ; send hi nybble |B0
swapf work,F ; |B0
call PutNyb ; send lo nybble |B0
DelayCy(40*usecs) ; 40 us inter-char delay |B0
return ; |B0
;
; shift out RS bit, the hi nibble bits, and one extra clock
;
PutNyb
bcf dat_pin ; dat = 0 |B0
skpnc ; RS = 1? no, skip, else |B0
bsf dat_pin ; dat = 1 |B0
bsf clk_pin ; clk = 1 (strobe clk) |B0
bcf clk_pin ; clk = 0 |B0
b7 bcf dat_pin ; dat = 0 |B0
btfsc work,7 ; b7 = 1? no, skip, else |B0
bsf dat_pin ; dat = 1 |B0
bsf clk_pin ; clk = 1 |B0
bcf clk_pin ; clk = 0 |B0
b6 bcf dat_pin ; dat = 0 |B0
btfsc work,6 ; b6 = 1? no, skip, else |B0
bsf dat_pin ; dat = 1 |B0
bsf clk_pin ; clk = 1 |B0
bcf clk_pin ; clk = 0 |B0
b5 bcf dat_pin ; dat = 0 |B0
btfsc work,5 ; b5 = 1? no, skip, else |B0
bsf dat_pin ; dat = 1 |B0
bsf clk_pin ; clk = 1 |B0
bcf clk_pin ; clk = 0 |B0
b4 bcf dat_pin ; dat = 0 |B0
btfsc work,4 ; b4 = 1? no, skip, else |B0
bsf dat_pin ; dat = 1 |B0
bsf clk_pin ; clk = 1 |B0
bcf clk_pin ; clk = 0 |B0
bsf clk_pin ; clk = 1 (extra clock) |B0
bcf clk_pin ; clk = 0 |B0
bsf ena_pin ; ena = 1 (strobe data) |B0
bcf ena_pin ; ena = 0 |B0
return ; |B0
;******************************************************************
; K8LH DelayCy() 16-bit uDelay (11..327690 cycle) subroutine *
; *
nop ; entry for (delay-11)%5 == 4 |B0
nop ; entry for (delay-11)%5 == 3 |B0
nop ; entry for (delay-11)%5 == 2 |B0
nop ; entry for (delay-11)%5 == 1 |B0
uDelay addlw -1 ; subtract 5 cycle loop time |B0
skpc ; borrow? no, skip, else |B0
decfsz delayhi,F ; done? yes, skip, else |B0
goto uDelay ; do another loop |B0
return ; |B0
;******************************************************************
; main.init *
;******************************************************************
;
; void main() //
; { //
; cmcon0 = 7; // comparator off, digital I/O
; osccon = 0x70; // setup INTOSC for 8-MHz
; while(osccon.HTS == 0); // wait for osc 'stable' flag
; trisio = 0b00001000; // GP3 input, others outputs
; gpio = 0; // clear all output latches
;
init
movlw 7 ; |B0
movwf CMCON0 ; comparator off, digital I/O |B0
bsf STATUS,RP0 ; bank 1 |B1
clrf ANSEL ; analog ADC off, digital I/O |B1
movlw 0x70 ; |B1
movwf OSCCON ; setup INTOSC = 8-MHz |B1
stable
btfss OSCCON,HTS ; osc stable? yes, skip, else |B1
goto stable ; |B1
movlw b'00001000' ; |B1
movwf TRISIO ; GP3 input, others outputs |B1
bcf STATUS,RP0 ; bank 0 |B0
clrf GPIO ; set all output latches low |B0
;
; //
; // initialize HD44780 display in 4-bit interface mode
; //
; delay_ms(100); // 100 msec LCD 'power up' reset
; PutNyb(0x20); // hi nibble of "4-bit" command
; PutCMD(0x28); // 4-bit, 2-lines, 5x7 font
; PutCMD(0x08); // display, cursor, blink all off
; PutCMD(0x01); // clear display
; delay_us(1530); // required 1.53 msec delay
; PutCMD(0x06); // cursor inc, shift off
; PutCMD(0xC0); // display on, leave cursor off
;
DelayCy(100*msecs) ; 100-msec LCD 'power up' reset |B0
movlw 0x20 ; hi nybble of "4-bit" command |B0
call PutNyb ; set "4-bit interface" mode |B0
movlw 0x28 ; 4-bit, 2-lines, 5x7 font |B0
call PutCMD ; send "function set" command |B0
movlw 0x08 ; display, cursor, blink all off |B0
call PutCMD ; send "display on/off" command |B0
movlw 0x01 ; clear display (1.53-msecs) |B0
call PutCMD ; send "entry mode set" command |B0
DelayCy(1530*usecs) ; 1.53 msec delay for "clear" |B0
movlw 0x06 ; cursor inc, shift off |B0
call PutCMD ; send "entry mode set" command |B0
movlw 0xC0 ; display on, leave cursor off |B0
call PutCMD ; send "display on/off" command |B0
;
movlw 'H' ; print "hello world" |B0
call PutDAT ; send 'H' |B0
movlw 'e' ; |B0
call PutDAT ; send 'e' |B0
movlw 'l' ; |B0
call PutDAT ; send 'l' |B0
movlw 'l' ; |B0
call PutDAT ; send 'l' |B0
movlw 'o' ; |B0
call PutDAT ; send 'o' |B0
movlw ' ' ; |B0
call PutDAT ; send ' ' |B0
movlw 'W' ; |B0
call PutDAT ; send 'W' |B0
movlw 'o' ; |B0
call PutDAT ; send 'o' |B0
movlw 'r' ; |B0
call PutDAT ; send 'r' |B0
movlw 'l' ; |B0
call PutDAT ; send 'l' |B0
movlw 'd' ; |B0
call PutDAT ; send 'd' |B0
loop goto loop ; loop forever |B0
;******************************************************************
end