📄 slavr748.asm
字号:
;用AT90S8535作0-7通道A/D转换,用LED显示,左一位(D5)显示通道号,
;右三位(D2-D0)显示转换值(十六进制数0-3FFH),程序下载即执行,
;自动从0通道到7通道A/D转换扫描显示,当你按下0-7任一位数字键,
;该通道显示时间延长一段时间,然后又自动循环显示。
;本程序在SL-AVR上调试通过。
;硬件接口: AT90S8535的PB.0-7接LED段显示(用短路块短接),PD.0-5接LED位显示,用接插线连接,
;PC0-PC7接键盘线
;PA.0-7接模拟电压,滑线电位器A/D VX端,
;AGND接地
;AVCC与VRBF间接1K电阻,VRBF到地接100μF电解电容,
;AVC与VCC间接一只100Ω电阻,AVCC接104瓷片电容到地,
;/RST接上复位按钮,插上CZ2到AT4下载线,即连通晶振引脚线,
.include "8535def.inc"
.org $0000
rjmp reset
.def TEMP =r16
.def TEMP1 =r17
.def temp2 =r18
.def temp3 =r19
.def CNT =r20
.def scndp =r21
.def KSNI =r22
.def SCNN =r23
.def KEYN =r24
.def temp4=r25
.equ label =$0f00
.org 0030
reset: ldi temp,high(ramend);设置堆栈指针.
out sph,temp
ldi temp,low(ramend)
out spl,temp
clr xh ;设置x指针为$0061.
ldi xl,$61
clr temp ;清$0061,$0062单元.
st x+,temp
st x,temp
init: clr temp2 ;由0通道开始.
next: ldi temp3,$01
next1: clr temp4
again: rcall cance ;调用a/d转换子程序cance.
lp: rcall scan1 ;调用键扫显示子程序scan1.
scann: rcall scan1
brtc recog ;用按键转recog.
inc temp4 ;键扫显示次数temp4加1.
cpi temp4,$ff
brne again ;temp4不等于$ff转again.
dec temp3
brne again ;temp3不等于0转again.
inc temp2 ;通道代码temp2加1.
cpi temp2,$08
brne next ;8个通道未结束转下一通道next.
rjmp init ;8个通道巳扫描完再重扫.
recog: cpi keyn,$08
brcc next ;无效键转next.
ldi temp3,$04 ;设置有效通道键按下后的循环次数.
mov temp2,keyn ;通道数送temp2.
rjmp next1
cance: mov temp,temp2 ;a/d转换子程序.
out admux,temp ;设置通道.
ldi temp,$86 ;设置a/d转换使能且采用1/64分频作转换工作频率.
out adcsr,temp
sbi adcsr,adsc ;启动转换.
loop: sbic adcsr,adsc ;转换结束跳行否则等待.
rjmp loop
in r2,adcl ;把转换结果送r2.r3.
in r3,adch
mov temp,temp2
rcall wrdisram ;调用把转换的结果转换成显示代码wrdisram.
ret ;转换结束返回.
wrdisram:clr xh ;使x指针为$0060.
ldi xl,$60
rcall fetch ;调用fetch.
st x+,temp ;把temp存入$0060单元.
inc xl
inc xl
mov temp,r3
andi temp,$0f ;取r3的低4位.
rcall fetch ;取字形代码.
st x+,temp
mov temp,r2
swap temp
andi temp,$0f ;取r2的高4位.
rcall fetch ;取字形代码.
st x+,temp
mov temp,r2
andi temp,$0f ;取r2的低4位.
rcall fetch ;取字形代码.
st x+,temp
ret ;返回.
fetch: ldi zh,high(label*2);设置字形表指针z.
mov zl,temp
lpm ;取字形.
mov temp,r0 ;字形码送temp.
ret ;返回
SCAN1: push xh ;键扫显示子程序。
PUSH XL ;将xl压入堆栈
PUSH TEMP3
PUSH TEMP2
PUSH TEMP1
PUSH TEMP
lDI XL,$60
SET ;T标志为1表示未按键
LDI SCNN,$00 ;按键起始扫描码SCNN为00
LDI SCNDP,0B11011111 ;令6位七段LED扫描显示码初始为11011111
LDI CNT,$06 ;七段LED共6位故CNT=6为位数计数
LDI KSNI,0B11110111 ;4*4键盘扫描码KSNI初始为11110111
COL1: LDI TEMP,$FF ;PORTB设定为输出
OUT DDRb,TEMP
OUT DDRC,TEMP ;PORTC设定为输出
OUT PORTC,TEMP
OUT DDRd,TEMP ;PORTD设定为输出
OUT PORTd,SCNDP ;6位七段LED扫描显示码输出到PORTD
CLR XH
LD R1,X+ ;要显示于七段LED的间接寄存器X中的内容送入R1并令X加1
OUT PORTb,R1 ;显示内容输出到PORTB以驱动LED显示
RCALL DELAY ;调用延时以显示此位数一段时间
MOV TEMP,CNT ;LED位数为6而按键码行数为4故需作CNT值检测
SUBI TEMP,$03 ;CNT=TEMP与3相减比较
BRCS NOSK ;位数扫描CNT超过3则C为1跳到NOSK不作按键处理
LDI TEMP1,$04 ;一共要检查4个按键
LDI TEMP,0B00001111 ;设定PC0-PC3为输出PC4-PC7为输入
OUT DDRc,TEMP
OUT PORTc,KSNI ;KSNI输出到PORTC并令PC7-PC4为上拉电阻输入态
RCALL DELYT ;调用延时以稳定读取键盘I/O输入端
IN TEMP,PINc ;读取C口检测PC7-PC4看是否有按键低电位输入
ANDI TEMP,0B11110000 ;取TEMP的高4位
SWAP TEMP ;键码顺序为PC4-PC7故将TEMP的高低4位互换成D0-D3
KROW: SEC ;令C标志为1以便将键盘码D0-D3移到C标志位检测
ROR TEMP ;TEMP的内容右移1位将第一个键码D0=PC4移到C标志位检测
BRCS NOKEY ;若有键按下则测到PC4=D0=0,若C=1无按键则转到NOKEY
CLT ;若PC4=D0=CF=0表示有按键令T=0表示有按键
MOV KEYN,SCNN ;把按键扫描码SCNN送键码KEYN中保存
SBIS PINd,$07
ADIW KEYN,$10 ;判定SHIFT键是否按下,按下则键值加10
NOKEY: INC SCNN ;按键扫描码SCNN加1
DEC TEMP1 ;扫描读取键数TEMP1减1
BRNE KROW ;每行有4个按键如TEMP1不为0则跳到KROW再检测PC5-PC7
SEC ;此行4个键码检测完后令C为1以方便键盘扫描码KSNI内容的移位
ROR KSNI ;键盘扫描码KSNI=CF=1>11110111移位以进行下一行按键扫描
NOSK: SEC ;令进位标志CF=1
ROR SCNDP ;将扫描显示码SCNDP左移作下一位扫描
DEC CNT ;共需作6位数扫描显示故CNT减1
BRNE COL1 ;CNT减1不为0则跳回COL1再作扫描显示及读取键盘输入
LDI TEMP,$FF ;若已完成全部扫描显示和读取按键则令TEMP=0ff
OUT DDRC,TEMP ; TEMP输出到DDRC设定PORTC为输出驱动LED
OUT PORTC,TEMP
POP TEMP
POP TEMP1
POP TEMP2
POP TEMP3
POP XL
pop xh
RET
delay: push temp1
push temp3
ldi temp1,$10
dt11:ldi temp3,$20
dt21:nop
dec temp3
brne dt21
dec temp1
brne dt11
pop temp3
pop temp1
ret
delyt: ldi temp3,$20
dt31:dec temp3
brne dt31
ret
.cseg
.org $0f00
.dw 0x063f,0x4f5b,0x6d66,0x077d
.dw 0x6f7f,0x7c77,0x5e39,0x7179
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -