基于51单片机的波形发生器(压控振荡器,矩形波,LCD1602)原理图、流程图、物料清单、仿真图、源代码
基于51单片机的波形发生器(压控振荡器,矩形波,LCD1602)
设计一个输入直流信号,输出矩形波的转换器
1、输入电压控制输出矩形波频率,输出频率范围为1-1kHz,输出幅值为正负7V
2、输入电压为0-10V
3、显示当前电压,占空比,频率
4、按键调节占空比
#include "reg51.h" //此文件中定义了单片机的一些特殊功能寄存器
#include"intrins.h"
#include "lcd1602.h"
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
sbit CLK= P2^4;//时钟,初始状态为0
sbit DI= P2^5;//数据输入
sbit DO= P2^6; // 数据输出
sbit CS= P2^7;
sbit k1=P1^6;
sbit k2=P1^7;
u8 time=0,volt=0;
sbit out=P3^7;//输出
u16 freq=100;//频率
u8 pwm=5,time1=0,time2=0,time3=0;//占空比
u8 set0=0,set1=0;
u8 disp1[]="Volt:00.0V";
u8 disp2[]="PWM:00% F:0000Hz";
/*********************************************
读取ADC
**********************************************/
u8 ADC(u8 ch)//通道ch 1,2
{
u8 temp0,temp1,i;
CS=0;
temp0=0;
temp1=0;
_nop_();
_nop_();
DI=1;//开始位
_nop_();
_nop_();
CLK=1;
_nop_();
_nop_();
CLK=0;
_nop_();
_nop_();
DI=0;
_nop_();
_nop_();
//选择通道0
DI=1;
_nop_();
CLK=1;//上升沿DI=1
_nop_();
CLK=0;//1个下降沿DI=1
_nop_();
if(ch==1)
DI=0;
if(ch==2)
DI=1;
_nop_();
CLK=1;
_nop_();
CLK=0;//第3个上升沿DI=0
_nop_();
DI=1;
//********通道选择结束开始读取转换后的二进制数****
//下降沿读数,一下进行判断和处理,共8次
for(i=0;i<8;i++)
{
temp0=temp0<<1;
CLK=1;
if(DO)
temp0++;
_nop_();
CLK=0;
}
for(i=0;i<8;i++)
{
temp1=temp1>>1;
CLK=1;
if(DO)
temp1=temp1 +0x80;
_nop_();
CLK=0;
}
CS=1;
return temp0;
}
/*******************************************************************************
* 函数名 :UsartInit()
* 函数功能 :设置串口
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void Init()
{
TMOD=0X11;
TH0=0X3c;
TL0=0Xb0;
TH1=0;
TL1=0;
ET0=1;
ET1=1;
EA=1; //打开总中断
TR0=1;
TR1=1;
}
/*******************************************************************************
* 函 数 名 : zhou
* 函数功能 : 计算周期
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void zhou()
{
unsigned long i;
i=1000000;
i=i/freq;//计算周期
i=i/10;//周期分成10份
if(i<60000)
{
set0=(65536-i)/256;
set1=(65536-i)%256;
time2=0;
}
else
{
set0=0xfc;
set1=0x18;
time2=i/1000;
}
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
init_1602();
Init(); // 初始化
while(1)
{
if(!k1)
{
if(pwm<9)
pwm++;
while(!k1);
}
if(!k2)
{
if(pwm>1)
pwm--;
while(!k2);
}
}
}
/*******************************************************************************
* 函数名 : tim0()
* 函数功能 : 定时器0中断
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void tim0() interrupt 1
{
u16 i;
if(time<10)
time++;
else
{
time=0;
volt=ADC(1);//测量
i=volt;
volt=i*100/127;
if(volt==0)
i=1;
freq=i*8;//计算频率
zhou();
//显示
disp1[5]=volt/100+0x30;
disp1[6]=volt%100/10+0x30;
disp1[8]=volt%10+0x30;
disp2[4]=pwm+0x30;
disp2[10]=freq/1000+0x30;
disp2[11]=freq%1000/100+0x30;
disp2[12]=freq%100/10+0x30;
disp2[13]=freq%10+0x30;
write_string(1,0,disp1);
write_string(2,0,disp2);
}
TH0=0X3c;
TL0=0Xb0;
}
/*******************************************************************************
* 函数名 : tim1()
* 函数功能 : 定时器1中断
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void tim1() interrupt 3
{
if(time1<time2)
time1++;
else
{
time1=0;
if(time3<9)
time3++;
else
time3=0;
}
if(time3<pwm)//输出PWM
out=1;
else
out=0;
TH1=set0;
TL1=set1;
}