【51单片机开发板】可调周期、占空比pwm工程

时光总嘲笑我的痴心妄想 提交于 2020-07-27 15:56:36

可调周期、占空比pwm工程(蜂鸣器提示效果)

(一)proteus虚拟仿真电路

在这里插入图片描述

这是基于51单片机开发板的proteus虚拟仿真电路。如果没有示波器,建议下载一个proteus进行虚拟仿真,链接: https://pan.baidu.com/s/1eTlMIcYVT9ySdQoOxdXi8w 提取码: mfqw,如果已经安装有虚拟仿真软件,可以自行建立工程。

在这里插入图片描述
上图部分为仿真电路元器件,点击AT89C51上面的P键可以对元器件进行搜索。

在这里插入图片描述
上图可引导找到电源和接地的符号。
在这里插入图片描述
完成C代码编写后,双击虚拟电路中的51单片机会出现上图窗口,单击红圈中的图标选择相应的文件,点击运行即可。


(二)C语言程序代码

以下为此次工程的C代码,如发现有不足之处可以加群 1138473316 一起探讨 。

#include <reg51.h>

#define uint unsigned int 
#define uchar unsigned char							 

sbit BZ=P1^5;                  //蜂鸣器输出端口
sbit PWM=P2^0;                 //P2^0口输出PWM 
sbit key1=P3^0;   
sbit key2=P3^1;  
sbit key3=P3^2; 
sbit key4=P3^3;
uint time, upper, floor;       //time为中断计数变量,upper为占空比上限,floor为占空比下限,
uint count=30,cyc=100;         //count为占空比初始值,cyc为周期中间变量,注:周期=cyc*10.
uchar i=4;
uchar a[17]={10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90};


/***********延时xms程序***********/
void Delayxms(uint z) 
{
    uchar x, y;
	while(z--)
	{
		x = 2;
		y = 239;
		do
		{
			while (--y);
		} while (--x);
	}
	
}


/***********定时器0初始化***********/
void T0_init()
{
	TMOD=0x01;                       //定时器0工作于方式1
	TH0=(65536-10)/256;              //定时器0初值,每10us产生一次中断
	TL0=(65536-10)%256;
	TR0=1;
	ET0=1;
	EA=1;
}


/*********主函数********************/
void main()
{	 
	T0_init();
	while(1)
	{
		Delayxms(2);
		if(key1==0)                   //占空比上调键按下;
		{
			Delayxms(2);              //按键消抖
			while(key1==0);
			Delayxms(2);
			count+=cyc/20;
			upper=9*(cyc/10);
			i++;
			if(count>upper) 
			{
				i=16;
				count=upper;
			}
		}
		if(key2==0)                  //占空比下调键按下;
		{
			Delayxms(2);
			while(key2==0);
			Delayxms(2);
			count-=cyc/20;
			floor=cyc/10;
			i--;
			if(count<floor) 
			{
				i=0;
				count=floor;
			}
		}
		if(key3==0)                   //周期中间变量上调键按下;
		{
			Delayxms(2);
			while(key3==0);
			Delayxms(2); 
			cyc+=100; 
			if(cyc>=1000) cyc=1000;
			count=a[i];
			count*=(cyc/100);

		} 
		if(key4==0)                   //周期中间变量下调键按下;
		{
			Delayxms(2);
			while(key4==0);
			Delayxms(2); 
			cyc-=100;
			if(cyc<100) cyc=100;
			count=a[i];
			count*=(cyc/100);
		}
		if(count>cyc/2)             //蜂鸣器反转循环
		{
			BZ=~BZ;
		}
	}
}


/**************定时0中断处理******************/
void timer0_int() interrupt 1 
{
		TR0=0;                                     //设置定时器初值期间,关闭定时器
		TH0=(65536-10)/256;                        //定时器0初值,每10us产生一次中断
		TL0=(65536-10)%256;
		TR0=1;	 
		time++;  
		if(time<count)	 PWM=1;	                  //输出高电平
		else if(time>=count && time<cyc) PWM=0;	  //输出低电平
		else time=0;
 }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!