硬件:AT89s52开发板(含4x4数字键盘)
功能: 用按键选择不同频率方波,由P1.0输出方波音频信号
作者:Kxuan163
汇编语言源程序如下:
;;--------------------------------------------
ORG 0000H
AJMP MAIN
;;--------------------------------------------
ORG 001BH ;定时器T1中断处理入口地址
AJMP T1_INT
;;--------------------------------------------
ORG 0030H ;主程序入口地址
MAIN: MOV SP,#60H
MOV 30H,#16 ;开机/复位显示“-”,16是段码表"-"偏移址
LOOP1: CALL KEY_SCAN ;扫描键盘
CALL KEYPLAER ;显示按键数字
;;CLR P1.0 ;令输出的初始状态为低电平
MOV A, 30H ;按键顺序号送至A
CJNE A, #16, OnKeyJmp ;若有按键,依键号跳转某程序段
JMP LOOP1 ;若无按键,继续扫描键盘
OnKeyJmp: RL A ;每条AJMP指令占2字节,按键顺序号x2
MOV DPTR, #JmpTab ;散转表首址送DPTR
JMP @A +DPTR ;依按键散转
JmpTab: AJMP LOOP1 ;按0键,
AJMP OUT100 ;按1键,输出100Hz方波
AJMP OUT200 ;按2键,输出200Hz方波
AJMP OUT300 ;按3键,输出300Hz方波
AJMP OUT400 ;按4键,输出400Hz方波
AJMP OUT500 ;按5键, 输出500Hz方波
AJMP OUT600 ;按6键, 输出600Hz方波
AJMP LOOP1 ;按7键,
AJMP LOOP1 ;按8键,
AJMP LOOP1 ;按9键,
AJMP LOOP1 ;按A键,
AJMP LOOP1 ;按b键,
AJMP LOOP1 ;按C键,
AJMP LOOP1 ;按D键,
AJMP LOOP1 ;按E键,
AJMP LOOP1 ;按F键,
;;---------------------------------------------
KEY_SCAN: MOV P1,#0F0H ;置列线为0,行线为1
MOV A,P1
ANL A,#0F0H
MOV B,A
MOV P1,#0FH ;置列线为1,行线为0
MOV A,P1
ANL A,#0FH
ORL A,B ;高四位与低四位重新组合
CJNE A,#0FFH,KEY_IN1 ;0FFH为末按键
RET
KEY_IN1: MOV B,A
MOV DPTR,#KEYTABLE
MOV R3,#0FFH ;
KEY_IN2: INC R3 ;顺序码加1
MOV A,R3
MOVC A,@A+DPTR
CJNE A,B,KEY_IN3
MOV A,R3 ;找到,取顺序码
MOV 30H,A ;送显示
RET
KEY_IN3: CJNE A,#00H,KEY_IN2 ;末完,继续查
RET ;00H为结束码
;;-------------------------------------------
KEYPLAER: MOV R3, 30H
MOV A, 30H
MOV DPTR,#TABLE ;取段码表地址
MOVC A,@A+DPTR ;查显示数据对应段码
MOV P0,A ;段码放入P0口
CLR P2.7 ;最右数码管亮
RET
;;--------------------------------------------
;定时器T1预装计数初值的计算:
;机器周期 =12/Fosc =12/(11.0592MHz) =1.08506944μs ≈1μs
;100Hz的半周期=(1/100)/2=5ms, 计数初值=65536-5000=60536=EC78h
;200Hz的半周期=(1/200)/2=2.5ms, 计数初值=65536-2500=63036=F63Ch
;300Hz的半周期=(1/250)/2=1.667ms,计数初值=65536-1667=63869=F97Dh
;400Hz的半周期=(1/400)/2=1.25ms, 计数初值=65536-1250=64286=FB1Eh
;500Hz的半周期=(1/500)/2=1ms, 计数初值=65536-1000=64536=FC18h
;600Hz的半周期=(1/600)/2=0.833ms,计数初值=65536-0833=64703=FCBFh
;;--------------------------------------------
OUT100: MOV R3,#0ECh ;;T1初值高8位
MOV R4,#78h ;;T1初值低8位
AJMP SET_T1 ;;T1初始化
;;--------------------------------------------
OUT200: MOV R3,#0F6h
MOV R4,#3Ch
AJMP SET_T1
;;--------------------------------------------
OUT300: MOV R3,#0F9h
MOV R4,#7Dh
AJMP SET_T1
;;--------------------------------------------
OUT400: MOV R3,#0FBh
MOV R4,#1Eh
AJMP SET_T1
;;--------------------------------------------
OUT500: ;;P1.0输出500Hz方波
MOV R3,#0FCh
MOV R4,#18h
AJMP SET_T1
;;--------------------------------------------
OUT600: ;;P1.0输出600Hz方波
MOV R3,#0FCh
MOV R4,#0BFh
AJMP SET_T1
;;--------------------------------------------
SET_T1: ;; T1初始化:
MOV TMOD, #00010000b ;; T1,定时模式,方式1,16位计数器
MOV TH1, R3 ;; 装入计数初值高字节
MOV TL1, R4 ;; 装入计数初值低字节
SETB TR1 ;; 启动T1
SETB ET1 ;; 允许T1中断
SETB EA ;; CPU开中断
SJMP $ ;; 等待T1中断
;;--------------------------------------------
T1_INT: ;; 定时器T1中断处理程序
CPL P1.0 ;; 电平反转,进入方波另半周期
MOV TH1, R3 ;; 重装初值高8位
MOV TL1, R4 ;; 重装初值低8位
RETI
;;--------------------------------------------
DLY1ms: MOV R6,#5 ;视觉暂留延时1ms
MOV R7,#100
DLY1msB: DJNZ R7,$
DJNZ R6,DLY1msB
RET
;; 5x100x2(1μs) =1000μs =1ms
;;--------------------------------------------
DLY2s: ;延时2000ms =2s
MOV R7,#16
DLY2sA: MOV R6,#250
DLY2sB: MOV R5,#250
DJNZ R5,$
DJNZ R6,DLY2sB
DJNZ R7,DLY2sA
RET
;; 16x250*250*2(1μs) =2000 0000μs =2s
;;--------------------------------------------
KEYTABLE: DB 0EEH,0EDH,0EBH,0E7H,0DEH ;0,1,2,3,4, 顺序码
DB 0DDH,0DBH,0D7H,0BEH,0BDH ;5,6,7,8,9,
DB 0BBH,0B7H,07EH,07DH,07BH ;A,B,C,D,E,
DB 077H,00H ;F, 00为结束码
;;---------------------------------------------
;;共阳极数码段码表:
;;字符 0 1 2 3 4 5 6 7
TABLE: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H
;;------------------------------------------
;;字符 8 9 A b C d E F 中横 上横 下横
DB 80H,90H,88H,83H,0C6H,0A1H,86H,8EH,0BFH,0FEH,0F7H
;;--------------------------------------------
;;字符 . P U Γ Y 8. "灭" Π L J
DB 7FH,82H,0C1H,0CEH,91H,00H,0FFH,0C8H,0C7H,0F1H
;;--------------------------------------------
END ;主程序结束
|