标题:
一个简单的PWM产生器频率占空比可调 单片机程序及仿真
[打印本页]
作者:
a89163930
时间:
2016-11-30 10:59
标题:
一个简单的PWM产生器频率占空比可调 单片机程序及仿真
废话不多说直接上程序仿真图
0.png
(30.96 KB, 下载次数: 63)
下载附件
2016-12-4 00:02 上传
0.png
(62.23 KB, 下载次数: 59)
下载附件
2016-12-4 00:02 上传
仿真工程文件下载:
PWM.rar
(25.81 KB, 下载次数: 101)
2016-11-30 10:59 上传
点击文件名下载附件
下载积分: 黑币 -5
单片机源程序:
#include <reg52.h>
unsigned char HighRH = 0; //高电平重载值的高位
unsigned char HighRL = 0; //高电平重载值的低位
unsigned char LowRH = 0; //低电平重载值的高位
unsigned char LowRL = 0; //低电平重载值的低位
unsigned int cnt=0; //记录T1中断次数
unsigned int i=0;
unsigned char dc=0;//PWM占空比
unsigned char fr=0; //PWM频率
unsigned char out=0; //PWM输出指示
sbit PWMOUT=P3^7; //PWM输出端口
void ConfigPWM();
void ClosePWM();
sbit k0=P1^0; //占空比+5
sbit k1=P1^1; //占空比-5
sbit k2=P1^2; //频率+
sbit k3=P1^3; // 频率-
sbit k4=P1^4; //输出PWM
sbit k5=P1^5; //停止输出PWM
unsigned char code LEDChar[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
unsigned char code LEDBuff[]={0xF7,0xFB,0x7F,0xBF};
void delay(int ms) //延时函数用于数码管的显示
{
unsigned int x,y;
for(x=ms;x>0;x--)
for(y=110;y>0;y--);
}
void LEDstate()
{
P0=LEDBuff[0];
P2=LEDChar[dc%10];
delay(3);
P0=LEDBuff[1];
P2=LEDChar[dc/10];
delay(3);
P0=LEDBuff[2];
P2=LEDChar[fr%10];
delay(3);
P0=LEDBuff[3];
P2=LEDChar[fr/10];
delay(3);
}
void Key(void)
{
if(out==0)
{
if(k0==0) //停止输出波形才能进行调整
{
if(dc<100) //占空比+5
dc+=5;
while(k0==0);
}
if(k1==0) //占空比-5
{
if(dc=0)
dc-=5;
while(k1==0);
}
if(k2==0) //频率+1
{
fr+=10;
while(k2==0);
}
if(k3==0) //频率-1
{
if(fr!=0)
fr-=10;
while(k3==0);
}
}
if(k4 == 0) //输出波形
out =1;
if(k5 == 0) //停止输出波形
out =0;
}
void main()
{
while (1)
{
LEDstate();
Key();
ConfigPWM(); //调用PWM配置函数
/* if(out==0)
ClosePWM();
*/
}
}
/* 配置PWM,fr频率,dc-占空比 */
void ConfigPWM()
{
unsigned int high, low;
unsigned long tmp;
tmp = (11059200/12)/100/fr; //计算一个周期所需要的计数值
high = (tmp*dc)/100; //计算高电平所需要的计数值
low = tmp - high; //计算低电平所需要的计数值
high = 65536 - high + 12; //计算高电平的重载值并补偿中断延时
low = 65536 - low + 12; //计算低电平的重载值并补偿中断延时
HighRH = (unsigned char)(high>>8); //高电平重载值拆分高低字节
HighRL = (unsigned char)high;
LowRH = (unsigned char)(low>>8); //低电平重载值拆分高低字节
LowRL = (unsigned char)low;
TMOD &= 0xF0; //清除T0的控制段?
TMOD |= 0x01; //T0为模式1
TH0 = HighRH; //加载T0重载值
TL0 = HighRL;
ET0 = 1; //使能T0中断
TR0 = 1; //启动T0
EA = 1; //开关总使能
PWMOUT=1; //输出高电平
}
/*关闭PWM */
void ClosePWM()
{
TR0 =0; //停止定时器
ET0 =0; //禁止中断
PWMOUT=1; //输出高电平
}
/* T0中断服务程序,产生PWM波 */
void InterruptTimer0() interrupt 1
{
if (PWMOUT==1) //当输出为高电平,加载低电平值并输出低电平
{
TH0 = LowRH;
TL0 = LowRL;
PWMOUT = 0;
}
else //当输出为低电平,加载高电平值并输出高电平
{
TH0 = HighRH;
TL0 = HighRL;
PWMOUT = 1;
}
}
复制代码
作者:
关外秀才
时间:
2018-8-31 14:01
好东西,谢谢分享,学习了~
作者:
关外秀才
时间:
2018-9-1 10:19
请问楼主使用什么软件仿真?我用Proteus仿真会闪退~
作者:
asdfgwqe
时间:
2019-5-23 09:11
这个是Proteus仿真嘛
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1