/*******************************************************************
模块名称:PWM.c
功 能:可调PWM波
说 明:按键AN1增加占空比,按键AN2减小占空比,P0^2口输出PWM波
*********************************************************************/
#include < reg52.h >
#define uchar unsigned char
#define uint unsigned int
uint T_1 = 10000; //定时器1初值变量
uchar flag; //按键返回变量
sbit PWM = P0^2; //PWM输出口
sbit AN1 = P0^0; //增加占空比
sbit AN2 = P0^1; //减小占空比
//调节占空比函数
/********************************************************************
函 数 名:timer_init()
功 能:定时器初始化函数
说 明:无
入口参数:无
返 回 值:无
********************************************************************/
void timer_init()
{
TMOD = 0x11; //定时器0、定时器1工作于模式1
EA = 1; //开总中断
ET0 = 1; //定时中断0允许
ET1 = 1; //定时中断1允许
TH0 = (65536-20000)/256; //定时器0装初值:20ms
TL0 = (65536-20000)%256;
TH1 = (65536-T_1)/256; //定时器1装初值:10ms
TL1 = (65536-T_1)%256;
TR0 = 1; //开启定时中断0
}
/********************************************************************
函 数 名:timer0()
功 能:定时中断0中断服务函数
说 明:产生高电平,中断固定时间20ms,频率50HZ
入口参数:无
返 回 值:无
********************************************************************/
void timer0() interrupt 1
{
TR0 = 0; //关闭定时中断0
PWM = 1; //脉冲高电平
TH0 = (65536-20000)/256; //定时器0装初值:20ms
TL0 = (65536-20000)%256;
TR1 = 1; //开启定时中断1
TR0 = 1; //开启定时中断0
}
/********************************************************************
函 数 名:timer1()
功 能:定时中断1中断服务函数
说 明:产生低电平,中断时间可变
入口参数:无
返 回 值:无
********************************************************************/
void timer1() interrupt 3
{
TR1 = 0; //关闭定时中断1
PWM = 0; //脉冲低电平
TH1 = (65536-T_1)/256; //定时器1装初值:10ms
TL1 = (65536-T_1)%256;
}
/********************************************************************
函 数 名:keyscan()
功 能:键盘扫描函数
说 明:无
入口参数:无
返 回 值:无
********************************************************************/
uchar keyscan(void)
{
if(AN1==0) //AN1按下
{
while(AN1==0); //AN1松开
return 1; //返回 1
}
if(AN2==0) //AN2按下
{
while(AN2==0); //AN2松开
return 2; //返回 2
}
else return 0; //返回 0
}
/********************************************************************
函 数 名:change()
功 能:调节占空比函数
说 明:无
入口参数:无
返 回 值:无
********************************************************************/
void change(void)
{
flag = keyscan(); //按键返回值保存
if(flag==1) //按键返回值为1,即AN1按下
{
if(T_1>=65435) //定时器初值变量大于等于65525
{
T_1 = 65530; //定时器初值变量等于65535
}
if(T_1<65525) //定时器初值变量小于65525
{
T_1 = T_1+100; //定时器初值变量加10
}
}
if(flag==2) //按键返回值为2,即AN2按下
{
if(T_1<=100) //定时器初值变量小于等于10
{
T_1 = 5; //定时器初值变量等于0
}
if(T_1>100) //定时器初值变量大于10
{
T_1 = T_1-100; //定时器初值变量减10
}
}
}
/********************************************************************
函 数 名:main()
功 能:主函数
说 明:无
入口参数:无
返 回 值:无
***********************************************************************/
void main()
{
timer_init(); //定时器初始化
while(1)
{
change(); //改变占空比
}
}
你用Protues软件的示波器按照程序引脚图连一下,就是一个PWM波了,且占空比可调
通过PROTEUS仿真成功的完整电路、程序,在下面有:
http://hi.baidu.com/%D7%F6%B6%F8%C2%DB%B5%C0/blog/item/f2005aed1643a12a63d09f24.html
简单地说,定时翻转一个脚位电平就可以了,当然是50%占空比的.
频率就看你定时的时间了.