本实验是基于STC8A8K64S4A12上的

呼吸灯,顾名思义就是灯的亮度像人的呼吸一样有节奏的由暗到亮,再又亮到暗,在现代手机中被广泛的应用。

一般来说现在的单片机都带有PWM所以直接用就好了,这里就不对这个做介绍了,这里我们是使用定时器来模拟实现的。

 PWM(脉冲宽度调制)对模拟信号电平进行数字编码的方法,计算机只能输出0或5V的数字电压值而不能输出模拟电压,而我们如果想获得一个模拟电压值,则需通过使用高分辨率计数器,改变方波的占空比来对一个模拟信号的电平进行编码。通过对连接和断开时间的控制,只要带宽足够,可以输出任意不大于最大电压值的模拟电压。

与之相对应的公式为:

                  输出电压=(接通时间/脉冲时间)*最大电压值

android 呼吸view 安卓呼吸灯怎么设置_呼吸灯

这样的话我们可以操作高低电平在相同的带宽内输出不同的电压,从而达到一个连续变化的电压(模拟量),这样就可以满足呼吸灯的效果了。

软件驱动

首先一些变量的声明和初始化一个定时器:

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了,希望对你们有帮助。