用AT89S51单片机产生"嘀,嘀,…"报警声

用AT89S51单片机产生“嘀、嘀、…”报警声从P1.0端口输出,产生频率为1KHz,1KHZ方波从P1.0输出0.2秒,接着0.2秒从P1.0
输出电平信号,如此循环下去,
由于要产生上面的信号,我们把上面的信号分成两部分,一部分为1KHZ方波,占用时间为0.2秒;另一部分为电平,也是占用0.2秒;因此,我们利用单片
机的定时/计数器T0作为定时,可以定时0.2秒;同时,也要用单片机产生1KHZ的方波,对于1KHZ的方波信号周期为1ms,高电平占用0.5ms,
低电平占用0.5ms,因此也采用定时器T0来完成0.5ms的定时;最后,可以选定定时/计数器T0的定时时间为0.5ms,而要定时0.2秒则是
0.5ms的400倍,也就是说以0.5ms定时400次就达到0.2秒的定时时间了。 一、#include <AT89X51.H>unsigned int t02s;unsigned char t05ms;bit flag;void main(void){TMOD=0x01;TH0=(65536-500)/256;TL0=(65536-500)%256;TR0=1;ET0=1;EA=1;while(1);}void t0(void) interrupt 1 using 0{TH0=(65536-500)/256;TL0=(65536-500)%256;t02s++;if(t02s==400){t02s=0;flag=~flag;}if(flag==0){P1_0=~P1_0;}}二、#include<reg51.h>#define uchar unsigned charsbit led=P1^0;int num;void main(){TMOD=0X01;TH0=(65536-500)/256;TL0=(65536-500)%256;EA=1;ET0=1;TR0=1;while(1);{if(num==801) num=0;}}void T0_time() interrupt 1{TH0=(65536-500)/256;TL0=(65536-500)%256;num++;if(num<=400)led=~led;elseled=0;}
第一个是正确的答案,第二个程序是自己写的,想到用led=0来表示那0.2S低电平,但是貌似行不通,输出的波形没有那0.2S低电平,麻烦帮我分析下。
可能是问题没写明白,我把题目的图贴出来了,要求是要0.2秒的方波再接0.2秒的低电平,还有那个 LED 就是输出的方波,接蜂鸣器的==,不是LED灯,我只是想通过400《num《800时,使LED=0,来达到0.2秒低电平的目的,通过while循环不断检测num是否到800,来达到方波和低电平之间循环的目的,我在仿真软件里接了示波器看了下,我的程序只有方波,没有那0.2秒低电平,麻烦网友帮我分析下,我的程序哪里不可行?

一个引脚要想用时驱动LED和蜂鸣器的话,建议加驱动电路,比如三极管之类的。

否则引脚可能会被拉低或拉高,进而不能同时实现两个功能。

或者用两个引脚分别完成两项功能:

#include<reg51.h>
#define uchar unsigned char
sbit led    = P1^0;
sbit buzzer = P1^1;
int num;
void main()
{
 TMOD=0X01;
 TH0=(65536-500)/256;
 TL0=(65536-500)%256;
 EA=1;
 ET0=1;
 TR0=1;
 while(1);
 {
  //if(num==801) num=0;
 }
}
void T0_time() interrupt 1
{
 TH0=(65536-500)/256;
 TL0=(65536-500)%256;
 num=(num+1)%800;
 if(num<=400)
 {
  buzzer=~buzzer;
  led=1;
 }
 else
 {
  buzzer=0;
  led=0;
 }
}

追问

可能是问题没写明白,我把题目的图贴出来了,要求是要0.2秒的方波再接0.2秒的低电平,还有那个 LED 就是输出的方波,接蜂鸣器的==,不是LED灯,我只是想通过400《num《800时,使LED=0,来达到0.2秒低电平的目的,通过while循环不断检测num是否到800,来达到方波和低电平之间循环的目的,我在仿真软件里接了示波器看了下,我的程序只有方波,没有那0.2秒低电平

追答

附件里是程序、Proteus 7.4a仿真电路和Keil C的工程,仿真可以看出来,实际电路用示波器也应该没问题,调一下左下角的时间尺度就可以。

另外,仿真时候单片机设成6MHz晶振了,所以时间长了一倍。

追问

能否帮我分析下我的程序问题出在哪里?这个是主要问题!!!答案我是有的。
用num++,和if判定num==801有什么问题?

追答

又看了一下你在问题中给的程序,“while(1)”后面紧接一个“;”号,后面的if判断应该是运行不到的,所以num会一直加到满,然后在变到零。
不知道你看到的方波是什么样子,按你第二个程序400是振荡,(65536-400)都应该是低电平。横轴缩小了看到的应该是类似尖脉冲;横轴放大了看要么是方波,要么是一条线。
我后来给的程序也没注意到这个地方,但是因为对num的判断是在中断子程序中,所以可以正常运行。
你只要把“while(1)”后面紧接一个“;”号删除就可以看到效果,不过建议你改在中断子程序中对num做判断比较好,个人观点,仅供参考。

温馨提示:答案为网友推荐,仅供参考
相似回答
大家正在搜