技术热线: 4007-888-234

PIC单片机在ICD做lcd显示时钟演示程序

更新时间: 2019-03-21
阅读量:487

;*************************************************
;* CLKTEST.ASM *
;*-----------------------------------------------*
;*-----------------------------------------------*
;*************************************************
;* ICDDEMO教学实验板 lcd显示时钟演示程序 *
;*************************************************
include

;*----
; 定义 LCD数据& 控制I/O口
LCD_DATA equ PORTB
LCD_CNTL1 equ PORTB
LCD_CNTL2 equ PORTA

; 定义 LCD控制相应的I/O引脚
RS equ 1
E equ 5

; LCD 模块命令
DISP_ON EQU 0x00C ; 开显示
DISP_ON_C EQU 0x00E ; 开显示, 开指针
DISP_ON_B EQU 0x00F ; 开显示, 开指针,开闪烁
DISP_OFF EQU 0x008 ; 关显示
CLR_DISP EQU 0x001 ; 清显示的操作数
ENTRY_INC EQU 0x006 ; 操作数
ENTRY_INC_S EQU 0x007 ; 操作数
ENTRY_DEC EQU 0x004 ; 操作数
ENTRY_DEC_S EQU 0x005 ; 操作数
DD_RAM_ADDR EQU 0x080 ; 初始化第一行显示的操作数
DD_RAM_UL EQU 0x0c0 ; 初始化第二行显示的操作数

; 设置显示相关寄存器
;*----

org 0
nop
goto start
org 4
goto ISR

org 10

CalTable
bcf STATUS,RP0
bcf PCLATH,0
movlw 0x66 ; 进行校准处理
subwf Temp,w ;
addwf PCL,f ; 将补偿结果与 PCL相加
dt 0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5
dt 6,6,6,7,7,7,8,8,8,9,9,0xa,0xa,0xb,0xb,0xc,0xc
dt 0xd,0xd,0xe,0xe,0xf,0xf,0xf,0x10,0x10,0x10
dt 0x11,0x11,0x12,0x12,0x12,0x13,0x13,0x14,0x14,0x14
dt 0x15,0x15,0x15,0x16,0x16,0x16,0x17,0x17,0x18,0x18
dt 0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,0x1c,0x1c
dt 0x1d,0x1d,0x1d,0x1e,0x1e,0x1f,0x1f,0x20,0x20
dt 0x21,0x21,0x22,0x22,0x23,0x23,0x24,0x24,0x25,0x25
dt 0x26,0x26,0x27,0x28,0x29,0x29,0x2a,0x2a,0x2b,0x2b
dt 0x2c,0x2d,0x2e,0x2f,0x30,0x3

movwf Temp

call Bin2BCDT ; 进行BCD码调整
movlw 08ah ; 从第一行的第0A个位置开始
call SendCmd
movf TempH,W ; 显示温度
call putcLCD
movf TempL,W
call putcLCD
movlw 'C' ; 显示“C”(表示摄氏度)
call putcLCD
movlw 20h
movwf BKM
return
;************************************************
;* Bin2BCDT - 将 Temp 寄存器内的二进制数转 *
;* 换为相应的 ASCII 码并存为 TempH:TempL 的形式 *
;************************************************
Bin2BCDT
bcf STATUS,RP0
clrf TempH ; Initialize variables
movf Temp,W
movwf TempL
Ttenth ; Subtract 10 from low variable
movlw .10 ; until result is < 0. On each
subwf TempL,W ; subtraction, increment the
btfss STATUS,C ; temperature high byte.
goto Over0
movwf TempL
incf TempH,F
goto Ttenth
Over0
movlw 0x30 ; Make decimal ASCII by adding
addwf TempH,F ; '0' to high and low byte
addwf TempL,F
return
;*************************************************
;* DisplayTime - 将显示指针移至第一行,调用Bin2BCD*
;* 子程序将Secs 和 Mins寄存器内的数据转换为相应的*
;* ASCII 码, 然后送 LCD显示. *
;*************************************************
DisplayTime
bcf STATUS,RP0
call Bin2BCD ; 调用二进制与bcd码转换子程序
movf HourH,W ; 显示小时高位
call putcLCD ;
movf HourL,W ; 显示小时低位
call putcLCD ;
movlw ':'
call putcLCD ; 显示 ':'
movf MinsH,W ; 显示分钟高位
call putcLCD ;
movf MinsL,W ; 显示分钟低位
call putcLCD ;
movlw ':' ; 显示 ':'
call putcLCD
movf SecsH,W ; 显示秒钟高位
call putcLCD ;
movf SecsL,W ; 显示秒钟低位
call putcLCD ;
return
;************************************************
;* Bin2BCD - 将 Secs & Mins 寄存器内的二进制数转*
;* 换为相应的 ASCII 码并存为 SecsH:SecsL 及 *
;* MinsH:MinsL,HourH:HourL的形式. *
;************************************************
Bin2BCD
bcf STATUS,RP0
clrf HourH ; 初始化变量
movf Hour,W ; 转换&ldquo;时&rdquo;
movwf HourL
Hourth ; Loop to subtract 10
movlw .10 ; from low byte and
subwf HourL,W ; increment high byte
btfss STATUS,C ; while low byte is > 0
goto Next
movwf HourL
incf HourH,F
goto Hourth
Next
clrf MinsH ; 初始化变量
movf Mins,W ; 转换&ldquo;分&rdquo;
movwf MinsL
Mtenth ; Loop to subtract 10
movlw .10 ; from low byte and
subwf MinsL,W ; increment high byte
btfss STATUS,C ; while low byte is > 0
goto Next1
movwf MinsL
incf MinsH,F
goto Mtenth
Next1
clrf SecsH ; 初始化变量
movf Secs,W ; 转换&ldquo;秒&rdquo;
movwf SecsL
Stenth ; Loop to subtract 10
movlw .10 ; from low byte and
subwf SecsL,W ; increment high byte
btfss STATUS,C ; while low byte is > 0
goto Over
movwf SecsL
incf SecsH,F
goto Stenth
Over
movlw 0x30 ;
addwf HourH,F ;
addwf HourL,F ; Add 0x30 ('0') to all
addwf MinsH,F ; variables to convert
addwf MinsL,F ; a number 0 - 9 to an
addwf SecsH,F ; ASCII equivalent
addwf SecsL,F ; '0' to '9'
return
;*====
DispTime
bcf STATUS,RP0
movlw 0c7h
call SendCmd
call Bin2BCa ; 调用二进制与bcd码转换子程序
movf HourH1,W ; 显示小时高位
call putcLCD ;
movf HourL1,W ; 显示小时低位
call putcLCD ;
movlw ':' ; 显示 ':'
call putcLCD
movf MinsH1,W ; 显示分钟高位
call putcLCD ;
movf MinsL1,W ; 显示分钟低位
call putcLCD ;
return
;*----
Bin2BCa
bcf STATUS,RP0
clrf HourH1 ; 初始化变量
movf Hour1,W ; 转换&ldquo;时&rdquo;
movwf HourL1
Hourth1 ; Loop to subtract 10
movlw .10 ; from low byte and
subwf HourL1,W ; increment high byte
btfss STATUS,C ; while low byte is > 0
goto Nexta
movwf HourL1
incf HourH1,F
goto Hourth1
Nexta
clrf MinsH1 ; 初始化变量
movf Mins1,W ; 转换&ldquo;分&rdquo;
movwf MinsL1
Mtenth1 ; Loop to subtract 10
movlw .10 ; from low byte and
subwf MinsL1,W ; increment high byte
btfss STATUS,C ; while low byte is > 0
goto Over1
movwf MinsL1
incf MinsH1,F
goto Mtenth1
Over1
movlw 0x30 ;
addwf HourH1,F ;
addwf HourL1,F ; Add 0x30 ('0') to all
addwf MinsH1,F ; variables to convert
addwf MinsL1,F ; a number 0 - 9 to an
return ; ASCII equivalent
;*******************************************************************
;* LCD 模块子程序 *
;*******************************************************************
;InitLCD&mdash;&mdash;初始化LCD模块 *
;*******************************************************************
InitLCD
bcf STATUS,RP0 ; Bank 0
bcf STATUS,RP1
clrf LCD_DATA ; 清 LCD 数据 & 控制位
bsf STATUS,RP0 ; Bank 1
movlw 0xc1 ; 设置RB1~RB5为输出
movwf LCD_DATA
bcf TRISA,5

bcf STATUS,RP0 ;
movlw 0x00 ;
movwf LCD_DATA
bsf LCD_CNTL2, E
bcf LCD_CNTL2, E

movlw 0x08 ;
movwf LCD_DATA
bsf LCD_CNTL2, E
bcf LCD_CNTL2, E
call LongDelay
call LongDelay

movlw b'00101000'
call SendCmd
movlw DISP_ON ; 开显示
call SendCmd
movlw ENTRY_INC ; 设置指针移动方式
call SendCmd
movlw DD_RAM_ADDR ; 设置起始地址
call SendCmd

InitLCDEnd ;
bcf STATUS,RP0 ;
movlw CLR_DISP ;
call SendCmd
return

;*******************************************************************
;*putcLCD&mdash;&mdash; 将字符数据送入 LCD *
;* 本程序将字符数据分成了高半字节和低半字节分别输入 *
;* 先送入的是高半字节 *
;*******************************************************************
putcLCD
bcf STATUS,RP0
movwf Byte ; 存 WREG 到 Byte 寄存器
swapf Byte,W ; 写入高半字节
movwf LCD_DATA1
rlf LCD_DATA1,1
rlf LCD_DATA1,1
movlw 0x3c
andwf LCD_DATA1,1
movf LCD_DATA1,w
movwf LCD_DATA
bsf LCD_CNTL1, RS ; 设置为送数据模式
bsf LCD_CNTL2, E ; 发送数据信号
bcf LCD_CNTL2, E

movf Byte,W ; 接着送低半字节
movwf LCD_DATA1
rlf LCD_DATA1,1
rlf LCD_DATA1,1
movlw 0x3c
andwf LCD_DATA1,1
movf LCD_DATA1,w
movwf LCD_DATA
bsf LCD_CNTL1, RS ; 设置为送数据模式
bsf LCD_CNTL2, E ; 发送数据信号
bcf LCD_CNTL2, E
call Delay
return

;*******************************************************************
;* SendCmd - 送命令到 LCD *
;* 本程序将命令数据分成了高半字节和低半字节分别输入 *
;* 先送入的是高半字节 *
;*******************************************************************
SendCmd
bcf STATUS,RP0
movwf Byte ; 存 WREG 到 Byte 寄存器
swapf Byte,W ; 送入命令的高字节
movwf LCD_DATA1
rlf LCD_DATA1,1
rlf LCD_DATA1,1
movlw 0x3c
andwf LCD_DATA1,1
movf LCD_DATA1,w
movwf LCD_DATA
bcf LCD_CNTL1,RS ; 设置为送命令模式
bsf LCD_CNTL2,E ; 发送数据信号
bcf LCD_CNTL2,E
movf Byte,W ; 接着送命令的低字节

movwf LCD_DATA1
rlf LCD_DATA1,1
rlf LCD_DATA1,1
movlw 0x3c
andwf LCD_DATA1,1
movf LCD_DATA1,w
movwf LCD_DATA
bcf LCD_CNTL1,RS ; 设置为送命令模式
bsf LCD_CNTL2,E ; 发送数据信号
bcf LCD_CNTL2,E
call Delay
return
;*******************************************************************
;* Delay - 延时子程序 *
;*******************************************************************
Delay ; call指令占用2个指令周期
bcf STATUS,RP0
clrf Count ; 清 Count占用1个指令周期
Dloop
decfsz Count,f ; 这两行指令将延时
goto Dloop ; (256 * 3) -1 个指令周期
return ; return占用2个指令周期

;*******************************************************************
;* LongDelay - 长延时子程序 *
;*******************************************************************
LongDelay
bcf STATUS,RP0
clrf Count
clrf Count1
movlw 0x03
movwf Count2
LDloop
decfsz Count,f
goto LDloop
decfsz Count1,f
goto LDloop
decfsz Count2,f
goto LDloop
return
;*------
END