基于STM32的LED实战 -- 流水灯、呼吸灯、流水呼吸灯
·

🌈个人主页:羽晨同学
💫个人格言:“成为自己未来的主人~”

驱动LED
// LED1: PE9
// LED2: PB1
// LED3: PB0
这个是我们板子上的三个LED灯分别对应的引脚名称。
首先,我们需要对这三个引脚进行初始化
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = LED1_PIN;
GPIO_Init(LED1_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LED2_PIN;
GPIO_Init(LED2_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LED3_PIN;
GPIO_Init(LED3_PORT, &GPIO_InitStructure);
以上的这些为引脚初始化的代码。
接下来,我们对引脚赋高低电平,就可以使得对应LED灯进行亮灭闪烁。
while (1)
{
GPIO_SetBits(LED1_PORT, LED1_PIN);
cpu_delay();
GPIO_ResetBits(LED1_PORT, LED1_PIN);
cpu_delay();
}
如果这个时候要是没有 cpu_delay();的话,我们会看到LED灯是保持常亮的,这个是因为stm32f407本身的主频就比较大(有168MHz),CPU执行的速度很快,所以我们需要加上一个对应的延时函数。
void cpu_delay(void)
{
uint32_t delay = 168 * 1000 * 10;
for (uint32_t t = 0; t < delay; t++) { ; }
}
这样,我们就实现了对应的LED灯的闪烁。
三个LED灯同时闪烁的原理也是如此
while (1)
{
GPIO_SetBits(LED1_PORT, LED1_PIN);
GPIO_SetBits(LED2_PORT, LED2_PIN);
GPIO_SetBits(LED3_PORT, LED3_PIN);
cpu_delay();
GPIO_ResetBits(LED1_PORT, LED1_PIN);
GPIO_ResetBits(LED2_PORT, LED2_PIN);
GPIO_ResetBits(LED3_PORT, LED3_PIN);
cpu_delay();
}
流水灯
为了方便查看,我们修改一下我们的呈现方式
static void led_set(uint8_t led, uint8_t state)
{
if (led == 1)
{
GPIO_WriteBit(GPIOE, GPIO_Pin_9, state ? Bit_RESET : Bit_SET);
}
else if (led == 2)
{
GPIO_WriteBit(GPIOB, GPIO_Pin_1, state ? Bit_RESET : Bit_SET);
}
else if (led == 3)
{
GPIO_WriteBit(GPIOB, GPIO_Pin_0, state ? Bit_RESET : Bit_SET);
}
}
有了这个函数之后,我们就可以通过以下方式来实现流水灯的效果。
首先,我们先让三个灯全部熄灭
led_set(1, 0);
led_set(2, 0);
led_set(3, 0);
然后,我们实现流水灯的效果
uint32_t ledidx = 1;
while (1)
{
led_set(ledidx, 1);
cpu_delay();
led_set(ledidx, 0);
if (++ledidx > 3)
{
ledidx = 1;
}
}
这样子,我们就可以实现流水灯的效果了。
呼吸灯
呼吸灯就是LED的渐灭和渐亮的过程,我们要利用的便是周期和占空比。
这个灯的亮度是由亮的时间和灭的时间来进行确定的,如果亮的时间长一些,灭的时间短一些,总体看上来就会更亮一些。
所以,我们可以采用除了PWM的方法的另外一个方式来实现这个效果:
while (1)
{
int period = 2000;
for(int d = 0;d<period;d++)
{
led_set(1,1);
for(int i = 0;i<d;i++);
led_set(1,0);
for(int i = d;i<period;i++);
}
}
浪潮灯
要实现浪潮灯,我们先来使得三个LED灯的亮度不一样,那应该怎么做呢?
当LED1低于20的时候,让LED1亮,当LED2低于40,LED3低于60的时候,让这三个亮,我们就能大概实现出来三个LED亮度不一样的效果
代码如下:
led_set(1, i < led1_duty ? 1 : 0);
led_set(2, i < led2_duty ? 1 : 0);
led_set(3, i < led3_duty ? 1 : 0);
所以,最终代码如下:
//软件模拟PWM
//设置频率
int period = 250;
//设置led的占空比
int led1_duty = 0, led2_duty = period * 25 / 100, led3_duty = period * 50 / 100;
int led1_inc = 1, led2_inc = 1, led3_inc = 1;
while (1)
{
//输出比较,向上计数,i < 占空比时置低电平,灯亮
for (int i = 0; i < period; i++)
{
led_set(1, i < led1_duty ? 1 : 0);
led_set(2, i < led2_duty ? 1 : 0);
led_set(3, i < led3_duty ? 1 : 0);
}
//占空比在0-100%period中自增或自减
led1_duty += led1_inc;
led2_duty += led2_inc;
led3_duty += led3_inc;
if (led1_duty >= period || led1_duty < 0) led1_inc = -led1_inc;
if (led2_duty >= period || led2_duty < 0) led2_inc = -led2_inc;
if (led3_duty >= period || led3_duty < 0) led3_inc = -led3_inc;
}

更多推荐



所有评论(0)