嵌入式学习---LED篇

(本教学基于标准固件库)

目录

1.了解原理

2.看电路图

3.编写代码

3.1 选择GPIO

3.2 配置并初始化GPIO

3.3 使能时钟

3.4 设置初始状态


学习嵌入式,做的第一个小项目几乎都是点亮一颗LED灯。

为什么要从点亮一颗灯开始呢?

其实把这颗灯点亮是很简单的。

但是在这简单的操作之下,却涵盖了单片机最基础最广泛使用的GPIO资源、时钟资源、以及嵌入式开发的基本配置流程、硬件电路的熟悉等。

一个简单的点灯,不仅使初学者掌握了包括编写代码、编译、下载到硬件平台、调试等嵌入式开发步骤,对嵌入式开发有了一个基本的了解,还增强了初学者的信心,激发了他们深入学习嵌入式的兴趣。

那么作为一个新手,在拿到板子,建立了基础工程后,该如何点亮一颗LED灯呢?

1.了解原理

作为一个嵌入式新手小白,或者说其他领域的小白,我们在做之前肯定要了解它最基本的东西,在嵌入式这边,就是要先了解硬件运作的基本原理。

对于LED灯的话,它的原理很简单:就是高低电平点亮。

详细讲解:

  • 就像我们所了解的基本电路常识一样,一个电路最起码要有正极、负极、负载。一边是正,一边是负,这样电路才能导通,并使电流流动,电流流过负载,负载工作。
  • 而不同之处在于,嵌入式使用的是高低电平来点亮LED,什么是高低电平呢?高低电平是数字电子电路中用来表示逻辑状态的两种电压水平,高低电平一般对应着逻辑“1”和逻辑“0”。在不同的系统中,高低电平的标准不太一样,在嵌入式系统中,一般用的都是3.3V的CMOS电路,高电平大约 3.0V 至 3.3V,低电平大约 0V 至 0.3V。

嵌入式系统正是通过GPIO引脚发出高低电平,控制LED的亮灭。

2.看电路图

了解了基本原理,那么我是发出高电平点亮灯呢,还是发出低电平点亮灯呢?

这就需要我们知道它的电路设计是怎样的。

如何了解它的电路设计?其实有多种方法,如:查看原理图,直接观察电路,用万用表测量等等。

在这里就讲最简单、最常规的方法---查看原理图,(其他方法虽然不同,但是都是同样的目的)。

新买的板子,都配的有原理图,直接打开,找到LED电路,观察电路连接:

低电平点亮

  • 电路连接:LED 的负极连接到 GPIO 引脚,正极连接到电源,中间串连一个限流电阻。
  • 点亮方式:GPIO 输出低电平,LED 点亮。

高电平点亮

  • 电路连接:LED 的正极连接到 GPIO 引脚,负极连接到地,中间串连一个限流电阻。
  • 点亮方式:GPIO 输出高电平,LED 点亮。

3.编写代码

在确定了点亮LED灯的电平之后,就可以编写代码了。

假设我们是低电平点亮。代码编写思路及步骤如下:

3.1 选择GPIO

很好理解,我们选择一个GPIO,也就是通用输入输出口,比如我选择PA0。就意味着我将用PA0这个口来输出高低电平,从而控制LED灯的亮灭。



3.2 配置并初始化GPIO

这就涉及到使用ST官方提供的有关于GPIO控制的函数(即标准固件库函数)。

找到stm32f10x_gpio.h这个头文件,点进去会发现有很多宏和函数声明。这里先讲用到的几个宏和函数,其他的可以通过翻译注释或数据手册或网上资源来理解。(其实我的建议是最好先把这个头文件的内容自己看一遍,了解一下其大概内容)。

如下图1:首先通过行号找到这个结构体,这是一个GPIO初始化的结构体,我们就是通过配置结构体内的这些参数,来设置GPIO的属性并控制GPIO的。

它的三个参数分别是:

  • GPIO_Pin  就是你选择哪个引脚,就填哪个引脚号,如我们选的是PA0,就填GPIO_Pin_0;
  • GPIO_Speed  就是这个引脚的输出速率 ,选50MHz就行,大多数时候不作过多关注;
  • GPIO_Mode  就是这个引脚的输入输出模式。共有8种输入输出模式,4种输入,4种输出,鉴于这期的主题就不再细讲这些,先记住最常用的就是推挽输出。它就是输出高和低,我们既要输出高电平,又要输出低电平,因此选择推挽输出。选择GPIO_Mode_Out_PP;

 GPIO 初始化结构体

GPIO_Pin  引脚号宏

 GPIO_Speed  输出速率宏

GPIO_Speed  模式宏  



配置完成后,我们要用一个初始化函数把配置加载到相关寄存器,这样我们的配置才会生效。还是在这个头文件,拉到最下面,找到如下图所示函数:

函数1 就是用来初始化配置的,2是输出一个高电平,3是输出一个低电平。



3.3 使能时钟

时钟的概念在后面会详细讲,在这里只需要记住,用一个外设的功能,就要使能对应的时钟。我们使用了GPIO,就要使能GPIO的时钟。

 GPIO的时钟是有多个划分的,我们知道一个STM32芯片有多个GPIO引脚,每个引脚都分配了0~15的引脚号,这些引脚分属不同的端口,比如A、B、C等等,所以才有PA0、PB1、PC15这样的GPIO名字,ST为每个端口都分配了一个时钟,也即PA的0~15引脚共用一个时钟,PB、PC等其他端口的0~15引脚也是如此。所以它的时钟参数,相应地也是具体到端口号,如RCC_APB2Periph_GPIOA,RCC_APB2Periph_GPIOB。

使能时钟的函数是在stm32f10x_rcc.h

打开后根据行号找到如下函数声明,1是开启挂在APB2总线上的时钟,2是开启挂在APB1总线上的时钟。

第一个参数是选择外设对应的时钟,第二个参数是开启还是关闭。



3.4 设置初始状态

因为我们要观察LED的变化,当我们程序刚下载进去时候,配置未生效的时候,该引脚的电平变化是未知的;当程序还没运行到主函数里我们配置的状态的时候,它也不应该是亮的。

我们需要的是:只有运行到我们使LED亮的代码的时候,它才能亮,所以在此之前,它的电平不应该是未知的,并且不应该是亮着的。因此要对选定的引脚进行初始状态设置。我们此前选择的是低电平点亮,根据我们的需要,先不让LED灯亮,先把它设置为高。

到此,一个LED灯的初始化配置就完成了。

下面贴出具体代码

void LED_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;  //定义一个GPIO初始化结构体
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);   //因为选的是PA0,开启A端口时钟
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;         //0号引脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出频率50MHz
	GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化A端口的相关配置,有这一句,配置才生效
	
	GPIO_SetBits(GPIOA, GPIO_Pin_0);   //PA0置高,使LED的初始状态为灭。
}

至于GPIO_Init(GPIOA, &GPIO_InitStructure)中的&GPIO_InitStructure,在这里&是取地址符,这是一个取该结构体地址的意思,如果不懂可以补一下C语言。

main 函数代码

int main(void)
{
    delay_init();   //延迟初始化
	SystemTinerInit(1000-1,3600-1); //系统时间初始化 定时100ms
    LED_Init();     //不要忘记LED初始化函数加到main函数里,否则代码不生效,灯也不会亮
    while(1)
    {
        GPIO_ResetBits(GPIOA, GPIO_Pin_0);
        delay_ms(100);
        GPIO_SetBits(GPIOA, GPIO_Pin_0);
    }
    return 0;
}

这里给出的是一个闪烁灯的代码,如果要点亮一个灯只需要初始化LED_Init()函数,然后循环里面只写一个给低电平的函数就行了。闪烁灯是点亮一个灯的进阶,就是多了一个延迟,一会亮一会灭就成了闪烁灯。

至于延迟函数,可以自己写一个软件的,上网找一下也有的。如果想要精准一点的延迟,就需要用定时器,这里就不讲了,后面再讲,可以复制一个配置好的先用着。

此外还有流水灯,可以自己思考一下如何实现。

本文只教了基础的思路,侧重于方法,有了这样一个通用的方法,学习其他外设或硬件也是类似的步骤,就很容易入门了。不过一些东西还是要自己多琢磨,多动手练习。:)

本人水平有限,有疏漏错误之处还请提出。一定虚心接受并改正。请大家不吝赐教,多多发言评价。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值