//////////////////////////////////////////////////////////////////
// 综合模拟发声 //
//////////////////////////////////////////////////////////////////
#include
sbit SPK=P1^0; //定义喇叭端口
sbit K1=P1^4; //报警声按键
sbit K2=P1^5; //消防声按键
sbit K3=P1^6; //救护声按键
sbit K4=P1^7; //停止按键
unsigned char frq; //频率变量
unsigned char sel=0; //功能变量
void DelayUs(unsigned char t) //us延时函数
{
while(--t); //大致延时tus
}
void DelayMs(unsigned char t) //ms延时函数
{
while(t--) //大致延时tms
{
DelayUs(245);
DelayUs(245);
}
}
void Keyscan() //键盘扫描
{
if(K1==0)sel=1; //报警声
if(K2==0)sel=2; //消防声
if(K3==0)sel=3; //救护声
if(K4==0)sel=0; //停止
}
void Init_Timer0(void)
{
TMOD|=0x01; //方式1,使用"|"可使用多个定时器时互不影响
EA=1; //开总中断
ET0=1; //开定时器中断
TR0=0; //关闭定时器
}
void main() //主程序
{
unsigned char i; //循环变量定义
Init_Timer0(); //初始化定时器
while(1)
{
Keyscan();
if(sel==0)TR0=0;
else TR0=1;
if(sel==1) //模拟报警声
{
DelayMs(1); //延时1ms,累加频率值
frq++;
}
if(sel==2) //模拟消防车声
{
for(i=0;i<200;i++)
{
DelayMs(10); //延时10ms,累加频率值
frq=i;
}
for(i=200;i>0;i--)
{
DelayMs(10); //延时10ms,累减频率值
frq=i;
}
}
if(sel==3)
{
frq=0;
for(i=0;i<60;i++)DelayMs(10);//播放1s左右一种频率
frq=100;
for(i=0;i<60;i++)DelayMs(10);//播放1s左右另外一种频率
}
}
}
void Timer0_isr(void) interrupt 1
{
TH0=0xfe; //重新赋值
TL0=frq; //低8位值在主程序中不断累加
SPK=!SPK; //端口电平取反
}
你是不是用蜂鸣器,然后程序是不是类似这样
void a() //程序a放出一段救护车的声音
{
}
void b() //程序a放出一段消防车的声音
{
}
//然后你觉得可以这样写
void main()
{
if(KEY1==0)
{
a();
}
if(KEY2==0)
{
b();
}
}
如果是这样的话,你思想肯定是错的,因为无论是a程序,还是b程序,都是一段占用CUP挺长时间的程序,比如a()程序是救护车三秒,那么在a()程序执行的三秒里,你的CPU就是运行在这个程序里,没有办法查询按键的状态
想要改进的话可以按照以下思路
加一段按键查询就放在a 和 b子程序内容
假如
void a ()
{
for( ; ; )
{
//送一定的电平给蜂鸣器IO口
delay();//肯定有延时
if(KEY2==0)
break; //先结束这个子程序的状态
}
}
注意,main函数原来的结构就不用改了
显示出你的程序,改改即可。