一、硬件电路
这里我们还是以stm32f103c8t6为例,并且我们以最小系统板的电路为例。以下是2种类型的最小系统板,区别在于一个是4pin的烧写,一个是20pin的烧写,但是电路基本一样。
为了方便,我们使用板子上的LED为实验对象。我们先来看板子上LED的电路,由于手头上刚好有20pin烧写的板,我就以这个为例吧。
(图四)
学过电路的都会知道,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函数库中有什么函数
(图二十一)
这里我们要调用的库函数是:
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
这个函数有两个入口的参数:RCC_APB2Periph、NewState;我们来看看这两个参数是什么
(图八)
(图九)
从图八可以看到的是,第一个参数的值是在图上定义的那些,我们从中找到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的函数库:
(图十)
这里我们需要用到的函数是:
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
这个函数包含有两个参数分别是GPIOx、GPIO_InitStruct。第一个参数是用来指定GPIO,取值范围为GPIOA—GPIOG
(图十一)
这里我们要使用的是GPIOC;第二个参数是初始化参数结构体指针;
(图十二)
这个结构体包含了3个成员变量,GPIO_Pin、GPIO_Speed、GPIO_Mode对应我们要设置的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引脚输出低电平
(图十六)
我们的延时函数是这样写的(使用正点原子制作好的函数)
delay_ms(600);//延时600ms
三、实操
以上一篇新建的工程为模版(任意门:STM32新建工程(固件库版))我们在那个工程的基础上进行实操;
首先我们打开那个TEST文件,在HARDWARE文件夹中建立一个文件夹命名为LED。进入USER文件夹,打开 TEST.uvprojx(关注后缀名,工程名称是自己命名的)的工程文件进入KEIL5;我们先编译一遍(这里的图忘了截,就放上一次的图吧)
(图一)
然后我们新建两个文件,保存在刚刚新建的LED文件夹内,并分别命名为 LED.c以及LED.h,对应的是LED的函数和头文件,并且分别添加到HARDWARE分组,以及头文件中,操作跟新建工程时新建main函数文件和导入头文件是一样的,更加具体操作在新建工程篇已经讲过了,就不复述了,完成后如图
(图十七)
然后我们打开LED.h编写以下内容:
#ifndef __LED_H //头文件定义
#define __LED_H
void LED_Init(void); //声明LED初始化函数
#endif
(图十八)
打开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的头文件
(图十九)
接着我们编写主函数,如下:
#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
}
}
(图二十)
在主函数我们要引入3个头文件,固件库的头文件以及自己编写的LED.h和延时函数的头文件,之后我们才能调用需要的函数。我们在初始化之后用一个死循环将GPIO的电平设置不断的循环,通过延时函数将亮和灭之间有一个固定时间差,实现呼吸灯的效果。通过编译之后,烧写进stm32,就可以看如图的呼吸灯的效果了。
-
led灯
+关注
关注
22文章
1592浏览量
107777 -
RCC
+关注
关注
0文章
93浏览量
26880 -
推挽电路
+关注
关注
18文章
113浏览量
37840 -
GPIO
+关注
关注
16文章
1189浏览量
51855 -
STM32F103C8T6
+关注
关注
107文章
160浏览量
83137
发布评论请先 登录
相关推荐
评论