;设计一个单片机抢答控制器
;要求:
;P3.0口的按键按下后,数码管显示十秒倒计时;
;在十秒钟之内,当四个抢答按键按下后,数码管显示对应组号,对应指示灯亮;
;倒计时十秒结束时,恢复初始状态,不能抢答。
;并且每个键按下都有声音提示。
;电路图,做而论道简化了一些,如下:
;插图链接:
;http://xiangce.baidu.com/picture/detail/008c61156b196044c5aadfba254a30294b862671
;题目链接:
;http://zhidao.baidu.com/question/555205809.html
;提问者留言:
;13476684571 2013-6-1 17:35
;谢谢你了,你的答案解决了我的问题,不过采纳答案的时候点错了,不好意思
;
;做而论道设计的程序如下:
;------------------------------------------
ORG 0000H
LJMP START
ORG 000BH
LJMP T0_INT
ORG 0040H
START:
MOV TMOD, #01H
MOV TH0, #(65536-50000) / 256
MOV TL0, #(65536-50000) MOD 256
MOV IE, #82H
MOV P1, #0FFH ;LED
MOV P2, #0FFH ;数码管
JB P3.0, $ ;等待开始
MOV P2, #90H
MOV R5, #20
MOV R4, #10
SETB TR0
CALL BEEP
AGAIN:
JNB P1.0, X1
JNB P1.1, X2
JNB P1.2, X3
JNB P1.3, X4
JB TR0, AGAIN
SJMP START
;------------------------
X1: ANL P1, #0EFH
MOV P2, #0F9H
SJMP XXX
X2: ANL P1, #0DFH
MOV P2, #0A4H
SJMP XXX
X3: ANL P1, #0BFH
MOV P2, #0B0H
SJMP XXX
X4: ANL P1, #7FH
MOV P2, #99H
XXX:CLR TR0
CALL BEEP
JB P3.0, $ ;等待清零
CALL BEEP
JNB P3.0, $ ;等待释放
SJMP START
;------------------------
BEEP:
DJNZ R7, $
CPL P3.1
DJNZ R6, BEEP
SETB P3.1
RET
;------------------------
T0_INT:
MOV TH0, #(65536-50000) / 256
MOV TL0, #(65536-50000) MOD 256
DJNZ R5, T0_END
MOV R5, #20
MOV A, R4
DEC A
DEC A
MOV DPTR, #TAB
MOVC A, @A + DPTR
MOV P2, A
DJNZ R4, T0_END
CLR TR0
T0_END:
RETI
TAB:
DB 0C0H, 0F9H, 0A4H, 0B0H, 099H
DB 092H, 082H, 0F8H, 080H, 090H
;------------------------
END
;------------------------------------------
;经过调试,做而论道的程序完全满足题目的要求。但是,运气,差了一点。呵呵
;提问者留言:
;13476684571 2013-6-1 17:35
;谢谢你了,你的答案解决了我的问题,不过采纳答案的时候点错了,不好意思
;
//***********************************************
功能相同的C程序如下:
#include
#define uchar unsigned char
#define uint unsigned int
sbit P30 = P3^0 ;
sbit SPK = P3^1;
uchar code TAB[10] = {
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
uchar n_50ms = 0, n_s;
void beep(void)
{
uchar i, j;
for (i = 0; i < 255; i++) {
SPK = ~SPK;
for (j = 0; j < 200; j++);
}
}
void main(void)
{
uchar key;
TMOD = 0x01; //T0定时方式1
TH0 = (65535 - 50000) / 256; //定时50ms(@12MHz)
TL0 = (65536 - 50000) % 256;
// TR0 = 1;
ET0 = 1;
EA = 1;
while(1) {
P1 = 255; // ;LED
P2 = 255; // ;数码管
while (P30 == 1); //;等待开始
// while (P30 == 0); //;等待释放
beep();
P2 = 0x90; // 数码管显示9
n_50ms = 20;
n_s = 10;
TR0 = 1; // 开始定时
while (TR0 == 1) {
key = P1;
if (key != 255) {
switch (key) {
case 0xfe: P1 &= 0xef; P2 = 0xf9; break;
case 0xfd: P1 &= 0xdf; P2 = 0xa4; break;
case 0xfb: P1 &= 0xbf; P2 = 0xb0; break;
case 0xf7: P1 &= 0x7f; P2 = 0x99; break;
}
TR0 = 0;
beep();
while (P30 == 1); //;等待清零
while (P30 == 0); //;等待释放
beep();
} } }
}
//------------------------------------------
void int1() interrupt 1 //50ms中断一次
{
TH0 = (65535 - 50000) / 256;
TL0 = (65536 - 50000) % 256;
n_50ms--;
if(n_50ms == 0) {
n_50ms = 20;
n_s--;
P2 = TAB[n_s - 1];
if(n_s == 0) TR0 = 0;
}
}
//------------------------------------------