呼吸灯的实现

最近调了一款耳机,客户要求做呼吸灯,在连接之后红蓝灯交替呼吸,具体实现如下:

首先,创建变量:

u16 count = 0;         //控制PWM低电平值
u8 tick_flag = 0;        //控制灯亮的模式(变亮阶段还是变暗阶段)
u8 test_flag = 0;        //关断控制位,使每次只关一次
u8 flip_led_timer = 0;    //呼吸灯动作标志位

之后需要将灯光控制的函数关掉:
Bsp_sys.c下usr_tmr5ms_isr()中:

	if(!bt_nor_is_connected())
	{
	//这里会调用底层的中断,灯光就会由底层中断来控制
	    led_scan();
	    led_sync();
	}

接下来就是呼吸灯的初始化:

//timer3 pwm(pwm0: PA6:1  ,   pwm1: PA7:2  ,  pwm2: PB3:3)
void timer3_pwm_init(void)
{
	FUNCMCON2 = (1 << 8);       //多个IO口时使用这个
//	FUNCMCON2 = (3 << 8);       //单个IO口时使用这个,即对应的数字,这里是PB3
	CLKGAT1 |= BIT(8);          //时钟
//相当于设置PWM低电平的值
//low level: TMR3DUTY0 + 1, 
//high level: TMR3PR-TMR3DUTY0+1
	TMR3CNT = 0;               //初始值 
	TMR3PR	= (1000*3)-1;      //PWM的周期
	TMR3DUTY0 = 3000 - 1;	   //pwm0 duty - PA6
	TMR3DUTY1 = 3000 - 1;      //pwm1 duty - PA7
	TMR3DUTY2 = 3000 - 1;	   //pwm2 duty - PB3
//timer3 pwm0(bit9), pwm1(bit10), pwm2 enable(bit11)
	TMR3CON |= BIT(9) | BIT(10) | BIT(11);	
//timer increase clk, 1:select xosc26_div 1MHz, 0:select sysclk 26MHz
	TMR3CON |= BIT(2);        //时钟
	TMR3CON |= BIT(0);        //Timer enable;unable:‘TMR3CON &=~BIT(0);’
}

接下来就是呼吸灯的实现:

//呼吸灯的每次PWM复制,这里使用的IO口为PB3、PA7
void flip_led()
{
	if(tick_flag == 0 || tick_flag == 1)//开PB3的呼吸灯,关PA7的使能
	{
		GPIOBDE |= BIT(3);
		GPIOBDIR &= ~BIT(3);
		GPIOBFEN |= BIT(3);       //使能特殊功能
		TMR3CON |= BIT(9)|BIT(10)|BIT(11);

		if(test_flag == 0)//关一次即可
		{
			test_flag = 1;
			GPIOADE |= BIT(7);
			GPIOAFEN &= ~BIT(7);	
			GPIOADIR |= BIT(7);
			GPIOACLR = BIT(7);
			TMR3DUTY1 = 3000;
		}
	}
	else//开PA7的呼吸灯,PB3关的使能
	{
		GPIOADE |= BIT(7);
		GPIOADIR &= ~BIT(7);
		GPIOAFEN |= BIT(7);	
		TMR3CON |= BIT(9)|BIT(10)|BIT(11);
		
		if(test_flag == 1)//关一次即可
		{
			test_flag = 0;
			GPIOBDE |= BIT(3);
			GPIOBFEN &= ~BIT(3);
			GPIOBDIR |= BIT(3);
			GPIOBCLR = BIT(3);
			TMR3DUTY2 = 3000;
		}
	}
	if(tick_flag == 0)
	{
		if(count > 5)
		{
			count-=5;
			TMR3DUTY2 = count;
		}
		else
		{
			count = 0;
			TMR3DUTY2 = 0;
			tick_flag = 1;
		}
	}
	else if(tick_flag == 1)
	{
		if(count < 3000)
		{
			count+=5;
			TMR3DUTY2 = count;
		}
		else
		{
			count = 3000;
			TMR3DUTY2 = 3000;
			tick_flag = 2;
		}
	}
	else if(tick_flag == 2)
	{
		if(count > 5)
		{
			count-=5;
			TMR3DUTY1 = count;
		}
		else
		{
			count = 0;
			TMR3DUTY1 =0;
			tick_flag = 3;
		}
	}
	else if(tick_flag == 3)
	{
		if(count < 3000)
		{
			count+=5;
			TMR3DUTY1 = count;
		}
		else
		{
			TMR3DUTY1 = 3000;
			tick_flag = 0;
		}
	}
}

最后就是调用了:
普通蓝牙模式下:func_bt.c下func_bt()的while循环中:

//条件满足,呼吸灯动作
	if(flip_led_timer == 1)
	{
		flip_led();
		delay_ms(5);//控制呼吸的快慢
	}
//控制初始化及呼吸灯条件
	if(bt_nor_is_connected())
	{
		if(!flip_led_timer)
		{
			flip_led_timer = 1;
			timer3_pwm_init();
		}
	}
	else
	{
		flip_led_timer = 0;
	}

蓝牙耳机通话的时候:sfunc_bt_call.c下sfunc_bt_call()的while循环中:

if(flip_led_timer == 1)
	{
		flip_led();
		delay_ms(4);//控制呼吸的快慢
	}

这里有一些需要注意的:
①:中断的底层调用需要在呼吸的时候屏蔽,不然的话会导致呼吸灯不起作用;
②:对寄存器的赋值必须去while循环中处理,不能在中断处理,会导致底层报错“ERROR ======> timer_thread miss: ”;

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值