📄 mcu.asm
字号:
mov KEYCODE,a ;按键键码暂存内存。
mov MENUINDEX,a ;当前主菜单序号。
mov ADCOUTCUR,a ;当前ADC转换的输出数值。
mov ADCOUTBAK,a ;前一次ADC转换的输出数值。
mov AUTOCOUNTER,a ;自动计数当前数值。
mov SINEINDEX,a ;当前正弦波采样索引序号。
mov FREQHIGH,a ;前一次测量频率高字节备份。
mov FREQLOW,a ;前一次测量频率低字节备份。
mov MILSTART,a ;毫秒表启动标志。
mov DS18B20HIGH,a ;DS18B20温度高字节。
mov DS18B20LOW,a ;DS18B20温度低字节。
mov COMINDEX,a ;串口发送索引值。
mov STATUS,#45h ;外部电设备状态。
;关闭扬声器,熄灭D15,马达全停,
;关闭继电器,AT89C52控制串口,
;处于测电压状态字。
mov RESERVED0,a ;保留。
mov MODEFLAG,a ;模式标志。
mov RETURNFLAG,a ;返回主程序标志。
mov DIVD4ADDRESS0,a ;4字节无符号除法子程序余数最高字节。
mov DIVD4ADDRESS1,a ;4字节无符号除法子程序余数次高字节。
mov DIVD4ADDRESS2,a ;4字节无符号除法子程序余数次低字节。
mov DIVD4ADDRESS3,a ;4字节无符号除法子程序余数最低字节。
mov DIVD4ADDRESS4,a ;4字节无符号除法子程序被除数最高字节。
mov DIVD4ADDRESS5,a ;4字节无符号除法子程序被除数次高字节。
mov DIVD4ADDRESS6,a ;4字节无符号除法子程序被除数次低字节。
mov DIVD4ADDRESS7,a ;4字节无符号除法子程序被除数最低字节。
mov DIVD4ADDRESS8,a ;4字节无符号除法子程序除数最高字节。
mov DIVD4ADDRESS9,a ;4字节无符号除法子程序除数次高字节。
mov DIVD4ADDRESSA,a ;4字节无符号除法子程序除数次低字节。
mov DIVD4ADDRESSB,a ;4字节无符号除法子程序除数最低字节。
mov DIVD4ADDRESSC,a ;没有使用,保留。
mov DIVD4ADDRESSD,a ;没有使用,保留。
mov DIVD4ADDRESSE,a ;没有使用,保留。
mov DIVD4ADDRESSF,a ;没有使用,保留。
mov RESULT1,a ;待显示的结果第1位。最多十五位,
;至少保留最后一位空终止符号。
mov RESULT2,a ;待显示的结果第2位。
mov RESULT3,a ;待显示的结果第3位。
mov RESULT4,a ;待显示的结果第4位。
mov RESULT5,a ;待显示的结果第5位。
mov RESULT6,a ;待显示的结果第6位。
mov RESULT7,a ;待显示的结果第7位。
mov RESULT8,a ;待显示的结果第8位。
mov RESULT9,a ;待显示的结果第9位。
mov RESULTA,a ;待显示的结果第10位。
mov RESULTB,a ;待显示的结果第11位。
mov RESULTC,a ;待显示的结果第12位。
mov RESULTD,a ;待显示的结果第13位。
mov RESULTE,a ;待显示的结果第14位。
mov RESULTF,a ;待显示的结果第15位。
mov RESULTNULL,a ;空终止符号。
call DISABLEINT0 ;屏蔽外部中断0。
call DISABLEINT1 ;屏蔽外部中断1。
clr TR0 ;关闭定时器0。
clr TR1 ;关闭定时器1。
clr EA ;关闭所有中端。
mov dptr,#8000h ;
mov a,#80h ;
movx @dptr,a ;命令自建元器件进入待机状态。
;此项功能为作者自定义功能,如果
;您自己编写程序,建议删去。如果
;您也想使用此项功能,可以查看压
;缩包内的“自定义协议.txt”这个
;文件。
mov dptr,#8100h ;外部电设备状态初始化。
mov a,STATUS ;
movx @dptr,a ;
mov dptr,#8400h ;数码管全灭。
mov a,#0FFh ;
movx @dptr,a ;
mov dptr,#8500h ;数码管全灭。
movx @dptr,a ;
mov dptr,#8600h ;LED全灭。
movx @dptr,a ;
ret ;
;;;;;;;;;;;;;;;;初始化子程序结束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;初始化LCD子程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;>>>>>>>>>>>>>>>资源占用报告>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>临时占用a
;>>>>>>>>>>>>>>>报告完毕>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
LCDINIT: mov a,#38h ;8位数据长度,双行,5x7字符。
call WRCMD ;调用写命令子程序。
mov a,#LCD_SETVISIBLE+7 ;开启显示屏,开启光标,光标所在
;字符闪烁。
call WRCMD ;调用写命令子程序。
mov a,#LCD_CLS ;
call WRCMD ;清屏。
mov dptr,#string0_1 ;
call WRSTR ;初始化LCD屏幕,显示第一行。
mov a,#LCD_SETDDADDR+64 ;换行。
call WRCMD ;
mov dptr,#string0_2 ;
call WRSTR ;初始化LCD屏幕,显示第二行。
ret ;
;;;;;;;;;;;;;;;;初始化LCD子程序结束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;读取按键子程序,只读一位,读到为止。;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;>>>>>>>>>>>>>>>资源占用报告>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>临时占用a,bank0区r0,r6,r7
;>>>>>>>>>>>>>>>报告完毕>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
READKEYPAD: mov r0,#00h ;按键初始值
;===============扫描第一列======================================================================
SCAN: mov a,#0EFh ;a=11101111b
mov p1,a ;配置p1口低四位为高电平,准备读取。注意,
;如果要从单片机的端口读取数据,必须先写
;1,使得端口内部处于高阻状态。配置p1.4为
;低电平,其余高3位为高电平,扫描第一列。
;如果第一列有按键按下,那么对应的端口位为
;高,其余保持低电平。请参考电路图,思考我
;为什么使用非门然后接入单片机?
jb p1.0,KEYIN ;按键0
inc r0 ;
jb p1.1,KEYIN ;按键1
inc r0 ;
jb p1.2,KEYIN ;按键2
inc r0 ;
jb p1.3,KEYIN ;按键3
inc r0 ;
;===============扫描第二列======================================================================
mov a,#0DFh ;
mov p1,a ;
jb p1.0,KEYIN ;按键4
inc r0 ;
jb p1.1,KEYIN ;按键5
inc r0 ;
jb p1.2,KEYIN ;按键6
inc r0 ;
jb p1.3,KEYIN ;按键7
inc r0 ;
;===============扫描第三列======================================================================
mov a,#0BFh ;
mov p1,a ;
jb p1.0,KEYIN ;按键8
inc r0 ;
jb p1.1,KEYIN ;按键9
inc r0 ;
jb p1.2,KEYIN ;按键小数点
inc r0
jb p1.3,KEYIN ;按键空格
inc r0 ;
;===============扫描第四列======================================================================
mov a,#7Fh ;
mov p1,a ;
jb p1.0,KEYIN ;按键回车
inc r0 ;
jb p1.1,KEYIN ;按键ESC
inc r0 ;
jb p1.2,KEYIN ;按键下箭头
inc r0 ;
jb p1.3,KEYIN ;按键上箭头
inc r0 ;
jmp READKEYPAD ;如果没有按键按下,返回继续扫描。
;===============如果有按键按下,去抖动,然后保存键值============================================
KEYIN: call DEBOUNCE ;软件延迟去抖动
mov a,r0 ;
mov KEYCODE,a ;
ret ;
;===============延迟约20ms======================================================================
DEBOUNCE: mov r6,#64h ;
D1: mov r7,#64h ;
D2: djnz r7,D2 ;
djnz r6,D1 ;
ret ;
;;;;;;;;;;;;;;;;读取按键子程序结束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;一组LCD操作的子程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;>>>>>>>>>>>>>>>资源占用报告>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>临时占用a,dptr,bank0区r0,r1,r2,r6,r7
;>>>>>>>>>>>>>>>报告完毕>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;===============写命令==========================================================================
WRCMD: mov p2,#87h ;选择LCD,关闭ADC的输出允许。
mov r0,#LCD_CMD_WR ;RS=0,RW=0写命令
movx @r0,a ;a保存所要写入的命令
jmp WTBUSY ;等待写操作完成
;===============等待写操作完成==================================================================
WTBUSY: mov r1,#LCD_BUSY_RD ;RS=0,RW=1读忙碌标志
movx a,@r1 ;将忙碌标志载入a中
jb acc.7,WTBUSY ;操作未完成等待
ret ;
;===============写字符串========================================================================
WRSTR: mov p2,#87h ;选择LCD,关闭ADC的输出允许。
mov r0,#LCD_DATA_WR ;RS=1,RW=0写数据
WRSTR1: clr a ;a保存所要写入的数据,先清零。
movc a,@a+dptr ;dptr保存所要写入字符串的首地址,空终止。
jz WRSTR2 ;如果当前所写入字符为零,结束写入过程。
movx @r0,a ;写入
call WTBUSY ;等待写操作完成
call LCDDELAY ;
inc dptr ;准备写入下一个字符
jmp WRSTR1 ;跳转
WRSTR2: ret ;
;===============写结果字符串====================================================================
WRRESULT: mov p2,#87h ;选择LCD,关闭ADC的输出允许。
mov r0,#LCD_DATA_WR ;RS=1,RW=0写数据
mov r1,#RESULT1 ;从地址RESULT1开始的16个字节保留作为
mov a,r1 ;结果缓冲区。
mov r2,a ;暂存r1。
WRRESULT1: mov a,r2 ;
mov r1,a ;恢复r1。
mov a,@r1 ;取得字符。
jz WRRESULT2 ;如果当前所写入字符为零,结束写入过程。
movx @r0,a ;写入
inc r1 ;指向下一个字符。
mov a,r1 ;
mov r2,a ;暂存r1。因为WTBUSY需要使用r1。
call WTBUSY ;等待写操作完成
call LCDDELAY ;调用延迟子程序,可选。
jmp WRRESULT1 ;跳转
WRRESULT2: ret ;
;===============字符显示的间隔==================================================================
LCDDELAY: mov r6,#80h ;
D3: mov r7,#80h ;
D4: djnz r7,D4 ;
djnz r6,D3 ;
ret ;
;;;;;;;;;;;;;;;;LCD操作的子程序结束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;按键判断子程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;>>>>>>>>>>>>>>>资源占用报告>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>临时占用a,dptr
;>>>>>>>>>>>>>>>报告完毕>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
MENUJUDGE: mov a,KEYCODE ;取得按键键值代码
;KEY 0=0 KEY 1=1 KEY 2=2 KEY 3=3
;KEY 4=4 KEY 5=5 KEY 6=6 KEY 7=7
;KEY 8=8 KEY 9=9
;KEY POINT=10 KEY SPACE=11
;KEY ENTER=12 KEY ESC=13
;KEY DOWN=14 KEY UP=15
cjne a,#0Eh,SUB1 ;如果按下DOWN键,转移至KEYDOWN。
jmp KEYDOWN ;否则转移至SUB1继续判断。
SUB1: cjne a,#0Fh,SUB2 ;如果按下UP键,转移至KEYUP。
jmp KEYUP ;否则转移至SUB2继续判断。
SUB2: cjne a,#0Ch,SUB3 ;如果按下ENTER键,写一个测试符串。
;该子程序返回后再转移至相应功能的
;子程序处。否则转移至SUB3继续判断。
mov dptr,#DEMO_1 ;写一个测试符串。
ret ;立即返回。
SUB3: mov a,MENUINDEX ;如果按下其它键,刷新屏幕,什么都
;不做返回。
mov dptr,#STRTABLE ;STRTABLE的每一个小段包含4个字节。
rl a ;a存储了功能序号,所以要乘以4。
rl a ;用左移2位实现乘以4操作。
jmp @a+dptr ;根据a的序号转移至STRTABLE的相应入口。
KEYDOWN: mov a,MENUINDEX ;如果按下DOWN键,先取得原先的功能序号。
dec a ;将序号减1。
cjne a,#0FFh,SUB4 ;如果原来的序号为0(也就是欢迎画面),
;那么减1后变为255,超出范围,必须恢复
;为最后一个画面(也就是结束画面)。
mov a,#0Dh ;修正数据。
SUB4: mov MENUINDEX,a ;将新的功能序号写回31号数据单元。
mov dptr,#STRTABLE ;
rl a ;
rl a ;
jmp @a+dptr ;
KEYUP: mov a,MENUINDEX ;如果按下UP键,先取得原先的功能序号。
inc a ;将序号加1。
cjne a,#0Eh,SUB5 ;如果原来的序号为13(也就是结束画面),
;那么加1后变为14,超出范围,必须恢复
;为第一个画面(也就是欢迎画面)。
mov a,#00h ;修正数据。
SUB5: mov MENUINDEX,a ;将新的功能序号写回31号数据单元。
mov dptr,#STRTABLE ;
rl a ;
rl a ;
jmp @a+dptr ;
STRTABLE: mov dptr,#string0_1 ;取得要显示的字符串的首地址。
;mov dptr指令占3个字节。
ret ;ret指令占1个字节,共4个字节。
mov dptr,#string1_1
ret
mov dptr,#string2_1
ret
mov dptr,#string3_1
ret
mov dptr,#string4_1
ret
mov dptr,#string5_1
ret
mov dptr,#string6_1
ret
mov dptr,#string7_1
ret
mov dptr,#string8_1
ret
mov dptr,#string9_1
ret
mov dptr,#string10_1
ret
mov dptr,#string11_1
ret
mov dptr,#string12_1
ret
mov dptr,#string13_1
ret
;;;;;;;;;;;;;;;;按键判断子程序结束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;菜单刷新子程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;>>>>>>>>>>>>>>>资源占用报告>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>临时占用a,dptr
;>>>>>>>>>>>>>>>报告完毕>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
MENUDISPLAY: mov a,#LCD_CLS ;dptr指示待写字符串首地址,空终止。
call WRCMD ;
call WRSTR ;
mov a,#LCD_SETDDADDR+64 ;
call WRCMD ;
inc dptr ;
call WRSTR ;
ret ;
;;;;;;;;;;;;;;;;菜单刷新子程序结束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;功能选择子程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;>>>>>>>>>>>>>>>资源占用报告>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>临时占用a,dptr
;>>>>>>>>>>>>>>>报告完毕>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
FUNCTIONSELECT: mov a,#0Fh ;
mov p1,a ;设定键盘为全扫描状态,任意键按下
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -