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;
- }
- }
- }