本实验是基于STC8A8K64S4A12上的
呼吸灯,顾名思义就是灯的亮度像人的呼吸一样有节奏的由暗到亮,再又亮到暗,在现代手机中被广泛的应用。
一般来说现在的单片机都带有PWM所以直接用就好了,这里就不对这个做介绍了,这里我们是使用定时器来模拟实现的。
PWM(脉冲宽度调制)对模拟信号电平进行数字编码的方法,计算机只能输出0或5V的数字电压值而不能输出模拟电压,而我们如果想获得一个模拟电压值,则需通过使用高分辨率计数器,改变方波的占空比来对一个模拟信号的电平进行编码。通过对连接和断开时间的控制,只要带宽足够,可以输出任意不大于最大电压值的模拟电压。
与之相对应的公式为:
输出电压=(接通时间/脉冲时间)*最大电压值
这样的话我们可以操作高低电平在相同的带宽内输出不同的电压,从而达到一个连续变化的电压(模拟量),这样就可以满足呼吸灯的效果了。
软件驱动
首先一些变量的声明和初始化一个定时器:
unsigned char PWM_COUNT; //计数
unsigned int HUXI_COUNT; //占空比更新时间
unsigned char PWM_VLAUE; //占空比比对值
bit direc_flag; //占空比更新方向
void Timer5Init(void) //200微秒@24.000MHz
{
AUXR &= 0xFB; //定时器时钟12T模式
T2L = 0x70; //设置定时初值
T2H = 0xFE; //设置定时初值
AUXR |= 0x10; //定时器2开始计时
}
这里没有开中断,一会儿会在主循环里开,下面是中断的处理函数
void TM2_Isr() interrupt 12
{
// printf("hello timer2222\r\n");
PWM_COUNT++;
HUXI_COUNT++;
if(PWM_COUNT == PWM_VLAUE) //判断是否到了点亮LED的时候
M_LED_K1_OUT_OFF; //点亮LED
if(PWM_COUNT == 10) //当前周期结束
{
M_LED_K1_OUT_ON; //熄灭LED
PWM_COUNT = 0; //重新计时
}
if((HUXI_COUNT == 600) && (direc_flag == 0))
{ //占空比增加10%
HUXI_COUNT = 0;
PWM_VLAUE++;
if(PWM_VLAUE == 9) //占空比更改方向
direc_flag = 1;
}
if((HUXI_COUNT == 600) && (direc_flag == 1))
{ //占空比减少10%
HUXI_COUNT = 0;
PWM_VLAUE--;
if(PWM_VLAUE == 1) //占空比更改方向
direc_flag = 0;
}
AUXINTIF &= ~T2IF; // 清中断标志
}
主函数如下:
void main (void)
{
HUXI_COUNT = 0;
PWM_COUNT = 0;
PWM_VLAUE = 5;
LED_init();
Timer5Init();
IE2 = ET2;
EA = 1;
for(;;)
{
}
}
这样就OK了,希望对你们有帮助。
来源:CSDN
作者:I_AM_JOKER
链接:https://blog.csdn.net/I_AM_JOKER/article/details/104051097