可调周期、占空比pwm工程(蜂鸣器提示效果)
(一)proteus虚拟仿真电路(二)C语言程序代码(一)proteus虚拟仿真电路
这是基于51单片机开发板的proteus虚拟仿真电路。如果没有示波器,建议下载一个proteus进行虚拟仿真,链接: /s/1zWhHeyIfzy1N5-MfE0DoJA 提取码: uwsa,如果已经安装有虚拟仿真软件,可以自行建立工程。
上图部分为仿真电路元器件,点击AT89C51上面的P键可以对元器件进行搜索。
上图可引导找到电源和接地的符号。
完成C代码编写后,双击虚拟电路中的51单片机会出现上图窗口,单击红圈中的图标选择相应的文件,点击运行即可。
(二)C语言程序代码
以下为此次工程的C代码 。
#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工作于方式1TH0=(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;}