软件实现PWM信号,LED闪烁

【原创作品,转帖注明出处:blog.csdn.net/lanmanck】


假设一个GPIO接了一个LED,低电平就点亮LED。现在使用一个定时器,来实现LED的各种闪烁状态。

又假设一个闪烁波形为:1秒内闪2次,如下:

----|       |-----|       |-------------------

     |___|       |___|

     |(起始处)------------------------>|(1秒到)


我把每次定时器进来叫做一个step,这里假设定时器时间为100ms,以step为单位定义整个周期为total_period,定义亮的时间为on_period,定义灭的时间为off_period。

最后,还要定义亮多少次为blink_cnt.

因此,如果定义一个周期为1秒,则1个total_period=1000/100ms=10个step,这样比较好计算。例如上述波形,假设:

亮200ms,灭200ms,亮2次。

total_period = 1000/100ms=10,

on_period=200ms/100ms=2,

off_period=200ms/100ms=2.

变量定义好了,说下产生波形的思路。定义好一个数组,用来记录哪个step需要亮灯:

u8 steps_on[128];

例如上面波形,steps_on[0/1/4/5]都等于1表示亮灯,然后呢,在定时器里面每次step++,如果发现steps_on[step]==1,那就置低电平让LED亮,这就可以了!

那么,如何初始化steps_on[]呢?看代码:

int i,j,b_cnt=0,continue_cnt=0;
	for(i=0;i<total_period;i++){
		j = i%(on_period+off_period);

		/* 一个周期的开始 */
		if(j==0){
			if(b_cnt<blink_cnt){
				continue_cnt = 0;
				b_cnt++;

				if(continue_cnt<on_period){
					continue_cnt++;
					steps_on[i] = 1;
				}
			}
		}else {
			if(continue_cnt<on_period){
				continue_cnt++;
				steps_on[i] = 1;
			}
		}
	}

大体思路如下,在每次开始我就认为要点亮,然后记录这个step,因为点亮有时间,则使用on_period看到了没有,没有就记录一次,下次重复波形的时候就检查

是不是闪烁的次数够了,不够就继续记录。

最后实现定时器函数,比较简单了:

static int led_status=LED_STATUS_OFF;

	if(steps_on[steps] == LED_STATUS_ON){
		if(led_status!=LED_STATUS_ON){
			led_status = LED_STATUS_ON;
			led_on(GPIO_LED);
		}
	}
	else{
		if(led_status!=LED_STATUS_OFF){
			led_status = LED_STATUS_OFF;
			led_off(GPIO_LED);
		}
	}

	steps++;
	steps %= total_period;

讲的不是很明白,有问题欢迎探讨哈!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值