小测试!
此程序在wave下能通过编译,看谁能在此程序找出最多逻辑错误!
; 8052 8通道扫描转换,温度采集控制程序
;
;
;20h 扫描通道
;21h 正在操作的扫描通道
;22h.0 显示通道1
;22h.1 显示通道2
;22h.2 显示通道3
;22h.3 显示通道4
;22h.4 收到发送标志
;22h.5 收到第一帧
;23h.0 全速扫描
;23h.1 0.5s
;23h.2 1s
;23h.3 5s
;23h.4 允许显示
;23h.5 发送允许
;23h.6 温度采集控制标志
;30h 显示通道1的数据
;31h 显示通道2的数据
;32h 显示通道3的数据
;33h 显示通道4的数据
;34h 显示计数
;35h 延时计数,即delay1ms调用次数
;36h 当前采集的数据
;37h 用于加在adc0809上的采集通道地址
;r3 显示时间控制
;r5 r4 计数标志
;r6做为模拟转换的地址位
;10100101 ----发送标志 a5h
;01111000-----电压采集控制标志 78h
;00011110-----温度控制标志 1eh
;11110000 00001111-----发送出错 f00fh
;关闭除串行口以外的中断
org 0000h
ljmp main
org 0003h
reti
org 000bh
reti
org 0013h
reti
org 001bh
reti
org 0023h
ljmp comr;串行中断跳转
;
;
; 初始化ram,串行模式,计数器t1模式
;
;
org 100h
main:
clr a
mov p2,a ;p1为0
mov 21h,a
mov 22h,a
mov 23h,a
mov 30h,a
mov 31h,a
mov 32h,a
mov 33h,a
mov 34h,a
mov 35h,a
mov 36h,a
mov 37h,a ;设置当前采集通道地址为00h
mov a,#0ffh
mov p0,a ;p0,p1,p2为ffh
mov p1,a
mov p2,a
mov 20h,a ;20h,采集通道标志全为一
setb 21h.0 ;设置当前采集通道为第一通道
setb 23h.2 ;每一通道的采集时间间隔为1
setb 23h.4 ;允许显示
mov pcon,#00h ;smod为0
mov tmod,#20h ;t1计数模式为8位再装入
mov scon,#50h ;通讯方式1,允许中断
mov th1,#0fdh ;设通讯波特率为9600bit/s
mov tl1,#0fdh
setb tr1 ;启动计时器t1
setb ea ;启用中断
setb es ;启用串行口中断
;
;
; 主程序
;
;
start:
jb 23h.6,start
lcall test ;采集当前通道
lcall nextq ;转向下一通道
lcall send ;发送数据
lcall senddelay ;延时
lcall display ;显示
ajmp start
;
;
; 采集子程序
;
;
test:
mov a,37h ;取采集地址
mov p2,a ;送到p2,将地址加载到adc0809
setb p2.3 ;地址锁存
nop
nop
clr p2.3 ;
setb p2.4 ;转换开始
nop
nop
clr p2.4 ;
nop
nop
nop
nop
wait: jb p3.7,movd ;等待结束
ajmp wait ;
movd: setb p2.5 ;输出允许
mov a,p0 ;取数据
mov 36h,a ;送到36h
clr p2.5 ;关闭输出
clr a ;
mov p2,a ;结束转换,复原 p0 p1 p2 p3
mov a,#0ffh
mov p1,a
mov p0,a
mov p3,a
ret
;
;
; 取下一位采集地址
;
;
nextq:
jb 21h.0,nq1 ;取当前采集通道
jb 21h.1,nq2
jb 21h.2,nq3
jb 21h.3,nq4
jb 21h.4,nq5
jb 21h.5,nq6
jb 21h.6,nq7
jb 21h.7,nq0
ljmp main ;没有当前采集通道,出错返回
nq1:
inc 37h ;先加1
jnb 20h.1,nq2 ;如果1通道不用采集,跳转到2通道,检测状态
mov 21h,#00h ;清除0通道标志
setb 20h.1 ;设置1通道标志
ret
nq2:
inc 37h
jnb 20h.2,nq3
mov 21h,#00h
setb 21h.2
ret
nq3:
inc 37h
jnb 20h.3,nq4
mov 21h,#00h
setb 21h.3
ret
nq4:
inc 37h
jnb 20h.4,nq5
mov 21h,#00h
setb 21h.4
ret
nq5:
inc 37h
jnb 20h.5,nq6
mov 21h,#00h
setb 21h.5
ret
nq6:
inc 37h
jnb 20h.6,nq6
mov 21h,#00h
setb 21h.6
ret
nq7:
inc 37h
jnb 20h.7,nq0
mov 21h,#00h
setb 21h.0
ret
nq0: mov 37h,#00h
jnb 20h.1,nq1
mov 21h,#00h
setb 21h.0
ret
;
;
; 发送数据
;
;
send:
jb 23h.5,sende ;如果允许发送,跳转到sende执行
ret
sende:
clr ren ;禁止接收
mov a,21h ;取当前通道
mov sbuf,a ;送到sbuf发送
waits1:
jnb ti,waits1 ;等待结束
clr ti ;
mov a,36h ;取当前采集的数据
waits2:
jnb ti,waits2
clr ti
setb ren ;允许接收
ret
;
;
; 发送之后的延时
;
;
senddelay:
jnb 23h.4,delayt ;如果允许显示,则不延时
ret
delayt:
jnb 23h.0,sd1
mov 35h,#01h
sjmp sd
sd1:
jnb 23h.1,sd2
mov 35h,#0ch
sjmp sd
sd2:
jnb 23h.2,sd3
mov 35h,#19h
sjmp sd
sd3:
jnb 23h.3,errordplay
mov 35h,#7ch
sd:
lcall delay1ms
djnz 35h,sd
ret
;
;
; 显示子程序
;
;
display:
jnb 23h.0,pt11 ;全速扫描,不显示
ret
pt11:
jnb 23h.1,pt2 ;0.5秒间隔
mov 35h,#0ch ;设置显示循环次数
sjmp ep
pt2:
jnb 23h.2,pt3 ;1秒间隔
mov 35h,#19h
sjmp ep
pt3:
jnb 23h.3,errordplay;五秒间隔,如果全部标志位没有数据,出错返回
mov 35h,#7ch
ep: mov a,36h ;取当前的采集数据
mov b,#100
div ab
mov 33h,a
mov a,#10
xch a,b
div ab
mov 32h,a
mov 31h,b
jnb 21h.0,dq1 ;置采集通道数
mov 30h,#00h
sjmp play
dq1:
jnb 21h.1,dq2
mov 30h,#01h
sjmp play
dq2:
jnb 21h.2,dq3
mov 30h,#02h
sjmp play
dq3:
jnb 21h.3,dq4
mov 30h,#03h
sjmp play
dq4:
jnb 21h.4,dq5
mov 30h,#04h
sjmp play
dq5:
jnb 21h.5,dq6
mov 30h,#05h
sjmp play
dq6:
jnb 21h.6,dq7
mov 30h,#06h
sjmp play
dq7:
jnb 21h.7,errordplay
mov 30h,#07h
sjmp play
errordplay:
ljmp main
play:
mov 34h,#04h
mov r0,#30h
mov r1,#0dfh ;用于p2口确定显示通道
play1:
mov a,@r0
mov dptr,#tab
movc a,@a+dptr;取显示数据
mov p1,a ;显示
mov a,r1
mov p3,a ;开启显示
lcall delay1ms
inc r0 ;指向下一位显示
mov r1,a
rr a
mov r1,a ;r1右移一位
djnz 34h,play1;如果没有显示完四位数码管,跳转显示
djnz 35h,play;循环显示
mov a,#0ffh
mov p2,a
clr a
mov p1,a
ret
tab: dw 0c0ch,0f9h,0a04h,0b0h,99h,92h,82h,0f8h,80h,90h,0ffh
;
;
; 延时1ms的子程序
;
;
delay1ms: mov r5,#14h
dl1: mov r6,#19h
dl2: djnz r6,dl2
djnz r5,dl1
ret
;
;
; 串口子程序
;
;
comr: clr es ;停止串行口中断
clr ri ;清除接收标志
mov a,sbuf ;取出数据
cjne a,#0a5h,serror ;并非发送标志
mov sbuf,a ;返回a5h
wait1: jnb ti,wait1 ;等待发送成功
clr ti
mov r5,#0ffh ;循环次数,等待计算机发送下一数据
wait2: djnz r5,wait3
sjmp serror ;如果在循环内没有接到数据返回
wait3: nop
nop
nop
jnb ri,wait2
mov a,sbuf ;取数据
clr ri ;清除接收标志
cjne a,#1eh,voltage ;与温度采集标志比较
temperature: setb 23h.6 ;温度采集程序
mov 37h,#00h ;送采集地址#00h到37h
lcall test ;采集数据
mov a,36h ;发送
mov sbuf,a
waitt1: jbc ti,waitt1
mov r5,#0ffh
waitt2: lcall delay1ms
jbc ri,step2 ;等待结果
djnz r5,waitt2
step2: mov a,sbuf ;如果是ffh,则输出加温标志
cjne a,#0ffh,down
setb p2.0
down: clr p2.0
reti
voltage: cjne a,#78h,serror ;如果与电压采集标志也不一样,出错
mov r5,#0ffh ;循环次数,等待计算机发送下一数据
wait4: djnz r5,wait5
sjmp serror ;如果在循环内没有接到数据返回
wait5: nop
nop
nop
jnb ri,wait4
clr ri
mov a,sbuf
clr 23h.6 ;清除温度采集标志
mov 20h,a ;将采集通道数据送往20h
mov sbuf,a ;返回a
wait6: jnb ti,wait6
clr ti
mov r5,#0ffh
wait7: djnz r5,wait8;等待下一数据
sjmp serror
wait8: nop
nop
nop
jnb ri,wait7
mov a,sbuf
clr ri
mov 23h,a ;将采集时间送往23h
mov sbuf,a ;返回a
wait9: jnb ri,wait9
lcall setq ;设置当前采集通道地址
clr ri
setb es
reti
serror: mov sbuf,#0f0h;出错,发送两侦错误侦
wait10: jbc ti,wait10
mov sbuf,#00fh
wait11: jbc ti,wait11
setb es
reti
setq: jnb 21h.0,setq1;设置当前采集通道地址
mov 37h,#00h
ret
setq1: jnb 21h.1,setq2
mov 37h,#01h
ret
setq2: jnb 21h.2,setq3
mov 37h,#02h
ret
setq3: jnb 21h.3,setq4
mov 37h,#03h
ret
setq4: jnb 21h.4,setq5
mov 37h,#04h
ret
setq5: jnb 21h.5,setq6
mov 37h,#05h
ret
setq6: jnb 21h.6,setq7
mov 37h,#06h
ret
setq7: jnb 21h.7,seterror
mov 37h,#07h
ret
seterror: ljmp main
end
发表时间:2003年11月14日18:41:16