1.设计思路
(1)使用两个定时器,T0用于PWM波翻转,T1用于调整占空比,均采用16位计时模式,因为51单片机在此模式下不能自动重装初值,因此需要在每一次触发中断后手动重装初值,为了不造成太大误差,重装初值程序需要写在中断最前面,PWM波占空比在5s内先由0%增加到100%,再逐渐减少到0%,为了保证呼吸灯呼吸均匀,决定每次以2.5%的增幅改变占空比,共改变80次;
(2)T0每25us中断一次,当累计中断80次(25×80=2000us,保证周期为2ms)时PWM波翻转;T1用于调整占空比,每12.5ms中断一次,当累计中断5次(12.5×5=62.5ms,5s/80=62.5ms)时改变占空比;
2.电路设计
(1)原理图
(2)PCB图
(3)3D模型图
3.程序源码
#include < reg52.h >
unsigned char XUNHUAN = 0;
unsigned char PWM_COUNT = 0; //PWM翻转计时
unsigned int HUXI_COUNT = 0; //占空比调节计时
signed char PWM_VALUE = 2; //占空比比对值
unsigned char ljk = 0; //控制占空比调整比对值direc_flag
bit direc_flag = 0; //占空比调节比对值,0为增加,1为减少
sbit LED = P1 ^ 3; //定义呼吸灯接口
void timer0_init() {
TMOD = 0x11;
TH0 = (65536 - 46) / 256;
TL0 = (65536 - 46) % 256;
TH1 = (65536 - 11520) / 256;
TL1 = (65536 - 11520) % 256;
EA = 1;
ET0 = 1;
ET1 = 1;
TR1 = 1;
TR0 = 1;
PWM_COUNT = 0; //初始化定时器
}
void time0()interrupt 1 {
TH0 = (65536 - 46) / 256;
TL0 = (65536 - 46) % 256;
PWM_COUNT++;
if (PWM_COUNT == PWM_VALUE) {
LED = 1;
}
if (PWM_COUNT == 40) {
LED = 0;
PWM_COUNT = 0;
}
}
void time1()interrupt 3 {
TH1 = (65536 - 11520) / 256;
TL1 = (65536 - 11520) % 256;
HUXI_COUNT++;
}
void main() {
LED = 1;
while (1) {
XUNHUAN = 1;
if (HUXI_COUNT == 5 && direc_flag == 0) {
HUXI_COUNT = 0;
PWM_VALUE = PWM_VALUE + 2;
ljk++;
}
if (ljk == 40) direc_flag = 1;
if (HUXI_COUNT == 5 && direc_flag == 1) {
HUXI_COUNT = 0;
PWM_VALUE = PWM_VALUE - 2;
ljk++;
}
if (ljk == 80) {
direc_flag = 0;
ljk = 0;
PWM_VALUE = 2;
}
}
}