初学正点原子Ministm32板跑马灯

跑马灯实验

通过代码控制 ALIENTEK MiniSTM32 开发板上的两个 LED:DS0 和 DS1 交 替闪烁,实现类似跑马灯的效果

1.STM32 IO 口简介 
2.硬件设计 
3.软件设计 

一. STM32 IO 简介

GPIO 端口操作对应的库函数函数以及相关定义在文件stm32f10x_gpio.h 和 stm32f10x_gpio.c 中。

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

1、输入浮空

2、输入上拉

3、输入下拉

4、模拟输入

5、开漏输出

6、推挽输出

7、推挽式复用功能

8、开漏复用功能

STM32 的每个 IO 端口都有 7 个寄存器来控制。他们分别是:配置模式的 2 个 32 位的端口 配置寄存器 CRL 和 CRH;2 个 32 位的数据寄存器 IDR 和 ODR;1 个 32 位的置位/复位寄存器、BSRR;一个 16 位的复位寄存器 BRR;1 个 32 位的锁存寄存器 LCKR。

在固件库开发中,操作寄存器 CRH 和 CRL 来配置 IO 口的模式和速度是通过 GPIO 初始化 函数完成:

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

这个函数有两个参数,第一个参数是用来指定 GPIO,取值范围为 GPIOA~GPIOG。第二个参数为初始化参数结构体指针,结构体类型为 GPIO_InitTypeDef。下面我们看看这个结 构体的定义。首先我们打开我们光盘的跑马灯实验,然后找到 FWLib 组下面的 stm32f10x_gpio.c文件,定位到 GPIO_Init 函数体处,双击入口参数类型 GPIO_InitTypeDef 后右键选择“Go to definition of …”可以查看结构体的定义:

typedef struct 

{ uint16_t GPIO_Pin; 
 GPIOSpeed_TypeDef GPIO_Speed; 
 GPIOMode_TypeDef GPIO_Mode; 
}GPIO_InitTypeDef;

下面我们通过一个 GPIO 初始化实例来讲解这个结构体的成员变量的含义。通过初始化结构体初始化 GPIO 的常用格式是:

GPIO_InitTypeDef GPIO_InitStructure; 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 端口配置 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度 50MHz 
GPIO_Init(GPIOB, &GPIO_InitStructure);//根据设定参数配置 GPIO 

第三个参数是 IO 口速度设置,有三个可选值,在 MDK 中同样是通过枚举类型定义:

typedef enum 
{ 
 GPIO_Speed_10MHz = 1, 
 GPIO_Speed_2MHz, 
 GPIO_Speed_50MHz 
}GPIOSpeed_TypeDef; 

要想知道某个 IO 口的电平状态,你只要读这个寄存器,再看某个位的状态就可以了。使 用起来是比较简单的。

在固件库中操作 IDR 寄存器读取 IO 端口数据是通过 GPIO_ReadInputDataBit 函数实现的:

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 

BRR 寄存器是端口位清除寄存器。该寄存器的作用跟 BSRR 的高 16 位雷同,这里就不做 详细讲解。在 STM32 固件库中,通过 BSRR 和 BRR 寄存器设置 GPIO 端口输出是通过函数 GPIO_SetBits()和函数 GPIO_ResetBits()来完成的。

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 

在多数情况下,我们都是采用这两个函数来设置 GPIO 端口的输入和输出状态。比如我们要设 置 GPIOB.5 输出 1,那么方法为:

GPIO_SetBits(GPIOB, GPIO_Pin_5); 

二.硬件设计

本次跑马灯用到的硬件只有 LEDDS0和DS1)。DS0 接PA8,DS1接PD2。

硬件原理如下图所示:

初学正点原子Ministm32板跑马灯_第1张图片

 三.软件设计

跑马灯实验我们主要用到的固件库文件是:

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

 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 输出高 

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

#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 

 

这里使用的是位带操作来实现操作某个IO口的1个位的,关于位带操作前面第五章5.2.1已经有介绍,这里不再多说。这里我们来讲解一下,操作IO口输出高低电平的三种方法。通过位带操作PA8输出高低电平从而控制LED0的方法如下:

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

库函数操作就直接调用两个函数即可控制IO输出高低电平。我们也通过直接操作寄存器BRR和BSRR的方式来操作IO口输出高低电平,方法如下:

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

main函数代码如下:

#include "led.h" #include "delay.h" 
#include "sys.h" //ALIENTEK miniSTM32开发板实验 1 //跑马灯实验   
    
int main(void)  
    {   delay_init();               //延时函数初始化     
        LED_Init();              //初始化与 LED连接的硬件接口  
        while(1) 
         {   LED0=0;     
             LED1=1;   
             delay_ms(500);            //延时 500ms   
             LED0=1;  
             LED1=0;   
             delay_ms(500);            //延时 500ms  
         }  
    } 

最后我们编译工程显示如下表示零错误零警告

初学正点原子Ministm32板跑马灯_第2张图片

新手小白若有错误还请大佬讲解,以上就是我的个人理解。

 

 

你可能感兴趣的:(stm32单片机,stm32,单片机,嵌入式硬件)