📄 1113752192.asm
字号:
;************************************************
;* 说明:这只是一个程序构架,您应按此构架的提示 *
;* 合理添加程序,以使其正常运行。 *
;************************************************
;************************************************
;* 接着LAB5,我们将在LAB6为时钟加上时间调整功能 *
;************************************************
include <p16f877.inc>
; 定义 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 ; 初始化第二行显示的操作数
;
;**************************************
; 请设置显示相关寄存器 *
;**************************************
Byte RES 1
Count RES 1
Count1 RES 1
Count2 RES 1
LCD_DATA1 RES 1
;**************************************
Secs res 1
Mins res 1
Hour res 1
SecsH res 1
SecsL res 1
MinsH res 1
MinsL res 1
HourH res 1
HourL res 1
_WREG res 1
_STATUS res 1
;**************************************
ORG 0
GOTO Start
org 4 ;中断入口
goto INTDISP ;中断处理
org 10
Start
clrf Secs ; 初始化变量
clrf Mins
call InitLCD ; 初始化 LCD
;*************************************************
;*提示:将code0替换成你的程序,依次完成以下功能: *
;* - 初始化 Timer1 的值为 8000h *
;* - 设置 Timer1 *
;* - 预分频 1:1 *
;* - 使能晶振 *
;* - 将其时钟源定义为外部时钟 *
;* - 启动 Timer1 *
;* - 清 Timer1 溢出中断标志 *
;* - 开 Timer1 溢出中断 *
;* - 开外部中断 *
;* - 开总中断 *
;*************************************************
code0
call InitDisplay ; 初始化LCD显示
;**************************************************
;* 提示:将code1替换成你的程序,依次完成以下功能: *
;* - 初始化 A/D 转换器 *
;* - 设置转换速率为Fosc/8 *
;* - 选定通道2 *
;* - A/D使能 *
;* - 设定 PORTE,0 脚电平为1 *
;* - 设定 PORTE,0 脚为输出 *
;**************************************************
code1
Main
;**************************************************
;* 提示:将code2替换成你的程序,依次完成以下功能: *
;* - 判断程序是否跳转 *
;* - 启动 A/D 转换 *
;* - 等待转换完成 *
;* - 将转换所得数据与设定值比较 *
;* - 如果大于设定值 *
;* - 使 RE0 输出电平关闭背光 *
;* - 如果小于设定值 *
;* - 使 RE0 输出电平开启背光 *
;**************************************************
code2
goto Main
INTDISP
Push
movwf _WREG ; 存 WREG状态
swapf STATUS,W ; 存 STATUS
movwf _STATUS
;**************************************************
;* 提示:将code3替换成你的程序,依次完成以下功能: *
;* %% 判断中断类型 *
;* -如果是A/D转换完成中断: *
;* -清ADIF位 *
;* -事件处理 *
;*------------------------------------------------*
;* -如果是Timer1溢出中断: *
;* - 清 Timer1 溢出中断标志 *
;* - 将 80h 写入 TMR1H *
;* - Secs寄存器加1 *
;* - 如果 Secs = 60 (十进制数)则: *
;* - 清 Secs寄存器 *
;* - Mins寄存器加1 *
;* -如果 Mins=60 (十进制数)则: *
;* -清 Mins寄存器 *
;* -Hour寄存器加1 *
;* -如果 Hour=24 (十进制数)则: *
;* -清Hour寄存器 *
;* - 调用 DisplayTime 更新 LCD 显示 *
;*------------------------------------------------*
;* -如果是RTCC中断: *
;* -清标志位 *
;* -事件处理 *
;*------------------------------------------------*
;* -如果是INT中断: *
;* -清标志位 *
;* -事件处理 *
;**************************************************
code3
;************************************************
Pop
swapf _STATUS,W ; Restore STATUS
movwf STATUS
swapf _WREG,F ; Restore WREG w/o
swapf _WREG,W ; affecting STATUS
retfie
;*************************************************
;* DisplayTime - 将显示指针移至第一行,调用Bin2BCD*
;* 子程序将Secs 和 Mins寄存器内的数据转换为相应的*
;* ASCII 码, 然后送 LCD显示. *
;*************************************************
DisplayTime
call L1homeLCD ; 显示指针定位在第一行
call Bin2BCD ; 调用二进制与bcd码转换子程序
movf HourH,W ; 显示小时高位
call putcLCD ;
movf HourL,W ; 显示小时低位
call putcLCD ;
movlw ':' ; 显示 ':'
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
clrf HourH ; 初始化变量
movf Hour,W ; 转换“时”
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 ; 转换“分”
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 ; 转换“秒”
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
;************************************************
;* InitDisplay - 初始化LCD 显示为 00:00 *
;************************************************
InitDisplay
bcf STATUS,RP0
bcf STATUS,RP1
call clrLCD ; 清显示
movlw '0' ; 显示 00:00:00
call putcLCD
movlw '0'
call putcLCD
movlw ':'
call putcLCD
movlw '0'
call putcLCD
movlw '0'
call putcLCD
movlw ':'
call putcLCD
movlw '0'
call putcLCD
movlw '0'
call putcLCD
return
;*******************************************************************
;* LCD 模块子程序 *
;*******************************************************************
;InitLCD——初始化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
;bsf 9fH,2 ; 设置RA5为数据口
bcf STATUS,RP0 ;
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 ;
call clrLCD
return
;*******************************************************************
;*putcLCD—— 将字符数据送入 LCD *
;* 本程序将字符数据分成了高半字节和低半字节分别输入 *
;* 先送入的是高半字节 *
;*******************************************************************
putcLCD
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
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
;*******************************************************************
;* clrLCD - 清除 LCD 显示 *
;*******************************************************************
clrLCD
movlw CLR_DISP ;
call SendCmd
return
;*******************************************************************
;* L1homeLCD - 将显示指针定位在第一行 *
;*******************************************************************
L1homeLCD
movlw DD_RAM_ADDR ;
call SendCmd ;
return
;*******************************************************************
;* L2homeLCD - 将显示指针定位在第二行 *
;*******************************************************************
L2homeLCD
movlw DD_RAM_UL ;
call SendCmd ;
return
;*******************************************************************
;* Delay - 延时子程序 *
;*******************************************************************
Delay ; call指令占用2个指令周期
clrf Count ; 清 Count占用1个指令周期
Dloop
decfsz Count,f ; 这两行指令将延时
goto Dloop ; (256 * 3) -1 个指令周期
return ; return占用2个指令周期
;*******************************************************************
;* LongDelay - 长延时子程序 *
;*******************************************************************
LongDelay
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
;****************************************************
;Written by : Yamato Tel:0591-3375855-721 *
;****************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -