简单的说这是一个可以通过51单片机来来输出一个可以调节占空比和周期的方波
这是一个学校的单片机的课设,我刚开始一直都不太懂,直到后面才慢慢的理解。
一.这个课设的主要内容就是:
我们要用AT89C51,ADC0809,74LS373,74LS138,74HC04,74HC4040,还有一个10K电位器,以及开关。
大家要去了解这个各个芯片的功能以及使用情况,具体的可以去参考其他大佬的博客
(1)ATC0809的主要功能就是控制,通过写入代码来控制信号的输出的高低电平
(2)ADC0809的主要功能就是AD信号的转换
(3)74LS373的主要功能就是一个储存一个暂时的锁存器
(4)74LS138的主要功能就是一个地址锁存器
(5)74HC04简单的说说就是可以让相位翻转180°
(6)74HC4040是一个可以调节不同的分频(分频就是把原来的信号的频率分为原来的1/N)
(7)电位器可以看作是一个通过滑动变阻器来调节的输出电压
二.基本的仿真思路
我们通过10K电位器W1接到ADC0809的输入端,这样就可以通过电压信号来转变为数字信号,根据数字信号来实现占空比的可调,同时也可以加一个S28的开关,通过开关的闭合也开启控制周期的大小(50HZ还是100HZ)
三.最能理解的思路就是我们要把简单的组合起来变成一个稍微复杂一点的
(1)要知道我们是如何实现一个简单的方波;
其实就是通过一个51单片机的输出口实现信号的高低电平的不断的切换;
所以编程的思路就是通过输出口不断的变换输出的高低电平,也就是说我们在一个周期内信号它要输出高电平和一个低电平,因为这是一个方波,它需要一段时间高电平,一段时间低电平,然后如此反复循环。所以我们要用到一个定时器,定时器输出一个高电平,通过定时器中断来取反实现高电平变成低电平。while循环就是一个方波了。
占空比就是高电平在整个周期中的占比的值
(2)如何实现一个开关的按键来控制一个方波的周期
很好你和我想的一样,就是一个if语句,if语句来判断按键的开或者关
但是还有一个问题,如何实现50hz还是100hz,对,就是通过计算初值来实现;这里我不细讲公式了50hz我们自己的定时需要65536- 18432;100hz就是65536-9216;
(3)接下来就是如何来实现一个可以自主调节的程序
在上面我们也说过了,我们是通过定时器的中断程序来实现输出信号的不断的翻转为原来的180度,也就是输出的信号为方波信号,如然后就是简单的程序与复杂的程序融合
仿真图
如下是代码
#include<reg51.h>
#include<absacc.h>
#include<intrins.h>
#define adc_v XBYTE[0x8000]
sbit eoc = P1^2;
sbit key = P1^3;
sbit P1_1 = P1^1;
sbit P1_0 = P1^0;
unsigned int PWM_w; //周期总宽度
unsigned int PWM_h; //周期高电平宽度
unsigned char temp; //adc_v暂存值
bit out_a,out_b;
void adc_init()
{
_nop_();
adc_v=0; //启动ADC
_nop_();
}
void time_init()
{
TMOD=0x11; //双定时器,方式1 16位定时器
TH0=(65536-PWM_w)/256;
TL0=(65536-PWM_w)%256;
TH1=(65536-PWM_h)/256;
TL1=(65536-PWM_h)%256;
ET0=1; //打开中断
ET1=1;
EA=1;
TR0=1; //启动定时器
TR1=1;
}
void timer0() interrupt 1 // 总周期定时
{
out_a=~out_a;
out_b=~out_b;
TH0=(65536-PWM_w)/256;
TL0=(65536-PWM_w)%256;
TR1=1; //周期结束打开定时器1,开始定高电平
}
void timer1() interrupt 3 //一个周期内高电平定时
{
out_a=~out_a;
out_b=~out_b;
TH1=(65536-PWM_h)/256;
TL1=(65536-PWM_h)%256;
TR1=0; //溢出关闭定时器1等待下一个周期
}
void main()
{
out_a=1; //给予输出初值
out_b=0;
time_init(); //启动定时器
while(1)
{
P1_0=out_a; //输出脉冲
P1_1=out_b;
if(key) PWM_w=18432; //判断按钮选择脉冲周期
else PWM_w=9216;
adc_init(); //启动adc
while(eoc==0); //停留等待转换完成
temp=adc_v; //启动adc并读取它的值
PWM_h=PWM_w*(temp/256); //讲其除以256得到占空比,再乘上总周期宽度,得到高电平定时时间
}
}
以上是我们小组的结果,假如有错误的大家可以一起探讨探讨,也希望大家能指出错误。