单片机源程序如下:
#include
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
ulong cnt;
uint cnt_T1, high, low;
uchar TH0_H, TL0_H, TH0_L, TL0_L, T1H1, T1L1, flag = 0;
uchar duty[19] = {5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95};
sbit out = P3^7;
uchar shuying = 0;
void delay_fy(uchar fy, uchar dy);
void time_1(uchar ms);
void sm_du(uchar dy);
void main()
{
TMOD = 0X11; // 定时器0/1都工作在方式1,是2^16计数
EA=1;
delay_fy(100, 5);
time_1(50);
while(1);
}
void delay_fy(uchar fy, uchar dy) // 输入频率fy,占空比dy
{
cnt = (11059200/fy)/12; // 要产生频率为fy,定时器0所要计的数值
high = (cnt*dy)/100; // 计算出高电平所要计的数值
low = cnt - high; // 计算出低电平所要计的数值
high = 65536 - high; // 确定定时器0,从哪个初值开始计时,记录的是高电平
low = 65536 - low; // 确定定时器0,从哪个初值开始计时,记录的是低电平
TH0_H = (uchar)(high>>8); // 高电平,给TH0预备重装初值
TL0_H = (uchar)high; // 高电平,给TL0预备重装初值
TH0_L = (uchar)(low>>8); // 低电平,给TH0预备重装初值
TL0_L = (uchar)low; // 低电平,给TL0预备重装初值
TH0 = TH0_H;
TL0 = TL0_H;
out = 1;
ET0 = 1;
TR0 = 1;
}
void time_1(uchar ms)
{
ulong temp;
temp = 11059200/1000;
temp = (temp*ms)/12;
cnt_T1 = 65536 - temp;
T1H1 = (uchar)(cnt_T1>>8);
T1L1 = (uchar)cnt_T1;
TH1 = T1H1;
TL1 = T1L1;
ET1=1;
TR1=1;
}
void sm_du(uchar dy)
{
high = (cnt*dy)/100;
low = cnt - high;
high = 65536 - high;
low = 65536 - low;
}
void time_0() interrupt 1
{
if(out==0) // 准备产生高电平
{
TH0 = TH0_H; // 高电平产生 初值重装
TL0 = TL0_H;
out = 1;
}
else
{
TH0 = TH0_L; // 低电平产生 初值重装
TL0 = TL0_L;
out = 0;
}
}
void T1_Timer1() interrupt 3
{
TH1 = T1H1;
TL1 = T1L1;
sm_du(duty[shuying]);
if(0 == flag) // flag=0时,表示呼吸灯由暗变亮
{
shuying++;
if(shuying >=18)
{
flag = 1;
}
}
}
}