STM32MIni板入门-跑马灯

本实验是基于STM32MIni板学习入门小实验,用到的硬件只有 LEDDS0 DS1)。硬件连接原理图如下:

STM32MIni板入门-跑马灯_第1张图片

实验中我们主要用到的固件库文件有:

stm32f10x_gpio.c /stm32f10x_gpio.h
stm32f10x_rcc.c/stm32f10x_rcc.h
misc.c/ misc.h
stm32f10x_usart /stm32f10x_usart.h

首先,建立一个实验的统一项目模板,项目名称命名为LED(自定义),然后建立新的“HARDWARE”文件夹(用来存放自己编写的函数文件)。

然后我们打开 USER 文件夹下的 LED.uvprojx 工程(根据前面的项目名称查找),按按钮新建一个文件,然后保存在 HARDWARE->LED 文件夹下面,保存为 led.c。在该文件中输入如下代码:

#include "led.h"
//初始化 PA8 和 PD2 为输出口.并使能这两个口的时钟
//LED IO 初始化
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|
RCC_APB2Periph_GPIOD, ENABLE); //使能 PA,PD 端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //LED0-->PA.8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO 口速度为 50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 GPIOA.8
GPIO_SetBits(GPIOA,GPIO_Pin_8); //PA.8 输出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //LED1-->PD.2 端口配置, 推挽输出
GPIO_Init(GPIOD, &GPIO_InitStructure); //推挽输出 , IO 口速度为 50MHz
GPIO_SetBits(GPIOD,GPIO_Pin_2); //PD.2 输出高

该代码里面就包含了一个函数 void LED_Init(void),该函数的功能就是用来实现配置 PA8PD2 为推挽输出。这里需要注意的是:在配置 STM32 外设的时候,任何时候都要先使能该外设的时钟。 GPIO 是挂载在 APB2 总线上的外设,在固件库中对挂载在 APB2 总线上的外设时钟使能是通过函数 RCC_APB2PeriphClockCmd()来实现的

在配置完时钟之后,LED_Init配置了GPIOA.8GPIOD.2的模式为推挽输出,并且默认输出1。这样就完成了对这两个IO口的初始化。函数代码是:

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //LED0-->PA8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO 口速度为 50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化 PA8
GPIO_SetBits(GPIOA,GPIO_Pin_8); //PA8 输出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //LED1-->PD2 推挽输出
GPIO_Init(GPIOE, &GPIO_InitStructure); //初始化 PD2
GPIO_SetBits(GPIOD,GPIO_Pin_2); //PD2 输出高

需要说明的是,因为 GPIOA GPIOD IO 口的初始化参数都是设置在结构体变量GPIO_InitStructure 中,因为两个 IO 口的模式和速度都一样,所以我们只用初始化一次,在GPIOD.2 的初始化的时候就不需要再重复初始化速度和模式了。最后一行代码:

GPIO_SetBits(GPIOD,GPIO_Pin_2);

它的作用是在初始化中将GPIOE.5 输出设置为高。

保存 led.c 代码,然后我们按同样的方法,新建一个 led.h 文件,也保存在 LED 文件夹下面 led.h 中输入如下代码:

#ifndef __LED_H
#define __LED_H
#include "sys.h"
//LED 端口定义
#define LED0 PAout(8) // PA8
#define LED1 PDout(2) // PD2
void LED_Init(void);//初始化
#endif

这段代码里面最关键就是 2 个宏定义:

#define LED0 PAout(8) // PA8
#define LED1 PDout(2) // PD2

这里使用的是位带操作来实现操作某个 IO 口的 1 个位的,这里位带操作不做详解。主要说一下操作 IO 口输出高低电平的三种方法。

通过位带操作 PA8 输出高低电平从而控制 LED0 的方法如下:

LED0=1; //通过位带操作控制 LED0 的引脚 PA8 输出高电平
LED0=0; //通过位带操作控制 LED0 的引脚 PA8 输出低电平

 库函数操作方法如下:

GPIO_SetBits(GPIOA, GPIO_Pin_8); //设置 GPIOA8 输出 1,等同 LED0=1;
GPIO_ResetBits (GPIOA, GPIO_Pin_8); //设置 GPIOA8 输出 0,等同 LED0=0;

直接操作寄存器BRR BSRR 的方式来操作 IO 口输出高低电平,方法如下:

GPIOA->BRR=GPIO_Pin_8; //设置 GPIOA.8 输出 1,等同 LED0=1;
GPIOA->BSRR=GPIO_Pin_8; //设置 GPIOA.8 输出 0,等同 LED0=0;

对于上面三种方法,大家根据自己喜好来选择一种即可。在 IO 口速度没有太大要求的情况下效果都是一样的。

接下来在开始添加的HARDWARE中导入我们刚刚编译的文件,文件导入方式参考STM32不完全手册,本人也是参考手册指导,这里具体不做介绍。

然后回到main函数面板编译程序:

#include "led.h"
#include "delay.h"
#include "sys.h"
int main(void)
{
delay_init(); //延时函数初始化
LED_Init(); //初始化与 LED 连接的硬件接口
while(1)
{ LED0=0;
LED1=1;
delay_ms(300); //延时 300ms
LED0=1;
LED1=0;
delay_ms(300); //延时 300ms
}
}

主程序中引入我们自己添加的led.h文件,使我们可以调用里面的函数。

系统在启动的时候会调用 system_stm32f10x.c 中的函数 SystemInit()对系统时钟进行初始化,在时钟初始化完毕之后会调用 main()函数。 所以大家不需要再在 main()函数中调用 SystemInit()函数。当然如果有需要重新设置时钟系统,可以写自己的时钟设置代码, SystemInit()只是将时钟系统初始化为默认状态。

main()函数非常简单,先调用 delay_init()初始化延时,接着就是调用 LED_Init()来初始化GPIOA.8GPIOD.2为输出。最后在死循环里面实现 LED0 LED1 交替闪烁,间隔为 300ms程序编译后烧入开发板即可看到跑马灯效果。




你可能感兴趣的:(STM32)