打印
[应用相关]

如何同时控制多个LED按规律闪烁

[复制链接]
3729|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
28027上有4个LED,如何同时控制多个LED按规律闪烁啊,求大神指导如何编程!
沙发
handleMessage| | 2018-3-5 21:25 | 只看该作者
主要还是通过不同的不同的定时器功能实现   

使用特权

评论回复
板凳
zhouhuanの| | 2018-3-5 21:31 | 只看该作者
你这个“规律”范围太大了,跑马灯,同时闪烁或者你自定义的闪烁规则.

使用特权

评论回复
地板
wanglaojii| | 2018-3-5 21:34 | 只看该作者
对准io,要么while+延时,要么定时器中断里,给高低电平就行了......

使用特权

评论回复
5
laozhongyi| | 2018-3-5 21:36 | 只看该作者
主要还是通过不同的不同的定时器功能实现

使用特权

评论回复
6
小明的同学| | 2018-3-5 21:38 | 只看该作者
莫非你是菜鸟

使用特权

评论回复
7
小明的同学| | 2018-3-5 21:38 | 只看该作者
你让显示顺序放个数组里,然后定时调用

使用特权

评论回复
8
Edisons| | 2018-3-5 21:39 | 只看该作者
多个定时器同时启用的,或者一个定时器 的最小单位的实现中断计时的,然后分配好个LED的闪亮时间的。

使用特权

评论回复
9
_gege| | 2018-3-5 21:44 | 只看该作者
使用定时器,延时都可以的。

使用特权

评论回复
10
xixi2017| | 2018-3-6 07:24 | 只看该作者
需要你学习io操作和定时器了

使用特权

评论回复
11
lihui567| | 2018-3-6 10:40 | 只看该作者
用定时器中断或者滴答定时器都可以实现

使用特权

评论回复
12
springvirus| | 2018-3-6 11:11 | 只看该作者
若想同时让N个LED以N个不同频率闪烁,可以考虑引入嵌入式操作系统,每个线程(任务)里加入延时函数
入口的实参m值根据你的延时函数和闪烁频率来确定
while(1)
{
    led_on();
    delay(m);
   led_off();
   delay(m);
}

非常好用,试试吧~

使用特权

评论回复
13
huangcunxiake| | 2018-3-6 17:23 | 只看该作者
一、库开发

这里指的库开发使之调用库函数接口完成对相应寄存器的设置,相比较与51单片机编程中直接对寄存器操作而言,代码量跟查找手册看寄存器位再去配置,能节约很多时间。但是相对的对寄存器的位操作看得就没拿明白了,不知道库函数接口是如何配置各个寄存器位的了,这个时候可以将函数名复制下来去STM32固件库使用手册中查看相应了用法了。如下图所示复制了库函数之后,打开STM32固件库使用手册,复制到这里





然后回车,就会跳到相应的库函数说明那里,一下就清楚了它是如何配置寄存器位的,如下图




这个函数解释的很清楚了,使能和失能APB1的外设时钟,如果不理解参数是什么,可以复制参数能在末尾的表中找到相应的参数解释。

说一下我对库开发的理解,最好的办法就是在别人的例程上修改,节约时间,框架已经搭建好了,只用配置成和自己开发板对应的就行了。这是上上之策,新手最好选择这个办法,现在网上的例程还是挺多的,不然作为一个连函数名都不知道的新手难道要去固件库一个一个翻看函数,浪费时间不说,还不一定有效果,太打消积极性了。至于对寄存器直接进行配置,我个人不反对也不支持,感觉各有各的优点,如果你老手了,可以建议选择用直接配置寄存器去写程序,这样代码自己看得清晰明了。下图显示了库开发个直接配置寄存器开发的区别



关于ST库的文件介绍可参考原子的:原子教你玩转STM32初级篇,写的很详细,我在昨天的第一讲里面已经给出下载地址了,这里在贴一遍:http://pan.baidu.com/s/1kTgI7Y3


二、点亮流水灯
首先我们需要用到第一讲中的建立好的模板,这里我一步一步很详细的教你如何去点亮流水灯
1. 看开发板原理图找到LED灯连接的GPIO( 通用输入输出)口,我这里使用的是神州三号开发板,


可以看到,对应 GPIO分别为GPIOF6 GPIOF7 GPIOF8 GPIOF9,而且是上拉输入,只要控制GPIO端为低电平,就会点亮LED了,为高电平,LED灭。
找到了对应的GPIO了,然后该用到我们的模板了,这个时候新手可能会问该从哪里下手啊,怎么配置GPIO啊,用什么函数啊等等。方法就是我上面说的上上之策:使用别人写好例程框架,修改成自己的。又会问:拿第一讲新建的工程模板不就用不到了?此言差矣,个人认为新建工程模板不仅能让初学者弄清楚各个文件的作用,而且对库开发整体的框架理解会更加深入,最好是对照例程将别人的程序在自己的工程模板中重新编写一份,这样你对各个函数会更加熟悉,基本框架也会有自己的理解。

下面开始介绍如何编写程序,首先打开别人的例程,看到工程文件目录



可以看到在工程目录下USER目录下相比于我们自己建立的工程模板多了led.c led.h两个文件,没错,这就是我们需要编写的两个文件,首先打开led.h

看到代码如下:
led.h

#ifndef __LED_H
#define __LED_H

#include "stm32f10x.h"
#define ON  0
#define OFF 1

#define LED1(a) if (a)
          GPIO_SetBits(GPIOF,GPIO_Pin_6);
          else
          GPIO_ResetBits(GPIOF,GPIO_Pin_6)
        
#define LED2(a) if (a)
          GPIO_SetBits(GPIOF,GPIO_Pin_7);
          else
          GPIO_ResetBits(GPIOF,GPIO_Pin_7)
         
#define LED3(a) if (a)
          GPIO_SetBits(GPIOF,GPIO_Pin_8);
          else
          GPIO_ResetBits(GPIOF,GPIO_Pin_8)
        
#define LED4(a) if (a)
          GPIO_SetBits(GPIOF,GPIO_Pin_9);
          else
          GPIO_ResetBits(GPIOF,GPIO_Pin_9)
         
void LED_GPIO_Config(void);        

#endif


这里用到了两个库函数和一个用户自定义函数
分别是:GPIO_SetBits(GPIOF,GPIO_Pin_x);
              GPIO_ResetBits(GPIOF,GPIO_Pin_x);
              void LED_GPIO_Config(void);  
很明显前面两个是对相应的GPIO管脚进行配置高地电平的,Set = 1 , Reset = 0
同时看上的宏定义和条件编译,LED(ON)显然就是对应的GPIO_ResetBits(GPIOF,GPIO_Pin_x);为什么呢?因为前面已经介绍过电路原理图了,低电平是点亮LED,所以Reset对应的是LED(ON);

接下来我们去看看led.c中用户自定义的函数是如何编写的吧

led.c
#include "led.h"
void LED_GPIO_Config(void)
{

GPIO_InitTypeDef GPIO_InitStructure;


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;


GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;


GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;


GPIO_Init(GPIOF,&GPIO_InitStructure);


GPIO_SetBits(GPIOF,GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9);
}



虽然上面有注释了,我还是一句一句来讲解下
1. 定义了一个GPIO_InitTypeDef类型的结构体,要想看到结构体中的内容,可以从stm32f10x.h中找到其结构体内部包含了哪些变量
2. 开启GPIOF的外设时钟,为什么要开启外设时钟呢?这里有必要解释一下,因为STM32为了实现低功耗,设计了很复杂的时钟系统,每个外设配置使用前都要开启外设时钟,如果对stm32时钟树不是很了解,去看看STM32中文参考手册吧,里面很详细的介绍了STM32时钟。
3. 连着看下面的三句,选择要控制的GPIOF引脚、设置引脚模式为通用推挽输出、设置引脚速率为50MHz。这里是选择对应的GPIO管脚,设置输出方式和配置引脚速率,因为stm32的GPIO有8中工作方式,不详细介绍了,可自行去看stm32中文参考手册。 出现了两个新的结构体GPIO_InitStructure.GPIO_Mode 和GPIO_InitStructure.GPIO_Speed,找其出处参考前面寻找GPIO_InitTypeDef
4.  GPIO_Init(GPIOF,&GPIO_InitStructure);很明显是把上面配置的信息写入这个结构体中,也叫对引脚配置的初始化
5. 置为高电平,关闭LED灯

照着上面的例子将看是否对应你自己开发板的GPIO和LED,如果不会一样的,修改GPIO引脚就可以了,别忘了led.h中也要修改,等修改成中自己开发板对应的之后,我们去写main函数,因为我们知道,程序的起点是从main函数开始执行的
main.c

#include "stm32f10x.h"
#include "led.h"

void Delay(__IO u32 nCount);


int main(void)
{

LED_GPIO_Config();

while(1)
{
  LED1(ON);
  Delay(0x0FFFEF);
  LED1(OFF);
  
  LED2(ON);
  Delay(0x0FFFEF);
  LED2(OFF);
  
  LED3(ON);
  Delay(0x0FFFEF);
  LED3(OFF);
  
  LED4(ON);
  Delay(0x0FFFEF);
  LED4(OFF);
}
}

void Delay(__IO u32 nCount)
{
for(; nCount !=0; nCount--);
}


这个程序就不详细介绍了,就是点亮一个灯,延时然后关掉,唯一要是的是延时程序中 __IO u32这个数据类型,32对应就是32位数据了,我们使用库开发时,库文件中已经把原本的unsigned intchar宏定义为u32 u16 u8等等数据类型了,这样我们使用起来是不是很方便,这就是库开发的好处之一了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

293

主题

1811

帖子

1

粉丝