基于51单片机的PWM发生器(频率,占空比,LCD1602)原理图、流程图、物料清单、仿真图、源代码
基于51单片机的PWM发生器(频率,占空比,LCD1602)
1、输出PWM波形,初始频率300Hz,占空比50%波形和占空比可调
2、波形频率和占空比由按键或串口命令输入
3、按键有四个,分别是S1,S2,S3,S4.S1作为启动键盘输入的标志键,一旦此键按下!表示键盘输入开始,提示单片机开始接收数据和命令,第一次按下,修改频率数,第二次按下,修改占空比数;S2作为增加键使用,此键按下表示在原来的基数上加1;S3作为减少键使用,此键按下表示在原来的基数上减一:S4作为结束键盘输入的确认键,此键按下表示数据或者命令输入结束。
4、串口通信输入波形频率数和占空比数,比如30050,频率300,占空比50,成功返回1失败返回0
5、LCD1602液晶显示当前波形频率数和占空比数
#include "reg51.h"
#include "lcd1602.h"
#define uchar unsigned char
#define uint unsigned int
sbit k1=P1^0;//按钮
sbit k2=P1^1;
sbit k3=P1^2;
sbit k4=P1^3;
sbit out=P2^7;//输出PWM
uchar time=0,mode=0;//系统变量
uchar disp1[]="Freq:000Hz";
uchar disp2[]=" PWM:00%";
uint freq=100;//频率
uchar sec=0,pwm=50;//占空比
uchar tha=0,thl=0;//定时器初值
uchar num[]="00000";
uchar next=0;
uint time1=0;//接收超时
//设置定时器1
void set()
{
unsigned long i=0;
if(freq<39) //低频
{
TMOD=0x21;
i=freq;
i=10000/freq;
tha=(65536-i)/256;
thl=(65536-i)%256;
}
else //高频
{
TMOD=0x22;
i=freq;
i=10000/freq;
tha=256-i;
TH0=tha;
TL0=tha;
}
}
void main()//主函数
{
uint i=0;
init_1602();//初始化LCD
set();
SCON=0X50; //设置为工作方式1
TH1=0XFD;
TL1=0XFD;
ES=1; //打开接收中断
TR1=1; //打开计数器
ET0=1;
EA=1;//打开总中断
TR0=1;//打开定时器
while(1)
{
//按键检测
if(!k1)//设置
{
if(mode<2)
mode++;
else
mode=0;
while(!k1);
}
if(!k2)//加
{
if(mode==1)
{
if(freq<999)
freq++;
}
if(mode==2)
{
if(pwm<99)
pwm++;
}
set();
while(!k2);
}
if(!k3)//减
{
if(mode==1)
{
if(freq>1)
freq--;
}
if(mode==2)
{
if(pwm>1)
pwm--;
}
set();
while(!k3);
}
if(!k4)//确认
mode=0;
//延时显示
if(i<10000)
i++;
else
{
i=0;
TR0=0;
//显示
write_com(0x0c);
disp1[5]=freq/100+0x30;
disp1[6]=freq%100/10+0x30;
disp1[7]=freq%10+0x30;
disp2[5]=pwm/10+0x30;
disp2[6]=pwm%10+0x30;
write_string(1,0,disp1);
write_string(2,0,disp2);
if(mode==1)
{
write_sfm(1,6);
write_com(0x0e);
}
if(mode==2)
{
write_sfm(2,6);
write_com(0x0e);
}
TR0=1;
}
//接收超时控制
if(time1>0)
time1--;
if(time1==1)
{
next=0;
ES=0;
SBUF='0';//失败
while(!TI);
TI=0;
RI=0;
ES=1;
}
}
}
//定时器0中断
void Timer0() interrupt 1
{
if(freq<39)//重装定时器
{
TH0=tha;
TL0=thl;
}
if(sec<100)//输出PWM
sec++;
else
sec=0;
if(sec<pwm)
out=1;
else
out=0;
}
//串口中断
void Usart() interrupt 4
{
uchar i;
time1=10000;
i=SBUF;//出去接收到的数据
RI = 0;//清除接收中断标志位
num[next]=i;
if(next<4)
next++;
else
{
next=0;
time1=0;
freq=num[0]-0x30;//接收数据处理
freq=freq*10+num[1]-0x30;
freq=freq*10+num[2]-0x30;
pwm=num[3]-0x30;
pwm=pwm*10+num[4]-0x30;
set();
SBUF='1';//成功
while(!TI);
TI=0;
}
}