pwm占空比来控制LED灯的明亮程度。
#include <reg52.h> typedef unsigned char uint8; typedef unsigned int uint16; sbit down = P3^0; sbit up = P3^1; uint8 t = 0; uint8 PWM_T = 0; //占空比控制变 void delay_1ms(uint16 t) { uint16 x,y; for(x=t;x>0;x--) for(y=120;y>0;y--); } void main(void) { TMOD = 0x02; //定时器0,工作模式2,8位定时模式 TH0=210; //写入预置初值(取值1-255,数越大PWM频率越高) TL0=210; //写入预置值 (取值1-255,数越大PWM频率越高) TR0=1; //启动定时器 ET0=1; //允许定时器0中断 EA=1; //允许总中断 P1=0xff; //初始化P1,输出端口 PWM_T=30; while(1) { if(!up) { if(PWM_T<250) { PWM_T++; } delay_1ms(10); } if(!down) { if(PWM_T>0) { PWM_T--; } delay_1ms(10); } } } timer0() interrupt 1 { t++; //每次定时器溢出加1 if(t==250) //PWM周期 100个单位 { t=0; //使t=0,开始新的PWM周期 P1=0x00; //输出端口 } if(PWM_T==t) //按照当前占空比切换输出为高电平 { P1=0xff; // } }
通过控制高电平在一个周期内的占比来控制。
可以通过定时器中断来模拟PWMM。
用单片机制作的占空比均匀间隔可调PWM发生器:
占空比可调间隔为0.1。即可取得占空比为0%,10%,20%……90%到100%的PWM波。
该波的频率固定为1KH(周期1000微秒)。
我所使用的QX-MCS51学习板上的操作键:
S2----占空比加 S3----占空比减
#include<reg52.h> #define uint unsigned int uint pp; char num=2,dis; sbit pwm=P1^0; sbit s2=P3^0; sbit s3=P3^1; sbit dula=P2^6; sbit wela=P2^7; unsigned char code table[]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f, 0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; void keyscan() { if(s2==0) { while(!s2); num++; if(num==11) num=10; dis=num; } if(s3==0) { while(!s3); num--; if(num==-1) num=0; dis=num; } } void display(a) { dula=0; P0=table[a]; dula=1; dula=0; wela=0; P0=0xfe; wela=1; wela=0; } void main() { TMOD=0x01; //模式设置,00000001,可见采用的是定时器0,工作与模式1(M1=0,M0=1)。 TR0=1; //打开定时器 TH0=0Xff; //定时器设置,每隔100微秒发起一次中断。 TL0=0Xa4; ET0=1; //开定时器0中断 EA=1; //开总中断 while(1) { keyscan(); if((num!=0)&&(num!=10)) //对于占空比为0和100%这两种极端情况,最好分离出,单独考虑 { if(pp<=num) pwm=1; else pwm=0; } else if(num==0) //当占空比为0 pwm=0; else pwm=1; if(pp==10) //当占空比为100% pp=0; display(num);//显示num当前值,占空比为num/10。 } } void time0() interrupt 1 { TH0=0Xff; TL0=0Xa4; pp++; }