?? 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 + -