通过STM32 GPIO口加上延时函数实现跑马灯的教程

电子说

1.3w人已加入

描述

一、硬件威廉希尔官方网站

这里我们还是以stm32f103c8t6为例,并且我们以最小系统板的威廉希尔官方网站 为例。以下是2种类型的最小系统板,区别在于一个是4pin的烧写,一个是20pin的烧写,但是威廉希尔官方网站 基本一样。

为了方便,我们使用板子上的LED为实验对象。我们先来看板子上LED的威廉希尔官方网站 ,由于手头上刚好有20pin烧写的板,我就以这个为例吧。

GPIO
(图四)

学过威廉希尔官方网站 的都会知道,LED灯亮的条件是什么,即只要我们在LED的两端施加一个电压差,使得LED两端有了电压差他就能亮。(记得区分正负哈)

由威廉希尔官方网站 图上,我们可以知道LED的正极已经接上了3.3V,负极接上了stm32的PC13的IO口上。由以上原理可得,只要我们将PC13输出一个低电平,LED两端就会有了电压差,即LED就亮了。

而要制作跑马灯,便是要让灯闪烁起来,一亮一灭。由亮灯的原理可得我们只要在PC13输出一个高电平那么LED便不会亮了。

然后在每一次的亮和灭之间我们加上一个固定时间的延时,就能实现出点灯的效果啦

二、软件编程

原理以及现象讲述完毕,接下来我们进入编程阶段。首先我们先来了解stm32 IO口的编程的流程:

01

Num

使能时钟: 时钟就对于stm32就像心脏对于人类,所以编程的第一步自然是赋予stm32一颗跳动“心脏”;

02

Num

IO口初始化: stm32的IO有多个输入和输出的模式,有不同的速度,以及多个IO口所以这一步我们要对这些进行初始化;

03

Num

操作IO口: IO是输出高电平还是低电平便是我们在这里要做的操作;

第1步:使能时钟:

在这个工程中我们使用的PC13是挂载在APB2上的,我们要使能的时钟便是对应的APB2;我们先来看看RCC函数库中有什么函数

GPIO

(图二十一)

这里我们要调用的库函数是:

void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);

这个函数有两个入口的参数:RCC_APB2Periph、NewState;我们来看看这两个参数是什么

GPIO

(图八)

GPIO

(图九)

从图八可以看到的是,第一个参数的值是在图上定义的那些,我们从中找到GPIOC,将RCC_APB2Periph_GPIOC复制下来作为要设置的参数;从图九可以看到的是,第二个的参数只有两个情况,一个是失能DISABLE,一个是使能ENABLE,这里我们要的是使能ENABLE;

综上我们的时钟使能函数的调用是这样写的:

void RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//使能GPIOC

第2步:IO口初始化:

首先STM32的IO口可以由软件配置成如下8种模式:

1、输入浮空 2、输入上拉 3、输入下拉

4、模拟输入 5、开漏输出 6、推挽输出

7、推挽式复用功能 8、开漏复用功能

有3种速度:2MHz;10MHz;50MHz;

还是一样我们先来看GPIO的函数库:

GPIO

(图十)

这里我们需要用到的函数是:

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

这个函数包含有两个参数分别是GPIOx、GPIO_InitStruct。第一个参数是用来指定GPIO,取值范围为GPIOA—GPIOG

GPIO

(图十一)

这里我们要使用的是GPIOC;第二个参数是初始化参数结构体指针;

GPIO

(图十二)

这个结构体包含了3个成员变量,GPIO_Pin、GPIO_Speed、GPIO_Mode对应我们要设置的GPIO引脚、速度、模式,其中各个的取值范围为:

GPIO

(图十三)

GPIO

(图十四)

GPIO

(图十五)

这里我们要用的是:

GPIO_InitStruct.GPIO_Pin=GPIO_Pin_13; //13引脚
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; //速度为50MHz
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//模式为推挽输出

综上我们的GPIO初始化函数是这样写的:

GPIO_InitTypeDef GPIO_InitStruct ; //定义结构体变量
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_13; //13引脚
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; //速度为50MHz
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; //模式为推挽输出
GPIO_Init(GPIOC, &GPIO_InitStruct); //初始化GPIOC

第3步:操作IO:

这里我们要用到的函数已经在图11中标注出来了;

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //将GPIO引脚置高电平
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //将GPIO引脚置低电平

图中写的注释我们可以简单理解为是将GPIO口输出高和低的函数;

这两个的函数的参数都是一样的,我们在上边已经说过了,就不再复述了,我们这里要使用的是GPIOC以及GPIO_PIN_13;

综上我们的GPIO操作函数是这样写的:

GPIO_SetBits(GPIOC,GPIO_Pin_13); //将GPIOC 13引脚输出高电平
GPIO_ResetBits(GPIOC,GPIO_Pin_13); //将GPIOC 13引脚输出低电平

GPIO

(图十六)

我们的延时函数是这样写的(使用正点原子制作好的函数)

delay_ms(600);//延时600ms

三、实操

以上一篇新建的工程为模版(任意门:STM32新建工程(固件库版))我们在那个工程的基础上进行实操;

首先我们打开那个TEST文件,在HARDWARE文件夹中建立一个文件夹命名为LED。进入USER文件夹,打开 TEST.uvprojx(关注后缀名,工程名称是自己命名的)的工程文件进入KEIL5;我们先编译一遍(这里的图忘了截,就放上一次的图吧)

GPIO

(图一)

然后我们新建两个文件,保存在刚刚新建的LED文件夹内,并分别命名为 LED.c以及LED.h,对应的是LED的函数和头文件,并且分别添加到HARDWARE分组,以及头文件中,操作跟新建工程时新建main函数文件和导入头文件是一样的,更加具体操作在新建工程篇已经讲过了,就不复述了,完成后如图

GPIO

(图十七)

然后我们打开LED.h编写以下内容:

#ifndef __LED_H //头文件定义
#define __LED_H
void LED_Init(void); //声明LED初始化函数
#endif

GPIO

(图十八)

打开LED.c编写LED初始化函数如下:

#include "LED.h"
#include "stm32f10x.h"
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); //时钟使能GPIOC
//初始化GPIO PC.13
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_13; //PIN13引脚
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; //速度50mhz
GPIO_Init(GPIOC,&GPIO_InitStruct); //初始化GPIOC
GPIO_SetBits(GPIOC,GPIO_Pin_13); //PC13设置为高电平
}

这里我们LED初始化函数中多了一个将PC13设为高电平的操作,是为了让程序烧写进去后,LED的第一状态是灭的,以便后续的操作;以及导入了库函数的头文件和LED的头文件

GPIO

(图十九)

接着我们编写主函数,如下:

#include "stm32f10x.h"
#include "LED.h"
#include "delay.h"
int main(void)
{
delay_init(); //延时初始化
LED_Init(); //LED初始化
while(1)
{
GPIO_SetBits(GPIOC,GPIO_Pin_13); // PC13设置为高电平(亮)
delay_ms(600); //延时600ms
GPIO_ResetBits(GPIOC,GPIO_Pin_13); // PC13设置为低电平(灭)
delay_ms(600); //延时600ms
}
}

GPIO

(图二十)

在主函数我们要引入3个头文件,固件库的头文件以及自己编写的LED.h和延时函数的头文件,之后我们才能调用需要的函数。我们在初始化之后用一个死循环将GPIO的电平设置不断的循环,通过延时函数将亮和灭之间有一个固定时间差,实现呼吸灯的效果。通过编译之后,烧写进stm32,就可以看如图的呼吸灯的效果了。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分