
- •Table of Contents
- •Preface
- •Additional Material
- •Basic Electronics
- •1.0 The Atom
- •1.1 Isotopes and Ions
- •1.2 Static Electricity
- •1.3 Electrical Charge
- •1.4 Electrical Circuits
- •1.5 Circuit Elements
- •1.6 Semiconductors
- •Number Systems
- •2.0 Counting
- •2.1 The Origins of the Decimal System
- •2.2 Types of Numbers
- •2.3 Radix Representations
- •2.4 Number System Conversions
- •Data Types and Data Storage
- •3.0 Electronic-Digital Machines
- •3.1 Character Representations
- •3.2 Storage and Encoding of Integers
- •3.3 Encoding of Fractional Numbers
- •3.4 Binary-Coded Decimals (BCD)
- •Digital Logic, Arithmetic, and Conversions
- •4.0 Microcontroller Logic and Arithmetic
- •4.1 Logical Instructions
- •4.2 Microcontroller Arithmetic
- •4.3 Bit Manipulations and Auxiliary Operations
- •4.4 Unsigned Binary Arithmetic
- •4.5 Signed Binary Arithmetic
- •4.6 Data Format Conversions
- •Circuits and Logic Gates
- •5.0 Digital Circuits
- •5.1 The Diode Revisited
- •5.2 The Transistor
- •5.3 Logic Gates
- •5.4 Transistor-Transistor Logic
- •5.5 Other TTL Logic Families
- •5.6 CMOS Logic Gates
- •Circuit Components
- •6.0 Power Supplies
- •6.1 Clocked Logic and Flip-flops
- •6.2 Clocks
- •6.3 Frequency Dividers and Counters
- •6.4 Multiplexers and Demultiplexers
- •6.5 Input Devices
- •The Microchip PIC
- •7.0 The PICMicro Microcontroller
- •7.1 PIC Architecture
- •Mid-range PIC Architecture
- •8.0 Processor Architecture and Design
- •8.1 The Mid-range Core Features
- •8.2 Mid-Range CPU and Instruction Set
- •8.3 EEPROM Data Storage
- •8.4 Data Memory Organization
- •8.5 Mid-range I/O and Peripheral Modules
- •PIC Programming: Tools and Techniques
- •9.0 Microchip’s MPLAB
- •9.1 Integrated Development Environment
- •9.2 Simulators and Debuggers
- •9.3 Programmers
- •9.4 Engineering PIC Software
- •9.5 Pseudo Instructions
- •Programming Essentials: Input and Output
- •10.0 16F84A Programming Template
- •10.1 Introducing the 16F84A
- •10.2 Simple Circuits and Programs
- •10.3 Programming the Seven-segment LED
- •10.4 A Demonstration Board
- •Interrupts
- •11.0 Interrupts on the 16F84
- •11.1 Interrupt Sources
- •11.2 Interrupt Handlers
- •11.3 Interrupt Programming
- •11.4 Sample Programs
- •Timers and Counters
- •12.0 The 16F84 Timer0 Module
- •12.1 Delays Using Timer0
- •12.2 Timer0 as a Counter
- •12.3 Timer0 Programming
- •12.4 The Watchdog Timer
- •12.5 Sample Programs
- •LCD Interfacing and Programming
- •13.0 LCD Features and Architecture
- •13.1 Interfacing with the HD44780
- •13.2 HD44780 Instruction Set
- •13.3 LCD Programming
- •13.4 Sample Programs
- •Communications
- •14.0 PIC Communications Overview
- •14.1 Serial Data Transmission
- •14.2 Parallel Data Transmission
- •14.4 PIC Protocol-based Serial Programming
- •14.5 Sample Programs
- •Data EEPROM Programming
- •15.0 PIC Internal EEPROM Memory
- •15.1 EEPROM Devices and Interfaces
- •15.2 Sample Programs
- •Analog to Digital and Realtime Clocks
- •16.0 A/D Converters
- •16.1 A/D Integrated Circuits
- •16.2 PIC On-Board A/D Hardware
- •16.3 Realtime Clocks
- •16.4 Sample Programs
- •Index
306 |
Chapter 13 |
to send ASCII characters. Since the scarcity of port lines is the original reason for using a master/slave set up, parallel communications may not be a good solution in many cases. On the other hand, communications between master and slave can take place serially, using a single interface line. The discussion of using serial interface between a master and an LCD slave driver PIC is left for the chapter on serial communications.
13.4 Sample Programs
The following section lists the sample programs discussed in this chapter.
13.4.1 LCDTest1
;File name: LCDTest1.asm
;Date: April 13, 2006
;Author: Julio Sanchez
;Processor: 16F84A
;Description:
;Program to exercise 8-bit PIC-to-LCD interface.
;Code assumes that LCD is driven by Hitachi HD44780
;controller and that the display supports two lines
;each one with 16 characters. The wiring and base
;address of each display line is stored in #define
;statements. These statements can be edited to
;accommodate a different set-up.
;Program uses delay loops for interface timing.
;WARNING:
;Code assumes 4Mhz clock. Delay routines must be
;edited for faster clock
;Displays: Minnesota State, Mankato
;
;===========================
;switches ;===========================
;Switches used in __config directive:
; |
|
_CP_ON |
Code protection ON/OFF |
; * |
_CP_OFF |
|
|
; |
* |
_PWRTE_ON |
Power-up timer ON/OFF |
;_PWRTE_OFF
; |
_WDT_ON |
Watchdog timer ON/OFF |
|
|
; * _WDT_OFF |
|
|
|
|
; |
_LP_OSC |
Low power crystal |
occilator |
|
; * _XT_OSC |
External parallel |
resonator/crystal oscillator |
||
; |
_HS_OSC |
High speed crystal resonator (8 to |
10 MHz) |
|
; |
|
Resonator: Murate |
Erie CSA8.00MG = |
8 MHz |
LCD Interfacing and Programming |
307 |
||
; |
_RC_OSC |
Resistor/capacitor oscillator (simplest, 20% |
|
error) |
|
|
;|
;|_____ * indicates set up values
;========================= ; set up and configuration ;=========================
processor 16f84A
include |
<p16f84A.inc> |
__config |
_XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF |
;===================================================== |
|
; |
constant definitions |
; for PIC-to-LCD pin wiring and LCD line addresses |
|
;===================================================== |
|
#define E_line 1 |
;| |
#define RS_line 2 |
;| — from wiring diagram |
#define RW_line 3 |
;| |
; LCD line addresses (from LCD data sheet) |
|
#define LCD_1 0x80 |
; First LCD line constant |
#define LCD_2 0xc0 |
; Second LCD line constant |
;Note: The constants that define the LCD display line
;addresses have the high-order bit set in
;order to facilitate the controller command
;
;=====================================================
; |
variables in PIC RAM |
;=====================================================
;Reserve 16 bytes for string buffer cblock 0x0c
strData endc
;Leave 16 bytes and Continue with local variables
cblock 0x1d |
; Start of block |
count1 |
; Counter # 1 |
count2 |
; Counter # 2 |
count3 |
; Counter # 3 |
pic_ad |
; Storage for start of text area |
|
; (labeled strData) in PIC RAM |
J |
; counter J |
K |
; counter K |
index |
; Index into text table (also used |
|
; for auxiliary storage) |
endc |
|
;============================================================
; program
308 |
Chapter 13 |
main: |
|
|
|
|
; Allow LCD time to initialize |
|
|
; itself |
call |
initLCD |
; Then do forced |
|
|
; initialization |
call |
delay_5ms |
; Wait. |
; Store base address of text buffer in PIC RAM |
||
movlw |
0x0c |
; Start address of text buffer |
movwf |
pic_ad |
; to local variable |
movlw |
b’00000000’ |
; All lines to output |
tris |
PORTA |
; in Port-A |
tris |
PORTB |
; and port B |
movlw |
b’00000000’ |
; All outputs ports low |
movwf |
PORTA |
|
movwf |
PORTB |
|
; Wait and initialize HD44780 |
|
|
call |
delay_5ms |
|
;======================
;first LCD line ;======================
;Store 16 blanks in PIC RAM, starting at address stored
;in variable pic_ad
call blank16
;Call procedure to store ASCII characters for message
;in text buffer
|
movlw |
d’3’ |
; Offset into buffer |
|
call |
storeMN |
|
; Set DDRAM address to start of first line |
|||
|
call |
line1 |
|
; Call procedure to display 16 characters in LCD |
|||
|
call |
display16 |
|
;======================== |
|
||
; |
second LCD line |
|
|
;======================== |
|
||
|
call |
delay_125mcs |
; Wait for termination |
|
call |
blank16 |
; Blank buffer |
;Call procedure to store ASCII characters for message
;in text buffer
movlw |
d’1’ |
; |
Offset into buffer |
call |
storeUniv |
|
|
call |
line2 |
; |
DDRAM address of LCD line 2 |
call |
display16 |
|
|
;=======================
LCD Interfacing and Programming |
309 |
; done! ;======================= loopHere:
goto loopHere ;done
;************************************************************ ; INITIALIZE LCD PROCEDURE ;************************************************************ initLCD
;Initialization for Densitron LCD module as follows:
;8-bit interface
;2 display lines of 16 characters each
;cursor on
;left-to-right increment
;cursor shift right
;no display shift
;***********************| |
|
|
|
|||
; |
COMMAND MODE |
| |
|
|
|
|
;***********************| |
|
|
|
|||
|
bcf |
PORTA,E_line |
|
; E line low |
||
|
bcf |
PORTA,RS_line |
|
; RS line low for command |
||
|
bcf |
PORTA,RW_line |
; Write mode |
|||
|
call |
delay_125mcs |
|
|
;delay 125 |
|
microseconds |
|
|
|
|
|
|
;***********************| |
|
|
|
|||
; |
FUNCTION SET |
| |
|
|
|
|
;***********************| |
|
|
|
|||
|
movlw |
0x38 |
; 0 0 |
1 |
1 1 0 0 0 (FUNCTION SET) |
|
|
|
|
; |
| |
| | |__ font select: |
|
|
|
|
; |
| |
| | |
1 = 5x10 in 1/8 or 1/11 |
|
|
|
; |
| |
| | |
0 = 1/16 dc |
|
|
|
; |
| |
| |___ Duty cycle select |
|
|
|
|
; |
| |
| |
0 = 1/8 or 1/11 |
|
|
|
; |
| |
| |
1 = 1/16 |
|
|
|
; |
| |
|___ Interface width |
|
|
|
|
; |
| |
0 = 4 bits |
|
|
|
|
; |
| |
1 = 8 bits |
|
|
|
|
; |
|___ FUNCTION SET COMMAND |
||
|
movwf |
PORTB |
;0011 |
1000 |
|
|
|
call |
pulseE |
;pulseE |
and delay |
||
;***********************| |
|
|
|
|||
; |
DISPLAY OFF |
|
| |
|
|
|
;***********************| |
|
|
|
|||
|
movlw |
0x08 |
; 0 0 |
0 |
0 1 0 0 0 (DISPLAY ON/OFF) |
|
|
|
|
; |
|
| | | |___ Blink character |
|
|
|
|
; |
|
| | | |
1 = on, 0 = off |
|
|
|
; |
|
| | |___ Cursor on/off |
310 |
|
|
|
|
|
|
Chapter 13 |
|
|
|
; |
|
| |
| |
1 = on, 0 = off |
|
|
|
; |
|
| |
|____ Display on/off |
|
|
|
|
; |
|
| |
|
1 = on, 0 = off |
|
|
|
; |
|
|____ COMMAND BIT |
||
|
movwf |
PORTB |
|
|
|
|
|
|
call |
pulseE |
;pulseE and |
delay |
|
||
;***********************| |
|
|
|
|
|||
; DISPLAY AND CURSOR ON | |
|
|
|
|
|||
;***********************| |
|
|
|
|
|||
|
movlw |
0x0e |
; 0 0 0 0 |
1 |
1 1 0 (DISPLAY ON/OFF) |
||
|
|
|
; |
|
| |
| | |___ Blink character |
|
|
|
|
; |
|
| |
| | |
1 = on, 0 = off |
|
|
|
; |
|
| |
| |___ Cursor on/off |
|
|
|
|
; |
|
| |
| |
1 = on, 0 = off |
|
|
|
; |
|
| |
|____ Display on/off |
|
|
|
|
; |
|
| |
|
1 = on, 0 = off |
|
|
|
; |
|
|____ COMMAND BIT |
||
|
movwf |
PORTB |
|
|
|
|
|
|
call |
pulseE |
;pulseE and |
delay |
|
||
;***********************| |
|
|
|
|
|||
; |
ENTRY MODE SET |
| |
|
|
|
|
|
;***********************| |
|
|
|
|
|||
|
movlw |
0x06 |
; 0 0 0 0 |
0 |
1 1 0 (ENTRY MODE SET) |
||
|
|
|
; |
|
|
| | |___ display shift |
|
|
|
|
; |
|
|
| | |
1 = shift |
|
|
|
; |
|
|
| | |
0 = no shift |
|
|
|
; |
|
|
| |____ increment mode |
|
|
|
|
; |
|
|
| |
1 = left-to-right |
|
|
|
; |
|
|
| |
0 = right-to-left |
|
|
|
; |
|
|
|___ COMMAND BIT |
|
|
movwf |
PORTB |
;00000110 |
|
|
|
|
|
call |
pulseE |
|
|
|
|
|
;***********************| |
|
|
|
|
|||
; CURSOR/DISPLAY SHIFT |
| |
|
|
|
|
||
;***********************| |
|
|
|
|
|||
|
movlw |
0x14 |
; 0 0 0 1 |
0 |
1 0 0 (CURSOR/DISPLAY |
||
|
|
|
; |
| |
| |
| | | |
SHIFT) |
|
|
|
; |
| |
| |
| |_|___ don’t care |
|
|
|
|
; |
| |
|_|__ cursor/display shift |
||
|
|
|
; |
| |
|
00 = cursor shift left |
|
|
|
|
; |
| |
|
01 = cursor shift right |
|
|
|
|
; |
| |
|
10 = cursor and display |
|
|
|
|
; |
| |
|
|
shifted left |
|
|
|
; |
| |
|
11 = cursor and display |
LCD Interfacing and Programming |
|
311 |
; |
| |
shifted right |
|
|
|
; |
|___ COMMAND BIT |
|
movwf |
PORTB |
;0001 |
1111 |
|
call |
pulseE |
|
|
;***********************| |
|
|
||
; |
CLEAR DISPLAY |
| |
|
|
;***********************| |
|
|
||
|
movlw |
0x01 |
; 0 0 |
0 0 0 0 0 1 (CLEAR DISPLAY) |
|
|
|
; |
|___ COMMAND BIT |
|
movwf |
PORTB |
;0000 |
0001 |
; |
|
|
|
|
|
call |
pulseE |
|
|
|
call |
delay_5ms |
;delay 5 milliseconds after |
init
return ;************************************************************ ; DELAY AND PULSE PROCEDURES ;************************************************************ ;=======================
;Procedure to delay
;42 microseconds ;======================= delay_125mcs
movlw |
D’42’ |
; Repeat 42 machine cycles |
movwf |
count1 |
; Store value in counter |
repeat |
|
|
decfsz |
count1,f |
; Decrement counter |
goto |
repeat |
; Continue if not 0 |
return |
|
; End of delay |
;=======================
;Procedure to delay
;5 milliseconds ;======================= delay_5ms
|
movlw |
D’41’ |
; Counter = 41 |
|
movwf |
count2 |
; Store in variable |
delay |
|
|
|
|
call |
delay_125mcs |
; Delay |
|
decfsz |
count2,f |
; 40 times = 5 milliseconds |
|
goto |
delay |
|
|
return |
|
; End of delay |
;======================== |
|
||
; |
pulse E line |
|
|
;======================== |
|
||
pulseE |
|
|
|
|
bsf |
PORTA,E_line |
;pulse E line |
|
bcf |
PORTA,E_line |
|
312 |
|
Chapter 13 |
call |
delay_125mcs |
;delay 125 microseconds |
return |
|
|
;=============================
;long delay sub-routine
;(for debugging) ;============================= long_delay
movlw |
D’200’ |
; w = 200 decimal |
movwf |
J |
; J = w |
jloop: |
|
|
movwf |
K |
; K = w |
kloop: |
|
|
decfsz |
K,f |
; K = K-1, skip next if zero |
goto |
kloop |
|
decfsz |
J,f |
; J = J-1, skip next if zero |
goto |
jloop |
|
return |
|
|
;=============================
;LCD display procedure ;=============================
;Sends 16 characters from PIC buffer with address stored
;in variable pic_ad to LCD line previously selected display16:
;Set up for data
bcf |
PORTA,E_line |
; E line low |
||
bsf |
PORTA,RS_line |
; RS line low for control |
||
call |
delay_125mcs |
; Delay |
||
; Set up counter for 16 characters |
||||
movlw |
D’16’ |
; |
Counter = 16 |
|
movwf |
count3 |
|
|
|
; Get display address from local variable pic_ad |
||||
movf |
pic_ad,w ; |
First display RAM address to W |
||
movwf |
FSR |
; |
W to FSR |
|
getchar: |
|
|
|
|
movf |
INDF,w |
; |
get character from display RAM |
|
|
|
; |
location pointed to by file select |
|
|
|
; |
register |
|
movwf |
PORTB |
|
|
|
call |
pulseE |
;send data to display |
||
; Test for 16 characters displayed |
||||
decfsz |
count3,f |
|
|
; Decrement counter |
goto |
nextchar ; |
Skipped if done |
||
return |
|
|
|
|
nextchar: |
|
|
|
|
incf |
FSR,f |
; |
Bump pointer |
|
goto |
getchar |
|
|
|
;========================
LCD Interfacing and Programming |
313 |
;blank buffer ;========================
;Procedure to store 16 blank characters in PIC RAM
;buffer starting at address stored in the variable
;pic_ad
blank16: |
|
|
movlw |
D’16’ |
; Set up counter |
movwf |
count1 |
|
movf |
pic_ad,w ; First PIC RAM address |
|
movwf |
FSR |
; Indexed addressing |
movlw |
0x20 |
; ASCII space character |
storeit: |
|
|
movwf |
INDF |
; Store blank character in PIC |
RAM |
|
|
|
|
; buffer using FSR register |
decfsz |
count1,f |
; Done? |
goto |
incfsr |
; no |
return |
|
; yes |
incfsr: |
|
|
incf |
FSR,f |
; Bump FSR to next buffer |
space |
|
|
goto |
storeit |
|
;========================
;Set Address register
;to LCD line 1 ;========================
;ON ENTRY:
;Address of LCD line 1 in constant LCD_1
line1:
bcf |
PORTA,E_line |
; E line low |
bcf |
PORTA,RS_line |
; RS line low, set up for |
control |
|
|
call |
delay_125mcs |
; delay 125 microseconds |
; Set to second display line |
|
|
movlw |
LCD_1 |
; Address and command bit |
movwf |
PORTB |
|
call |
pulseE |
; Pulse and delay |
; Set RS line for data |
|
|
bsf |
PORTA,RS_line |
; Set up for data |
call |
delay_125mcs |
; Delay |
return |
|
|
;========================
;Set Address register
;to LCD line 2 ;========================
;ON ENTRY:
;Address of LCD line 2 in constant LCD_2
314
line2: |
|
bcf |
PORTA,E_line |
bcf |
PORTA,RS_line |
call |
delay_125mcs |
; Set to second display line |
|
movlw |
LCD_2 |
movwf |
PORTB |
call |
pulseE |
; Set RS line for data |
|
bsf |
PORTA,RS_line |
call |
delay_125mcs |
return |
|
;===============================
Chapter 13
;E line low
;RS line low, set up for
;control
;delay
;Address with high-bit set
;Pulse and delay
;RS = 1 for data
;delay
;first text string procedure ;=============================== storeMN:
;Procedure to store in PIC RAM buffer the message
;contained in the code area labeled msg1
;ON ENTRY:
;variable pic_ad holds address of text buffer
;in PIC RAM
;w register hold offset into storage area
;msg1 is routine that returns the string characters
;and a zero terminator
;index is local variable that hold offset into
;text table. This variable is also used for
;temporary storage of offset into buffer
;ON EXIT:
;Text message stored in buffer
;
;Store offset into text buffer (passed in the w register)
;in temporary variable
movwf |
index |
; Store w in index |
; Store base address of text buffer in FSR |
||
movf |
pic_ad,w ; first display RAM address to W |
|
addwf |
index,w |
; Add offset to address |
movwf |
FSR |
; W to FSR |
; Initialize index for text string access |
||
movlw |
0 |
; Start at 0 |
movwf |
index |
; Store index in variable |
; w still = 0 |
|
|
get_msg_char: |
|
|
call |
msg1 |
; Get character from table |
; Test for zero terminator |
|
|
andlw |
0x0ff |
|
btfsc |
STATUS,Z ; Test zero flag |
LCD Interfacing and Programming |
315 |
|
goto |
endstr1 |
; End of string |
;ASSERT: valid string character in w
;store character in text buffer (by FSR)
movwf |
INDF |
; store in buffer by FSR |
incf |
FSR,f |
; increment buffer pointer |
; Restore table character counter from variable |
||
movf |
index,w |
; Get value into w |
addlw |
1 |
; Bump to next |
character |
|
|
movwf |
index |
; Store table index in |
variable |
|
|
goto |
get_msg_char |
; Continue |
endstr1: |
|
|
return |
|
|
; Routine for returning message stored in program area msg1:
addwf |
PCL,f |
; Access table |
retlw |
‘M’ |
|
retlw |
‘i’ |
|
retlw |
‘n’ |
|
retlw |
‘n’ |
|
retlw |
‘e’ |
|
retlw |
‘s’ |
|
retlw |
‘o’ |
|
retlw |
‘t’ |
|
retlw |
‘a’ |
|
retlw |
0 |
|
;=================================
;second text string procedure ;================================= storeUniv:
;Processing identical to procedure StoreMSU
movwf |
index |
; Store w in index |
; Store base address of text buffer in FSR |
||
movf |
pic_ad,0 ; first display RAM address to W |
|
addwf |
index,0 |
; Add offset to address |
movwf |
FSR |
; W to FSR |
; Initialize index for text string access |
||
movlw |
0 |
; Start at 0 |
movwf |
index |
; Store index in variable |
; w still = 0 |
|
|
get_msg_char2: |
|
|
call |
msg2 |
; Get character from table |
; Test for zero terminator |
|
|
andlw |
0x0ff |
|
btfsc |
STATUS,Z ; Test zero flag |
316 |
|
Chapter 13 |
goto |
endstr2 |
; End of string |
;ASSERT: valid string character in w
;store character in text buffer (by FSR)
movwf |
INDF |
; Store in buffer by FSR |
incf |
FSR,f |
; Increment buffer pointer |
; Restore table character counter from variable |
||
movf |
index,w |
; Get value into w |
addlw |
1 |
; Bump to next character |
movwf |
index |
; Store table index in |
variable |
|
|
goto |
get_msg_char2 |
; Continue |
endstr2: |
|
|
return |
|
|
; Routine for returning message stored in program area msg2:
addwf |
PCL,f |
; Access table |
retlw |
‘S’ |
|
retlw |
‘t’ |
|
retlw |
‘a’ |
|
retlw |
‘t’ |
|
retlw |
‘e’ |
|
retlw |
‘,’ |
|
retlw |
0x20 |
|
retlw |
‘M’ |
|
retlw |
‘a’ |
|
retlw |
‘n’ |
|
retlw |
‘k’ |
|
retlw |
‘a’ |
|
retlw |
‘t’ |
|
retlw |
‘o’ |
|
retlw |
0 |
|
end |
|
|
13.4.2 LCDTest2 Program
;File name: LCDTest2.asm
;Date: April 16, 2006
;Author: Julio Sanchez
;Processor: 16F84A
;Description:
;Program to exercises 8-bit PIC-to-LCD interface.
;Code assumes that LCD is driven by Hitachi HD44780
;controller and that the display supports two lines
;each one with 16 characters. The wiring and base
LCD Interfacing and Programming |
317 |
;address of each display line is stored in #define
;statements. These statements can be edited to
;accommodate a different set-up.
;Program uses the busy flag to synchronize processor
;access, although delay loops are still required in
;some cases.
;Displays: Minnesota State, Mankato
;WARNING:
;Code assumes 4Mhz clock. Delay routines must be
;edited for faster clock
;
;Displays: Minnesota State, Mankato
;===========================
;switches ;===========================
;Switches used in __config directive:
; |
|
_CP_ON |
Code protection ON/OFF |
; * |
_CP_OFF |
|
|
; |
* |
_PWRTE_ON |
Power-up timer ON/OFF |
;_PWRTE_OFF
; |
_WDT_ON |
Watchdog timer ON/OFF |
|
|
; * _WDT_OFF |
|
|
|
|
; |
_LP_OSC |
Low power crystal |
occilator |
|
; * _XT_OSC |
External parallel |
resonator/crystal oscillator |
||
; |
_HS_OSC |
High speed crystal resonator (8 to |
10 MHz) |
|
; |
|
Resonator: Murate |
Erie CSA8.00MG = |
8 MHz |
; |
_RC_OSC |
Resistor/capacitor oscillator |
|
|
; | |
|
(simplest, 20% error) |
|
;|
;|_____ * indicates set up values presently selected
;========================= ; set up and configuration ;=========================
processor 16f84A
include |
<p16f84A.inc> |
__config |
_XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF |
;===================================================== |
|
; |
constant definitions |
; for PIC-to-LCD pin wiring and LCD line addresses |
|
;===================================================== |
|
#define E_line 1 |
;| |
#define RS_line 2 |
;| — from wiring diagram |
#define RW_line 3 |
;| |
; LCD line addresses (from LCD data sheet)
318 |
|
|
Chapter 13 |
#define LCD_1 |
0x80 |
; |
First LCD line constant |
#define LCD_2 |
0xc0 |
; |
Second LCD line constant |
;Note: The constants that define the LCD display line
;addresses have the high-order bit set in
;order to facilitate the controller command
;
;=====================================================
; |
variables in PIC RAM |
;=====================================================
;Reserve 16 bytes for string buffer cblock 0x0c
strData endc
;Leave 16 bytes and Continue with local variables
cblock |
0x1d |
|
; Start of block |
count1 |
|
; Counter # 1 |
|
count2 |
|
; Counter # 2 |
|
count3 |
|
; Counter # 3 |
|
pic_ad |
|
; Storage for start of text area |
|
|
|
; (labeled strData) in PIC RAM |
|
J |
|
; counter J |
|
K |
|
; counter K |
|
index |
|
; Index into text table (also used |
|
|
|
; for auxiliary storage) |
|
endc |
|
|
|
;========================================================= |
|||
; |
|
program |
|
;========================================================= |
|||
org |
0 |
; start at address |
|
goto |
main |
|
|
; Space for interrupt handlers |
|
||
org |
0x08 |
|
|
main: |
|
|
|
movlw |
b’00000000’ |
; All lines to output |
|
tris |
PORTA |
|
; in Port-A |
tris |
PORTB |
|
; and port B |
movlw |
b’00000000’ |
; All outputs ports low |
|
movwf |
PORTA |
|
|
movwf |
PORTB |
|
|
; Wait and initialize HD44780 |
|
||
call |
delay_5 |
|
; Allow LCD time to initialize |
|
|
|
; itself |
call |
initLCD |
|
; Then do forced |
initialization |
|
|
|
; Store base address of text buffer in PIC RAM |
|||
movlw |
0x0c |
|
; Start address for buffer |
LCD Interfacing and Programming |
319 |
|
movwf |
pic_ad |
; to local variable |
;======================
;first LCD line ;======================
;Store 16 blanks in PIC RAM, starting at address stored
;in variable pic_ad
call blank16
;Call procedure to store ASCII characters for message
;in text buffer
|
movlw |
d’3’ |
; Offset into buffer |
|
call |
storeMSU |
|
; Set DDRAM address to start of first line |
|||
|
call |
line1 |
|
; Call procedure to display 16 characters in LCD |
|||
|
call |
display16 |
|
;======================== |
|
||
; |
second LCD line |
|
|
;======================== |
|
||
|
call |
busyTest ; Wait for termination |
|
|
call |
blank16 |
; Blank buffer |
;Call procedure to store ASCII characters for message
;in text buffer
|
movlw |
d’1’ |
; Offset into buffer |
|
call |
storeUniv |
|
|
call |
line2 |
; DDRAM address of LCD line 2 |
|
call |
display16 |
|
;======================= |
|
||
; |
done! |
|
|
;======================= |
|
||
loopHere: |
|
|
|
|
goto |
loopHere |
;done |
;************************************************************
; INITIALIZE LCD PROCEDURE
;************************************************************
initLCD: |
|
|
|
|
|
;***********************| |
|
|
|||
; |
COMMAND MODE |
| |
|
|
|
;***********************| |
|
|
|||
|
bcf |
|
PORTA,E_line |
;E line low |
|
|
bcf |
|
PORTA,RS_line |
;RS line low |
|
|
call |
delay_125 |
|
;delay 125 |
|
microseconds |
|
|
|
|
|
;***********************| |
|
|
|||
; |
FUNCTION SET |
| |
|
|
|
;***********************| |
|
|
|||
|
movlw |
0x38 |
; 0 0 1 1 1 0 0 0 (FUNCTION SET) |
||
|
|
|
; |
| | | |__ font select: |
320 |
|
|
|
|
|
Chapter 13 |
|
|
|
; |
| | | |
|
1 = 5x10 in 1/8 or 1/11 |
|
|
|
; |
| | | |
|
0 = 1/16 dc |
|
|
|
; |
| | |___ Duty cycle select |
||
|
|
|
; |
| | |
|
1 = 1/8 or 1/11 |
|
|
|
; |
| | |
|
0 = 1/16 |
|
|
|
; |
| |___ Interface width |
||
|
|
|
; |
| |
0 = 4 bits |
|
|
|
|
; |
| |
1 = 8 bits |
|
|
|
|
; |
|___ FUNCTION SET COMMAND |
||
|
movwf |
PORTB |
;0011 1000 |
|
|
|
|
call |
pulseE |
;pulseE and |
delay |
||
;***********************| |
|
|
|
|||
; |
DISPLAY OFF |
|
| |
|
|
|
;***********************| |
|
|
|
|||
|
movlw |
0x08 |
; 0 0 0 0 1 |
0 0 0 (DISPLAY ON/OFF) |
||
|
|
|
; |
| |
| | |___ Blink character |
|
|
|
|
; |
| |
| | |
1 = on, 0 = off |
|
|
|
; |
| |
| |___ Cursor on/off |
|
|
|
|
; |
| |
| |
1 = on, 0 = off |
|
|
|
; |
| |
|____ Display on/off |
|
|
|
|
; |
| |
|
1 = on, 0 = off |
|
|
|
; |
|____ COMMAND BIT |
||
|
movwf |
PORTB |
|
|
|
|
|
call |
pulseE |
;pulseE and |
delay |
||
;***********************| |
|
|
|
|||
; DISPLAY AND CURSOR ON | |
|
|
|
|||
;***********************| |
|
|
|
|||
|
movlw |
0x0e |
; 0 0 0 0 1 |
1 1 0 (DISPLAY ON/OFF) |
||
|
|
|
; |
| |
| | |___ Blink character |
|
|
|
|
; |
| |
| | |
1 = on, 0 = off |
|
|
|
; |
| |
| |___ Cursor on/off |
|
|
|
|
; |
| |
| |
1 = on, 0 = off |
|
|
|
; |
| |
|____ Display on/off |
|
|
|
|
; |
| |
|
1 = on, 0 = off |
|
|
|
; |
|____ COMMAND BIT |
||
|
movwf |
PORTB |
|
|
|
|
|
call |
pulseE |
;pulseE and |
delay |
||
;***********************| |
|
|
|
|||
; |
ENTRY MODE SET |
| |
|
|
|
|
;***********************| |
|
|
|
|||
|
movlw |
0x06 |
; 0 0 0 0 0 |
1 1 0 (ENTRY MODE SET) |
||
|
|
|
; |
|
| | |___ display shift |
|
|
|
|
; |
|
| | |
1 = shift |
|
|
|
; |
|
| | |
0 = no shift |
|
|
|
; |
|
| |____ increment mode |
LCD Interfacing and Programming |
|
|
321 |
|||
|
|
|
; |
|
| |
1 = left-to-right |
|
|
|
; |
|
| |
0 = right-to-left |
|
|
|
; |
|
|___ COMMAND BIT |
|
|
movwf |
PORTB |
;00000110 |
|
|
|
|
call |
pulseE |
|
|
|
|
;***********************| |
|
|
|
|||
; CURSOR/DISPLAY SHIFT |
| |
|
|
|
||
;***********************| |
|
|
|
|||
|
movlw |
0x14 |
; |
0 0 0 1 |
0 1 0 |
0 (CURSOR/DISPLAY |
|
|
|
; |
| |
| | | | SHIFT) |
|
|
|
|
; |
| |
| | |_|___ don’t care |
|
|
|
|
; |
| |
|_|__ cursor/display shift |
|
|
|
|
; |
| |
|
00 = cursor shift left |
|
|
|
; |
| |
|
01 = cursor shift right |
|
|
|
; |
| |
|
10 = cursor and display |
|
|
|
; |
| |
|
shifted left |
|
|
|
; |
| |
|
11 = cursor and display |
|
|
|
; |
| |
|
shifted right |
|
|
|
; |
|___ COMMAND BIT |
||
|
movwf |
PORTB |
;0001 1111 |
|
|
|
|
call |
pulseE |
|
|
|
|
;***********************| |
|
|
|
|||
; |
CLEAR DISPLAY |
|
| |
|
|
|
;***********************| |
|
|
|
|||
|
movlw |
0x01 |
; |
0 0 0 0 |
0 0 0 |
1 (CLEAR DISPLAY) |
|
|
|
; |
|
|
|___ COMMAND BIT |
|
movwf |
PORTB |
;0000 0001 |
|
|
|
; |
|
|
|
|
|
|
|
call |
pulseE |
|
|
|
|
|
call |
busyTest ; |
Test for busy |
|
||
|
return |
|
|
|
|
|
;========================
;busy flag test routine ;========================
;Procedure to test the HD44780 busy flag
;Execution returns when flag is clear busyTest:
movlw |
b’11111111’ |
; All lines |
to input |
|
tris |
PORTB |
; in port B |
|
|
bcf |
PORTA,RS_line |
; RS line low |
for control |
|
bsf |
PORTA,RW_line |
; Read mode |
|
|
bsf |
PORTA,E_line |
; E line high |
|
|
movf |
PORTB,w |
; Read port |
B |
into W |
; Port B bit 7 is busy flag |
|
|
|
|
bcf |
PORTA,E_line |
; E line low |
|
|
322 |
|
|
|
Chapter 13 |
andlw |
0x80 |
; Test bit 7, high is busy |
||
btfss |
STATUS,Z ; Test zero |
bit |
in STATUS |
|
goto |
busyTest ; Repeat if |
set |
|
;At this point busy flag is clear
;Reset R/W line and port B to output
bcf |
PORTA,RW_line |
; Clear R/W |
line |
|
movlw |
b’00000000’ |
; |
All lines |
to output |
tris |
PORTB |
; |
in port B |
|
return |
|
|
|
|
;=======================
;Procedure to delay
;42 microseconds ;======================= delay_125:
movlw |
D’42’ |
; Repeat 42 machine cycles |
movwf |
count1 |
; Store value in counter |
repeat: |
|
|
decfsz |
count1,f |
; Decrement counter |
goto |
repeat |
; Continue if not 0 |
return |
|
; End of delay |
;=======================
;Procedure to delay
;5 milliseconds ;======================= delay_5:
|
movlw |
D’41’ |
; Counter = 41 |
|
movwf |
count2 |
; Store in variable |
delay: |
|
|
|
|
call |
delay_125 |
; Delay |
|
decfsz |
count2,f |
; 40 times = 5 milliseconds |
|
goto |
delay |
|
|
return |
|
; End of delay |
;======================== |
|
||
; |
pulse E line |
|
|
;======================== |
|
||
pulseE |
|
|
|
|
bsf |
PORTA,E_line |
; Pulse E line |
|
nop |
|
; Delay |
|
bcf |
PORTA,E_line |
|
|
call |
delay_5 |
; Wait |
|
return |
|
|
;=============================
;long delay sub-routine
;(for debugging) ;=============================
LCD Interfacing and Programming |
323 |
|
long_delay |
|
|
movlw |
D’200’ ; w = 200 decimal |
|
movwf |
J |
; J = w |
jloop: |
|
|
movwf |
K |
; K = w |
kloop: |
|
|
decfsz |
K,f |
; K = K-1, skip next if zero |
goto |
kloop |
|
decfsz |
J,f |
; J = J-1, skip next if zero |
goto |
jloop |
|
return |
|
|
;=============================
;LCD display procedure ;=============================
;Sends 16 characters from PIC buffer with address stored
;in variable pic_ad to LCD line previously selected display16
call |
busyTest ; Make sure not busy |
||
; Set up for data |
|
|
|
bcf |
PORTA,E_line |
; E line low |
|
bsf |
PORTA,RS_line |
; RS line high for data |
|
; Set up counter for 16 characters |
|||
movlw |
D’16’ |
|
; Counter = 16 |
movwf |
count3 |
|
|
; Get display address from local variable pic_ad |
|||
movf |
pic_ad,w ; First display RAM address to W |
||
movwf |
FSR |
|
; W to FSR |
getchar |
|
|
|
movf |
INDF,w |
; get character from display RAM |
|
|
|
; location pointed to by file select |
|
|
|
; register |
|
movwf |
PORTB |
|
|
call |
pulseE |
;send data to display |
|
; Test for 16 characters displayed |
|||
decfsz |
count3,f |
|
; Decrement counter |
goto |
nextchar ; Skipped if done |
||
return |
|
|
|
nextchar: |
|
|
|
incf |
FSR,f |
; Bump pointer |
|
goto |
getchar |
|
|
;========================
;blank buffer ;========================
;Procedure to store 16 blank characters in PIC RAM
;buffer starting at address stored in the variable
;pic_ad
blank16:
movlw |
D’16’ |
; Set up counter |
324 |
|
Chapter 13 |
movwf |
count1 |
|
movf |
pic_ad,w |
; First PIC RAM address |
movwf |
FSR |
; Indexed addressing |
movlw |
0x20 |
; ASCII space character |
storeit: |
|
|
movwf |
INDF |
; Store blank character in PIC |
RAM |
|
|
|
|
; buffer using FSR register |
decfsz |
count1,f |
; Done? |
goto |
incfsr |
; no |
return |
|
; yes |
incfsr |
|
|
incf |
FSR,f |
; Bump FSR to next buffer |
|
|
; space |
goto storeit ;========================
;Set Address register
;to LCD line 1 ;========================
;ON ENTRY:
;Address of LCD line 1 in constant LCD_1
line1:
bcf |
PORTA,E_line |
; E line low |
bcf |
PORTA,RS_line |
; RS line low, set up for |
control |
|
|
call |
busyTest ; busy? |
|
; Set to second display line |
|
|
movlw |
LCD_1 |
; Address and command bit |
movwf |
PORTB |
|
call |
pulseE |
; Pulse and delay |
; Set RS line for data |
|
|
bsf |
PORTA,RS_line |
; Set up for data |
call |
busyTest ; Busy? |
|
return |
|
|
;========================
;Set Address register
;to LCD line 2 ;========================
;ON ENTRY:
;Address of LCD line 2 in constant LCD_2
line2:
bcf |
PORTA,E_line |
; E line low |
bcf |
PORTA,RS_line |
; RS line low, set up for |
control |
|
|
call |
busyTest |
; Busy? |
; Set to second display line |
|
|
movlw |
LCD_2 |
; Address with high-bit set |
movwf |
PORTB |
|
LCD Interfacing and Programming |
325 |
|
call |
pulseE |
; Pulse and delay |
; Set RS line for data |
|
|
bsf |
PORTA,RS_line |
; RS = 1 for data |
call |
busyTest ; Busy? |
|
return |
|
|
;===============================
;first text string procedure ;=============================== storeMSU:
;Procedure to store in PIC RAM buffer the message
;contained in the code area labeled msg1
;ON ENTRY:
;variable pic_ad holds address of text buffer
;in PIC RAM
;w register hold offset into storage area
;msg1 is routine that returns the string characters
;and a zero terminator
;index is local variable that hold offset into
;text table. This variable is also used for
;temporary storage of offset into buffer
;ON EXIT:
;Text message stored in buffer
;
;Store offset into text buffer (passed in the w register)
;in temporary variable
movwf |
index |
; Store w in index |
; Store base address of text buffer in FSR |
||
movf |
pic_ad,w ; first display RAM address to W |
|
addwf |
index,w |
; Add offset to address |
movwf |
FSR |
; W to FSR |
; Initialize index for text string access |
||
movlw |
0 |
; Start at 0 |
movwf |
index |
; Store index in variable |
; w still = 0 |
|
|
get_msg_char: |
|
|
call |
msg1 |
; Get character from table |
; Test for zero terminator |
|
|
andlw |
0x0ff |
|
btfsc |
STATUS,Z ; Test zero flag |
|
goto |
endstr1 |
; End of string |
;ASSERT: valid string character in w
;store character in text buffer (by FSR)
movwf |
INDF |
; store in buffer by FSR |
||
incf |
FSR,f |
; increment |
buffer pointer |
|
; Restore table character counter from variable |
||||
movf |
index,w |
; |
Get value |
into w |
addlw |
1 |
; |
Bump to next character |
326 |
|
Chapter 13 |
movwf |
index |
; Store table index in |
variable |
|
|
goto |
get_msg_char |
; Continue |
endstr1: |
|
|
return |
|
|
; Routine for returning message stored in program area msg1:
addwf |
PCL,f |
; Access table |
retlw |
‘M’ |
|
retlw |
‘i’ |
|
retlw |
‘n’ |
|
retlw |
‘n’ |
|
retlw |
‘e’ |
|
retlw |
‘s’ |
|
retlw |
‘o’ |
|
retlw |
‘t’ |
|
retlw |
‘a’ |
|
retlw |
0 |
|
;=================================
;second text string procedure ;================================= storeUniv:
;Processing identical to procedure StoreMSU
movwf |
index |
; Store w in index |
; Store base address of text buffer in FSR |
||
movf |
pic_ad,0 ; first display RAM address to W |
|
addwf |
index,0 |
; Add offset to address |
movwf |
FSR |
; W to FSR |
; Initialize index for text string access |
||
movlw |
0 |
; Start at 0 |
movwf |
index |
; Store index in variable |
; w still = 0 |
|
|
get_msg_char2: |
|
|
call |
msg2 |
; Get character from table |
; Test for zero terminator |
|
|
andlw |
0x0ff |
|
btfsc |
STATUS,Z ; Test zero flag |
|
goto |
endstr2 |
; End of string |
;ASSERT: valid string character in w
;store character in text buffer (by FSR)
movwf |
INDF |
; Store in buffer by FSR |
incf |
FSR,f |
; Increment buffer pointer |
; Restore table character counter from variable |
||
movf |
index,w |
; Get value into w |
addlw |
1 |
; Bump to next character |
movwf |
index |
; Store table index in |
LCD Interfacing and Programming |
|
327 |
|
|
|
; |
variable |
goto |
get_msg_char2 |
; |
Continue |
endstr2: |
|
|
|
return |
|
|
|
; Routine for returning message stored in program area msg2:
addwf |
PCL,f |
; Access table |
retlw |
‘S’ |
|
retlw |
‘t’ |
|
retlw |
‘a’ |
|
retlw |
‘t’ |
|
retlw |
‘e’ |
|
retlw |
‘,’ |
|
retlw |
0x20 |
|
retlw |
‘M’ |
|
retlw |
‘a’ |
|
retlw |
‘n’ |
|
retlw |
‘k’ |
|
retlw |
‘a’ |
|
retlw |
‘t’ |
|
retlw |
‘o’ |
|
retlw |
0 |
|
End |
|
|
13.4.3 LCDTest3 Program
;File name: LCDTest3.asm
;Date: April 16, 2006
;Author: Julio Sanchez
;Processor: 16F84A
;Description:
;Program to exercise 4-bit PIC-to-LCD interface.
;Code assumes that LCD is driven by Hitachi HD44780
;controller and that the display supports two lines
;each one with 16 characters. The wiring and base
;address of each display line is stored in #define
;statements. These statements can be edited to
;accommodate a different set-up.
;Program uses delay loops for interface timing.
;WARNING:
;Code assumes 4Mhz clock. Delay routines must be
;edited for faster clock
;
; Displays: Minnesota State, Mankato
;
328 |
Chapter 13 |
;===========================
;switches ;===========================
;Switches used in __config directive:
; |
|
_CP_ON |
Code protection ON/OFF |
; * |
_CP_OFF |
|
|
; |
* |
_PWRTE_ON |
Power-up timer ON/OFF |
;_PWRTE_OFF
; |
_WDT_ON |
Watchdog timer ON/OFF |
|
|
; * _WDT_OFF |
|
|
|
|
; |
_LP_OSC |
Low power crystal |
occilator |
|
; * _XT_OSC |
External parallel |
resonator/crystal oscillator |
||
; |
_HS_OSC |
High speed crystal resonator (8 to |
10 MHz) |
|
; |
|
Resonator: Murate |
Erie CSA8.00MG = |
8 MHz |
; |
_RC_OSC |
Resistor/capacitor oscillator |
|
|
; | |
|
(simplest, 20% error) |
|
;|
;|_____ * indicates set up values presently selected
;=========================
;set up and configuration
;=========================
processor 16f84A
include |
<p16f84A.inc> |
__config |
_XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF |
;===================================================== |
|
; |
constant definitions |
; for PIC-to-LCD pin wiring and LCD line addresses ;=====================================================
#define E_line 1 |
;| |
|
#define RS_line 2 |
;| — from wiring diagram |
|
#define RW_line 3 |
;| |
|
; LCD line addresses (from LCD data sheet) |
||
#define LCD_1 |
0x80 |
; First LCD line constant |
#define LCD_2 |
0xc0 |
; Second LCD line constant |
;Note: The constants that define the LCD display line
;addresses have the high-order bit set in
;order to facilitate the controller command
;
;=====================================================
; |
variables in PIC RAM |
;=====================================================
; Reserve 16 bytes for string buffer
cblock 0x0c
strData
endc
LCD Interfacing and Programming |
329 |
||
; Leave 16 bytes and Continue with local variables |
|||
cblock |
0x1d |
|
; Start of block |
count1 |
|
; Counter # 1 |
|
count2 |
|
; Counter # 2 |
|
count3 |
|
; Counter # 3 |
|
pic_ad |
|
; Storage for start of text area |
|
|
|
; (labeled strData) in PIC RAM |
|
J |
|
; counter J |
|
K |
|
; counter K |
|
index |
|
; Index into text table (also used |
|
|
|
; for auxiliary storage) |
|
store1 |
|
; Local temporary storage |
|
store2 |
|
; Storage # 2 |
|
endc |
|
|
|
;========================================================= |
|||
; |
|
program |
|
;========================================================= |
|||
org |
0 |
; start at address |
|
goto |
main |
|
|
; Space for interrupt handlers |
|
||
org |
0x08 |
|
|
main: |
|
|
|
movlw |
b’00000000’ |
; All lines to output |
|
tris |
PORTA |
|
; in Port-A |
tris |
PORTB |
|
; and port B |
movlw |
b’00000000’ |
; All outputs ports low |
|
movwf |
PORTA |
|
|
movwf |
PORTB |
|
|
; Wait and initialize HD44780 |
|
||
call |
delay_5 |
|
; Allow LCD time to initialize |
|
|
|
; itself |
call |
delay_5 |
|
|
call |
initLCD |
|
; Then do forced |
initialization |
|
|
|
call |
delay_5 |
|
; Wait again |
; Store base address of text buffer in PIC RAM |
|||
movlw |
0x0c |
|
; Start address for buffer |
movwf |
pic_ad |
|
; to local variable |
;======================
;first LCD line ;======================
;Store 16 blanks in PIC RAM, starting at address stored
;in variable pic_ad
call blank16
;Call procedure to store ASCII characters for message
;in text buffer
330 |
|
|
Chapter 13 |
|
movlw |
d’3’ |
; Offset into buffer |
|
call |
storeMSU |
|
; Set DDRAM address to start of first line |
|||
|
call |
line1 |
|
; Call procedure to display 16 characters in LCD |
|||
|
call |
display16 |
|
;======================== |
|
||
; |
second LCD line |
|
|
;======================== |
|
||
|
call |
delay_5 |
; Wait for termination |
|
call |
blank16 |
; Blank buffer |
;Call procedure to store ASCII characters for message
;in text buffer
|
movlw |
d’1’ |
; Offset into buffer |
|
call |
storeUniv |
|
|
call |
line2 |
; DDRAM address of LCD line 2 |
|
call |
display16 |
|
;======================= |
|
||
; |
done! |
|
|
;======================= |
|
||
loopHere: |
|
|
|
|
goto |
loopHere |
;done |
;============================================================ ; initialize LCD for 4-bit mode ;============================================================ initLCD:
;Initialization for Densitron LCD module as follows:
;4-bit interface
;2 display lines of 16 characters each
;cursor on
;left-to-right increment
;cursor shift right
;no display shift
;=======================| |
|
|
|||
; |
set command mode |
| |
|
|
|
;=======================| |
|
|
|||
|
bcf |
PORTA,E_line |
; E line low |
||
|
bcf |
PORTA,RS_line |
; RS line low |
||
|
bcf |
PORTA,RW_line |
; Write mode |
||
|
call |
delay_125 |
|
; delay 125 |
|
microseconds |
|
|
|
|
|
;***********************| |
|
|
|||
; |
FUNCTION SET |
| |
|
|
|
;***********************| |
|
|
|||
|
movlw |
0x28 |
; 0 0 1 0 1 0 0 0 (FUNCTION SET) |
||
|
|
|
; |
| | | |__ font select: |
|
|
|
|
; |
| | | |
1 = 5x10 in 1/8 or 1/11 |
LCD Interfacing and Programming |
|
|
331 |
|||
|
|
|
; |
| | | |
0 = 1/16 dc |
|
|
|
|
; |
| | |___ Duty cycle select |
||
|
|
|
; |
| | |
0 = 1/8 or 1/11 |
|
|
|
|
; |
| | |
1 = 1/16 |
|
|
|
|
; |
| |___ Interface width |
||
|
|
|
; |
| |
0 = 4 bits |
|
|
|
|
; |
| |
1 = 8 bits |
|
|
|
|
; |
|___ FUNCTION SET COMMAND |
||
|
call |
send8 |
; 4-bit send routine |
|||
; Set 4-bit mode command must be repeated |
||||||
|
movlw |
0x28 |
|
|
|
|
|
call |
send8 |
|
|
|
|
;***********************| |
|
|
|
|||
; DISPLAY AND CURSOR ON | |
|
|
|
|||
;***********************| |
|
|
|
|||
|
movlw |
0x0e |
; 0 0 0 0 1 1 1 0 (DISPLAY ON/OFF) |
|||
|
|
|
; |
|
| | | |___ Blink character |
|
|
|
|
; |
|
| | | |
1 = on, 0 = off |
|
|
|
; |
|
| | |___ Cursor on/off |
|
|
|
|
; |
|
| | |
1 = on, 0 = off |
|
|
|
; |
|
| |____ Display on/off |
|
|
|
|
; |
|
| |
1 = on, 0 = off |
|
|
|
; |
|
|____ COMMAND BIT |
|
|
call |
send8 |
|
|
|
|
;***********************| |
|
|
|
|||
; |
set entry mode |
| |
|
|
|
|
;***********************| |
|
|
|
|||
|
movlw |
0x06 |
; 0 0 0 0 0 1 1 0 (ENTRY MODE SET) |
|||
|
|
|
; |
|
| | |___ display shift |
|
|
|
|
; |
|
| | |
1 = shift |
|
|
|
; |
|
| | |
0 = no shift |
|
|
|
; |
|
| |____ increment mode |
|
|
|
|
; |
|
| |
1 = left-to-right |
|
|
|
; |
|
| |
0 = right-to-left |
|
|
|
; |
|
|___ COMMAND BIT |
|
|
call |
send8 |
|
|
|
|
;***********************| |
|
|
|
|||
; cursor/display shift |
| |
|
|
|
||
;***********************| |
|
|
|
|||
|
movlw |
0x14 |
; 0 0 0 1 0 1 0 0 (CURSOR/DISPLAY |
|||
|
|
|
; |
|
| | | | | SHIFT) |
|
|
|
|
; |
|
| | | |_|___ don’t care |
|
|
|
|
; |
|
| |_|__ cursor/display shift |
|
|
|
|
; |
|
| |
00 = cursor shift left |
|
|
|
; |
|
| |
01 = cursor shift right |
|
|
|
; |
|
| |
10 = cursor and display |
332 |
|
|
|
|
Chapter 13 |
|
|
|
; |
| |
shifted left |
|
|
|
; |
| |
11 = cursor and display |
|
|
|
; |
| |
shifted right |
|
|
|
; |
|___ COMMAND BIT |
|
|
call |
send8 |
|
|
|
;***********************| |
|
|
|||
; |
clear display |
| |
|
|
|
;***********************| |
|
|
|||
|
movlw |
0x01 |
; 0 0 0 0 |
0 0 0 1 (CLEAR DISPLAY) |
|
|
|
|
; |
|
|___ COMMAND BIT |
|
call |
send8 |
|
|
|
; Per documentation |
|
|
|
||
|
call |
delay_5 |
; Test for busy |
||
|
return |
|
|
|
|
;=======================
;Procedure to delay
;42 microseconds ;======================= delay_125
movlw |
D’42’ |
; Repeat 42 machine cycles |
movwf |
count1 |
; Store value in counter |
repeat |
|
|
decfsz |
count1,f |
; Decrement counter |
goto |
repeat |
; Continue if not 0 |
return |
|
; End of delay |
;=======================
;Procedure to delay
;5 milliseconds ;======================= delay_5:
|
movlw |
D’41’ |
; Counter = 41 |
|
movwf |
count2 |
; Store in variable |
delay: |
|
|
|
|
call |
delay_125 |
; Delay |
|
decfsz |
count2,f |
; 40 times = 5 milliseconds |
|
goto |
delay |
|
|
return |
|
; End of delay |
;======================== |
|
||
; |
pulse E line |
|
|
;======================== |
|
||
pulseE |
|
|
|
|
bsf |
PORTA,E_line |
; Pulse E line |
|
nop |
|
|
|
bcf |
PORTA,E_line |
|
|
return |
|
|
LCD Interfacing and Programming |
333 |
;=============================
;long delay sub-routine
;(for debugging) ;============================= long_delay:
movlw |
D’200’ |
; w = 200 decimal |
movwf |
J |
; J = w |
jloop: |
|
|
movwf |
K |
; K = w |
kloop: |
|
|
decfsz |
K,f |
; K = K-1, skip next if zero |
goto |
kloop |
|
decfsz |
J,f |
; J = J-1, skip next if zero |
goto |
jloop |
|
return |
|
|
;=============================
;LCD display procedure ;=============================
;Sends 16 characters from PIC buffer with address stored
;in variable pic_ad to LCD line previously selected display16
call |
delay_5 |
|
; Make sure not busy |
; Set up for data |
|
|
|
bcf |
PORTA,E_line |
; E line low |
|
bsf |
PORTA,RS_line |
; RS line high for data |
|
; Set up counter for 16 characters |
|||
movlw |
D’16’ |
|
; Counter = 16 |
movwf |
count3 |
|
|
; Get display address from local variable pic_ad |
|||
movf |
pic_ad,w ; First display RAM address to W |
||
movwf |
FSR |
|
; W to FSR |
getchar: |
|
|
|
movf |
INDF,w |
; get character from display RAM |
|
|
|
; location pointed to by file select |
|
|
|
; register |
|
call |
send8 |
; 4-bit interface routine |
|
; Test for 16 characters displayed |
|||
decfsz |
count3,f |
|
; Decrement counter |
goto |
nextchar |
|
; Skipped if done |
return |
|
|
|
nextchar: |
|
|
|
incf |
FSR,f |
|
; Bump pointer |
goto |
getchar |
|
|
;========================
;send 2 nibbles in
;4-bit mode ;========================
334 |
Chapter 13 |
;Procedure to send two 4-bit values to port B lines
;7, 6, 5, and 4. High-order nibble is sent first
;ON ENTRY:
;w register holds 8-bit value to send
send8:
movwf |
store1 |
; Save |
original value |
call |
merge4 |
; Merge with port B |
|
; Now w has merged byte |
|
|
|
movwf |
PORTB |
; w to |
port B |
call |
pulseE |
; Send |
data to LCD |
; High nibble is sent |
|
|
|
movf |
store1,w |
; Recover byte into w |
|
swapf |
store1,w |
; Swap |
nibbles in w |
call |
merge4 |
|
|
movwf |
PORTB |
|
|
call |
pulseE |
; Send |
data to LCD |
call |
delay_125 |
|
|
return |
|
|
|
;=================
;merge bits ;=================
;Routine to merge the 4 high-order bits of the
;value to send with the contents of port B
;so as to preserve the 4 low-bits in port B
;Logic:
;AND value with 1111 0000 mask
;AND port B with 0000 1111 mask
;Now low nibble in value and high nibble in
;port B are all 0 bits:
;value = vvvv 0000
;port B = 0000 bbbb
;OR value and port B resulting in:
; |
vvvv bbbb |
;ON ENTRY:
;w contain value bits
;ON EXIT:
;w contains merged bits
merge4:
andlw |
b’11110000’ |
; ANDing |
with |
0 clears the |
||
|
|
; bit. ANDing |
with 1 preserves |
|||
|
|
; the original value |
||||
movwf |
store2 |
; |
Save |
result |
in variable |
|
movf |
PORTB,w |
; |
port |
B |
to w |
register |
andlw |
b’00001111’ |
Clear high nibble |
in port b |
|
|
; and preserve low |
nibble |
iorwf |
store2,w ; OR two operands in w |
|
|
return |
|
|
|
LCD Interfacing and Programming |
335 |
;========================
;blank buffer ;========================
;Procedure to store 16 blank characters in PIC RAM
;buffer starting at address stored in the variable
;pic_ad
blank16 |
|
|
|
movlw |
D’16’ |
; |
Set up counter |
movwf |
count1 |
|
|
movf |
pic_ad,w ; |
First PIC RAM address |
|
movwf |
FSR |
; |
Indexed addressing |
movlw |
0x20 |
; |
ASCII space character |
storeit |
|
|
|
movwf |
INDF |
; |
Store blank character in PIC RAM |
|
|
; |
buffer using FSR register |
decfsz |
count1,f |
|
; Done? |
goto |
incfsr |
; |
no |
return |
|
; |
yes |
incfsr |
|
|
|
incf |
FSR,f |
; |
Bump FSR to next buffer space |
goto |
storeit |
|
|
;========================
;Set Address register
;to LCD line 1 ;========================
;ON ENTRY:
;Address of LCD line 1 in constant LCD_1
line1:
bcf |
PORTA,E_line |
; E line low |
bcf |
PORTA,RS_line |
; RS line low, set up for |
control |
|
|
call |
delay_5 |
; busy? |
; Set to second display line |
|
|
movlw |
LCD_1 |
; Address and command bit |
call |
send8 |
; 4-bit routine |
; Set RS line for data |
|
|
bsf |
PORTA,RS_line |
; Set up for data |
call |
delay_5 |
; Busy? |
return |
|
|
;========================
;Set Address register
;to LCD line 2 ;========================
;ON ENTRY:
;Address of LCD line 2 in constant LCD_2
line2:
bcf |
PORTA,E_line |
; E line low |
336 |
|
Chapter 13 |
bcf |
PORTA,RS_line |
; RS line low, set up for |
|
|
; control |
call |
delay_5 |
; Busy? |
; Set to second display line |
|
|
movlw |
LCD_2 |
; Address with high-bit set |
call |
send8 |
|
; Set RS line for data |
|
|
bsf |
PORTA,RS_line |
; RS = 1 for data |
call |
delay_5 |
; Busy? |
return |
|
|
;===============================
;first text string procedure ;=============================== storeMSU:
;Procedure to store in PIC RAM buffer the message
;contained in the code area labeled msg1
;ON ENTRY:
;variable pic_ad holds address of text buffer
;in PIC RAM
;w register hold offset into storage area
;msg1 is routine that returns the string characters
;andiy a zero terminator
;index is local variable that hold offset into
;text table. This variable is also used for
;temporary storage of offset into buffer
;ON EXIT:
;Text message stored in buffer
;
;Store offset into text buffer (passed in the w register)
;in temporary variable
movwf |
index |
; Store w in index |
; Store base address of text buffer in FSR |
||
movf |
pic_ad,w ; first display RAM address to W |
|
addwf |
index,w |
; Add offset to address |
movwf |
FSR |
; W to FSR |
; Initialize index for text string access |
||
movlw |
0 |
; Start at 0 |
movwf |
index |
; Store index in variable |
; w still = 0 |
|
|
get_msg_char: |
|
|
call |
msg1 |
; Get character from table |
; Test for zero terminator |
|
|
andlw |
0x0ff |
|
btfsc |
STATUS,Z ; Test zero flag |
|
goto |
endstr1 |
; End of string |
;ASSERT: valid string character in w
;store character in text buffer (by FSR)
LCD Interfacing and Programming |
337 |
|
movwf |
INDF |
; store in buffer by FSR |
incf |
FSR,f |
; increment buffer pointer |
; Restore table character counter from variable |
||
movf |
index,w |
; Get value into w |
addlw |
1 |
; Bump to next character |
movwf |
index |
; Store table index in |
variable |
|
|
goto |
get_msg_char |
; Continue |
endstr1: |
|
|
return |
|
|
; Routine for returning message stored in program area |
||
msg1: |
|
|
addwf |
PCL,f |
; Access table |
retlw |
‘M’ |
|
retlw |
‘i’ |
|
retlw |
‘n’ |
|
retlw |
‘n’ |
|
retlw |
‘e’ |
|
retlw |
‘s’ |
|
retlw |
‘o’ |
|
retlw |
‘t’ |
|
retlw |
‘a’ |
|
retlw |
0 |
|
;=================================
;second text string procedure ;================================= storeUniv:
;Processing identical to procedure StoreMSU
movwf |
index |
; Store w in index |
; Store base address of text buffer in FSR |
||
movf |
pic_ad,0 ; first display RAM address to W |
|
addwf |
index,0 |
; Add offset to address |
movwf |
FSR |
; W to FSR |
; Initialize index for text string access |
||
movlw |
0 |
; Start at 0 |
movwf |
index |
; Store index in variable |
; w still = 0 |
|
|
get_msg_char2: |
|
|
call |
msg2 |
; Get character from table |
; Test for zero terminator |
|
|
andlw |
0x0ff |
|
btfsc |
STATUS,Z ; Test zero flag |
|
goto |
endstr2 |
; End of string |
;ASSERT: valid string character in w
;store character in text buffer (by FSR)
movwf |
INDF |
; |
Store in buffer by FSR |
incf |
FSR,f |
; |
Increment buffer pointer |
338 |
|
Chapter 13 |
; Restore table character counter from variable |
||
movf |
index,w |
; Get value into w |
addlw |
1 |
; Bump to next character |
movwf |
index |
; Store table index in |
|
|
; variable |
goto |
get_msg_char2 |
; Continue |
endstr2: |
|
|
return |
|
|
; Routine for returning message stored in program area msg2:
addwf |
PCL,f |
; Access table |
retlw |
‘S’ |
|
retlw |
‘t’ |
|
retlw |
‘a’ |
|
retlw |
‘t’ |
|
retlw |
‘e’ |
|
retlw |
‘,’ |
|
retlw |
0x20 |
|
retlw |
‘M’ |
|
retlw |
‘a’ |
|
retlw |
‘n’ |
|
retlw |
‘k’ |
|
retlw |
‘a’ |
|
retlw |
‘t’ |
|
retlw |
‘o’ |
|
retlw |
0 |
|
end |
|
|