#include<reg51.h>
#include "PWM.h"
#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned long
sbit PWMOUT1 = P3^2;
sbit PWMOUT2 = P3^3;
u32 PeriodCnt = 0;
u8 HighRH = 0;
u8 HighRL = 0;
u8 LowRH = 0;
u8 LowRL = 0;
u8 T0RH = 0;
u8 T0RL = 0;
unsigned char j;
void ConfigPWM(u16 fr, u8 dc);
void ConfigTimer0(u16 ms);
void delay(unsigned int i);
void AdjustPWM(u8 dc);
//T2产生PWM波,T0来查表法改变占空比
void main()
{
EA = 1;
P1 = 0xFF;
P3 = 0xFF;
P5 = 0xFF;
ConfigPWM(100, 16);
ConfigTimer0(50);
while(1);
}
void ConfigPWM(u16 fr, u8 dc)
{
u16 high, low;
PeriodCnt = (11059200/12)/fr; //计算一个周期所有需的计数值。
high = (PeriodCnt*dc)/100; //计算高电平所需要的计数值。
low = PeriodCnt - high; //计算低电平所需要的计数值。
high = 65536 - high; //高电平定时器重载值。
low = 65536 - low; //低电平定时器重载值。
HighRH = (u8)(high>>8);
HighRL = (u8)high;
LowRH = (u8)(low>>8);
LowRL = (u8)low;
T2H = (u8)(high>>8); //定时器重载值拆分为高低字节
T2L = (u8)high;
AUXR |= 0x14; //辅助寄存器不12分频
IE2 |= 0X04; //使能T2定时器中断
}
void InterruptTimer2() interrupt 12
{
if(PWMOUT1 == 1)
{
T2H = LowRH;
T2L = LowRL;
PWMOUT1 = 0;
PWMOUT2 = 0;
PWMOUT3 = 0;
}
else
{
T2H = HighRH;
T2L = HighRL;
PWMOUT1 = 1;
PWMOUT2 = 1;
PWMOUT3 = 1;
}
}
void ConfigTimer0(u16 ms)
{
u32 tmp;
tmp = 11059200;
tmp = (tmp*ms)/1000;
tmp = 65536 - tmp;
T0RH = (u8)(tmp >> 8);
T0RL = (u8)tmp;
TH0 = T0RH >>8;
TL0 = T0RL;
TR0 = 1; //定时器开始计时
ET0 = 1; //使能定时器0中断
}
void InterruptTimer0() interrupt 1
{
static u8 dir = 0;
static u8 index = 0;
u8 code Table[] = {
16,16,17,17,18,18,19,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,
52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100
}; //48次循环
AdjustPWM(Table[index]);
if(dir == 0)
{
index++;
if(index == 47)
dir = 1;
}
if(dir == 1)
{
index--;
if(index == 0)
dir = 0;
}
}
void AdjustPWM(u8 dc)
{
u16 high, low;
high = (PeriodCnt*dc)/100; //高电平所需要的计数值。
low = PeriodCnt - high; //低电平所需要的计数值。
high = 65536 - high; //电高平计数初值。
low = 65536 - low; //低电平计数初值。
HighRH = (u8)(high>>8); //定时器高电平总数重载值拆分为高低字节
HighRL = (u8)high;
LowRH = (u8)(low>>8); //定时器低电平总数重载值拆分为高低字节
LowRL = (u8)low;
}
void delay(unsigned int i) //延时毫秒
{
for(i=0;i<100;i++) {;}
}
//可以在这个基础上优化吗?谢谢!!
我这个程序已经实现单个灯的呼吸效果了,加上流水是否就可以实现波浪呼吸效果呢?如何加呢?
追答本质就是8路pwm输出,流水效果可以通过一个8*128(即8灯,每个128种状态循环)的数组完成,每运行一段时间换一组,控制每个pwm。。。虽然我想这么说,但是如果手打确实很累。所以,你可以实时计算这个数组(8个元素),可以定时器中断,每10ms对其更新,然后主函数里面尽可能快地跑pwm。算法是核心。简化就是把所有比较在一起做,不用每个pwm输出单独做。反正我就差不多这个思路,也没做过,你可以试试看