基础知识
PWM脉冲宽度调制:利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。
占空比:高电平所占整个周期的时间。
程序控制
要求:在P34管脚上输出PWM信号,要求频率1KHZ,占空比10%~90%可调
占空比1KHZ,所以高低电平时间之和为1ms
占空比是10%,高电平是0.1ms,低电平是0.9ms
占空比是90%,高电平是0.9ms,低电平是0.1ms
编程思路:
将1ms的周期切成10份,每份让0.1ms
将定时器2该成0.1ms的定时器中断,即中断的频率为10KHZ
定义pwm_cnt变量,在定时器2中断服务函数中将pwm_cut++,相当于0.1ms加一次,加10次等于周期1ms
根据占空比,来计算高低电平时间,再来操作IO口输出电平
//在P34管脚上输出PWM信号,要求频率1KHZ,占空比10%~90%可调
#include <STC15F2K60S2.H>
//PWM输出函数,放在0.1ms中断里执行
u8 cnt_pwm=1;
u8 pwm_duty = 90;
void PWM_Prcocess()
{
cnt_pwm = cnt_pwm % 10 + 1; //cnt_pwm的范围是1~10,共10个数,即定义了PWM的周期为1ms
if(cnt_pwm <= (pwm_duty/10))
{
P34 = 1;
}
else
{
P34 = 0;
}
}
}
void Timer2Init(void) //100微秒@12.000MHz
{
AUXR &= 0xFB; //定时器时钟12T模式
T2L = 0x9C; //设置定时初始值
T2H = 0xFF; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
IE2 |= 0x04; //开定时器2中断
EA = 1;
}
void main()
{
Timer2Init();
while(1)
{
}
}
void t2int() interrupt 12 //中断入口
{
PWM_Prcocess();
}
ps:这里没有加LED、蜂鸣器、继电器等的外设控制的初始化等函数,我有点懒得写。
LED亮度调节
注意事项:
LED调光的频率最好为1KHZ,太小的频率会导致LED闪烁
占空比调节可以控制LED的亮度,但是注意由于LED是共阳极的,占空比越高,反而亮度越低
上面的代码中高电平是P34=1,在对LED控制时,可以对字节进行赋值,即led_ctrl=0xff
//PWM输出按键调节LED和数码管亮度
#include <STC15F2K60S2.H>
#include <system.H>
#include <Smg.H>
#include <keyboard.H>
#include <PWM.H>
u8 cnt_pwm=1;
u8 pwm_duty = 90;
void PWM_Prcocess()
{
cnt_pwm = cnt_pwm % 10 + 1; //cnt_pwm的范围是1~10,共10个数,即定义了PWM的周期为1ms
if(cnt_pwm <= (pwm_duty/10))
{
device_ctrl(0x80,0xff);
}
else
{
device_ctrl(0x80,0);
}
}
u8 keyboard_cnt;
u8 keyboard_val;
void keyboard_process()
{
if(keyboard_cnt>=10)
{
keyboard_cnt=0;
keyboard_read();
keyboard_val=cont;
if(keyboard_val==0x88)
{
pwm_duty=pwm_duty+1;
if(pwm_duty>=10)
{
pwm_duty=0;
}
}
if(keyboard_val==0x11)
{
pwm_duty=pwm_duty-1;
if(pwm_duty<=0)
{
pwm_duty=10;
}
}
}
}
void SMG_process()
{
SMG_buf[0]=t_display[keyboard_val/16%16];
SMG_buf[1]=t_display[keyboard_val%16];
SMG_buf[2]=0;
SMG_buf[3]=0;
SMG_buf[4]=0;
SMG_buf[5]=0;
SMG_buf[6]=0;
SMG_buf[7]=0;
}
void Timer2Init(void) //100微秒@12.000MHz
{
AUXR &= 0xFB; //定时器时钟12T模式
T2L = 0x9C; //设置定时初始值
T2H = 0xFF; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
IE2 |= 0x04; //开定时器2中断
EA = 1;
}
void main()
{
system_init();
Timer2Init();
while(1)
{
SMG_process();
keyboard_process();
}
}
void t2int() interrupt 12 //中断入口
{
keyboard_cnt++;
SMG_dispaly();
PWM_Prcocess();
}
数码管亮度调节
//PWM输出按键调节LED和数码管亮度
#include <STC15F2K60S2.H>
#include <system.H>
#include <Smg.H>
#include <keyboard.H>
#include <PWM.H>
u8 keyboard_cnt;
u8 keyboard_val;
void keyboard_process()
{
if(keyboard_cnt>=10)
{
keyboard_cnt=0;
keyboard_read();
keyboard_val=cont;
if(keyboard_val==0x88)
{
pwm_duty=pwm_duty+1;
if(pwm_duty>=10)
{
pwm_duty=0;
}
}
if(keyboard_val==0x11)
{
pwm_duty=pwm_duty-1;
if(pwm_duty<=0)
{
pwm_duty=10;
}
}
}
}
u8 cnt_pwm=1;
u8 pwm_duty = 90;
void PWM_Prcocess()
{
cnt_pwm = cnt_pwm % 10 + 1; //cnt_pwm的范围是1~10,共10个数,即定义了PWM的周期为1ms
if(cnt_pwm <= (pwm_duty/10))
{
SMG_buf[0]=t_display[keyboard_val/16%16];
SMG_buf[1]=t_display[keyboard_val%16];
SMG_buf[2]=0;
SMG_buf[3]=0;
SMG_buf[4]=0;
SMG_buf[5]=0;
SMG_buf[6]=0;
SMG_buf[7]=0;
}
else
{
SMG_buf[0]=0;
SMG_buf[1]=0;
SMG_buf[2]=0;
SMG_buf[3]=0;
SMG_buf[4]=0;
SMG_buf[5]=0;
SMG_buf[6]=0;
SMG_buf[7]=0;
}
}
void SMG_process()
{
}
void Timer2Init(void) //100微秒@12.000MHz
{
AUXR &= 0xFB; //定时器时钟12T模式
T2L = 0x9C; //设置定时初始值
T2H = 0xFF; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
IE2 |= 0x04; //开定时器2中断
EA = 1;
}
void main()
{
system_init();
Timer2Init();
while(1)
{
SMG_process();
keyboard_process();
}
}
void t2int() interrupt 12 //中断入口
{
keyboard_cnt++;
SMG_dispaly();
PWM_Prcocess();
}