请问如何用51单片机生成频率可调的方波?请给出方案或者修改我的方案(如下)

请问如何用51单片机生成频率可调的方波?请给出方案或者修改我的方案(如下)
(重要说明:这个东西我在proteus上虚拟运行一点问题没有,可是用51单片机实际产生的方波不符合要求的)
用0~5V可变电压控制输出频率,选用AD0832模数转换器读取可变电压值,51单片机根据AD0832的端口输出量转换成具体电压值,然后根据电压值的大小控制每个方波的产生时间来改变频率。
图一中方波是我最终要生成的,两个方波完全一致,第二个波形相比第一个波形滞后四分之一波长。
图二是我在proteus中仿真的图,其中我用频率极低的正弦波当成0~5V的控制电压观察输出方波效果用的。
以下是C语言源代码:
(写不下了,我把它放到个人主页上)
http://hi.baidu.com/warlab/item/a0cc8a7b24f75c3dd7a89c97

P0 口,应该加上上拉电阻

AD 转换的结果,应该是:0~255。
使用真实的硬件,结果是多少?
可以在 P2 口,接上八个 LED,当场显示出来看看。

另外,对于这一批数据,你所期望得到的频率范围,究竟是多少?

还有,采用软件定时,并不准确。追问

要求当输入为5V时候输出方波为100Hz,,输入为0时无方波输出,线性变化;定时不准确不要紧,主要是使用的,差个几赫兹不要紧。我用硬件测试出现的情况为:确实,当我输入2V电压时,的确输出了40Hz方波,符合我的要求,可是这个方波只持续了大概十个周期就没有了,搞不懂什么原因……用proteus测试都是好的,能持续输出方波

追答

也许 0832 芯片工作不稳定。

试试直接用拨动开关,在 P1 输入八位数,执行下列程序:

#include
#define uchar unsigned char
#define uint unsigned int

//输出端口定义
sbit X1 = P0^0;
sbit X2 = P0^1;

//延时函数
void delay_ms(uint x)
{
uchar t;
while(x--) for(t=0;t 10) {

X1 = 0; X2 = 1; delay_ms(t);
X1 = 0; X2 = 0; delay_ms(t);
X1 = 1; X2 = 0; delay_ms(t);
X1 = 1; X2 = 1; delay_ms(t);

}
else {
X1 = 1; X2 = 1; delay_ms(4.0 * t);
}
}
}

如果能看到调频的效果,毛病就出在 0832 上。

追问

问题出在ADC0832上。去掉读取ADC0832的程序块,输出恒定频率方波正常。使用原程序在输出端口接LED,低电压,灯缓慢闪几下,熄灭,等很久,再以相同的频率闪,再次熄灭很久,反复;调高电压,灯快速闪动,熄灭,隔一小段时间再次快速闪烁,反复……个人感觉是51单片机从ADC0832读取、转化需要时间,造成了延迟,而proteus理想化没有延迟,以至于理论和实际试验有差别。不知该如何改进呢?

问题出在ADC0832上。去掉读取ADC0832的程序块,输出恒定频率方波正常。使用原程序在输出端口接LED,低电压,灯缓慢闪几下,熄灭,等很久,再以相同的频率闪,再次熄灭很久,反复;调高电压,灯快速闪动,熄灭,隔一小段时间再次快速闪烁,反复……个人感觉是51单片机从ADC0832读取、转化需要时间,造成了延迟,而proteus理想化没有延迟,以至于理论和实际试验有差别。不知该如何改进呢?

追答

哦,看来是转换的问题,值得深入讨论。

但是,手头没有这个器件,看来,是帮不上忙了。

追问

啊?兄弟别这么放弃啊,在帮我想想办法啊,得靠你呢

温馨提示:答案为网友推荐,仅供参考
第1个回答  2014-01-12
从硬件上来说,PO口作为IO口是要加上拉电阻的,你先试一试1K电阻。或者你不要用PO口,改为P1.6和P1.7这样就不用接上拉电阻了(软件要记得改)
如果不行的话,就从你说的一开始有40HZ后来没有了入手查找问题,
首先判断你的硬件是否失效?如果单片机正常运行,那是不是你的d<10了?方法是加2个LED到其中2个端口 ,如P1.3,P1.4,然后在软件中添加相应操作如下,如果单片机正常的跑,那两个LED至少有一个在闪烁,否则单片机就是失效了。如果是P1.4的LED在闪烁,那说明AD部分有问题。如果P1.3在闪烁,呵呵 那就奇怪了!
暂时就这些,希望你试一试!其实你的问题肯定能解决的,相信自己!
if(d>10)
{ P1.3=0;
X1 = 0; X2 = 1;
delay_ms(t);
X1 = 0; X2 = 0;
delay_ms(t);
P1.3=1;
X1 = 1; X2 = 0;
delay_ms(t);
X1 = 1; X2 = 1;
delay_ms(t);
}
else
{ P1.4=0;
X1 = 1; X2 = 1;
delay_ms(4.0 * t);
P1.4=1;
}追问

首先谢谢您!你说的这些我下午都试过了,换成led小灯也是,闪烁几次后就不动了,然后隔一段很长的时间又闪了几下,周而复始……

追答

请问你实际电路也是直接把EA和AD0832VCC接上而没有接5V电源吗

第2个回答  2014-01-12
可以用定时器!好像51有款单片机可以输出可编程方波好像还可以改变占空比好久没用了都忘记了,改变定时器值就可以改变输出波形和频率,你这个又用AD很麻烦!追问

晕……拜托看清题意再回答。我主要是用输入的不确定电压控制输出方波频率的,你倒好,叫我不用ad转换,无语

相似回答