用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>可能是问题没写明白,我把题目的图贴出来了,要求是要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做判断比较好,个人观点,仅供参考。