天天看点

stm32 跑马灯(01)工程LED灯原理图函数介绍完整代码函数功能实验步骤其他资源

跑马灯

  • 工程
  • LED灯原理图
  • 函数介绍
    • RCC_APB2PeriphColckCmd()
    • GPIO_Init()
    • GPIO_SetBits() 和GPIO_ResetBits()
  • 完整代码
    • Led.h
    • Led.c
    • main.c
  • 函数功能
  • 实验步骤
  • 其他资源

工程

将00MyPro工程复制粘贴一份后,改名为01 跑马灯。

打开文件夹并新建一个文件为Hrd(硬件驱动)。并新建LED文件夹。

在Keil中新建两个文件并保存在LED文件下,命名Led.c和Led.h。

并将Led.c添加到工程中,Led.h添加到环境变量中。详细添加请看stm32新建工程模板

stm32 跑马灯(01)工程LED灯原理图函数介绍完整代码函数功能实验步骤其他资源
stm32 跑马灯(01)工程LED灯原理图函数介绍完整代码函数功能实验步骤其他资源
stm32 跑马灯(01)工程LED灯原理图函数介绍完整代码函数功能实验步骤其他资源

LED灯原理图

stm32 跑马灯(01)工程LED灯原理图函数介绍完整代码函数功能实验步骤其他资源
stm32 跑马灯(01)工程LED灯原理图函数介绍完整代码函数功能实验步骤其他资源

因为 LED1和LED2的一端(正极)连接着高电平VCC3.3,所以在另一端(负极)就要接低电平使LED灯点亮。

函数介绍

RCC_APB2PeriphColckCmd()

使能IO口时钟,不同的IO组,调用的时钟使能函数不一样。这里不做过多介绍。

函数原型

详细请看此链接:stm32时钟系统

GPIO_Init()

详细请看此链接:stm32-GPIO

初始化IO口模式。

函数原型

GPIO_TypeDef* GPIOx:选择要使用的IO口。要根据stm32的型号来选择(不同的型号的IO口会有区别),还要根据LED灯原理图中使用的IO口来进行选择(不能选择非LED的IO口取驱动LED灯)。我的stm32中LED灯使用的IO口为GPIOA和GPIOD。

#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \
                                    ((PERIPH) == GPIOB) || \
                                    ((PERIPH) == GPIOC) || \
                                    ((PERIPH) == GPIOD) || \
                                    ((PERIPH) == GPIOE) || \
                                    ((PERIPH) == GPIOF) || \
                                    ((PERIPH) == GPIOG))
           

GPIO_InitTypeDef* GPIO_InitStruct:结构体,里面定义了IO口要使用的引脚、模式和频率。

引脚:选择引脚8和引脚2

#define GPIO_Pin_0                 ((uint16_t)0x0001)  /*!< Pin 0 selected */
#define GPIO_Pin_1                 ((uint16_t)0x0002)  /*!< Pin 1 selected */
#define GPIO_Pin_2                 ((uint16_t)0x0004)  /*!< Pin 2 selected */
#define GPIO_Pin_3                 ((uint16_t)0x0008)  /*!< Pin 3 selected */
#define GPIO_Pin_4                 ((uint16_t)0x0010)  /*!< Pin 4 selected */
#define GPIO_Pin_5                 ((uint16_t)0x0020)  /*!< Pin 5 selected */
#define GPIO_Pin_6                 ((uint16_t)0x0040)  /*!< Pin 6 selected */
#define GPIO_Pin_7                 ((uint16_t)0x0080)  /*!< Pin 7 selected */
#define GPIO_Pin_8                 ((uint16_t)0x0100)  /*!< Pin 8 selected */
#define GPIO_Pin_9                 ((uint16_t)0x0200)  /*!< Pin 9 selected */
#define GPIO_Pin_10                ((uint16_t)0x0400)  /*!< Pin 10 selected */
#define GPIO_Pin_11                ((uint16_t)0x0800)  /*!< Pin 11 selected */
#define GPIO_Pin_12                ((uint16_t)0x1000)  /*!< Pin 12 selected */
#define GPIO_Pin_13                ((uint16_t)0x2000)  /*!< Pin 13 selected */
#define GPIO_Pin_14                ((uint16_t)0x4000)  /*!< Pin 14 selected */
#define GPIO_Pin_15                ((uint16_t)0x8000)  /*!< Pin 15 selected */
#define GPIO_Pin_All               ((uint16_t)0xFFFF)  /*!< All pins selected */

#define IS_GPIO_PIN(PIN) ((((PIN) & (uint16_t)0x00) == 0x00) && ((PIN) != (uint16_t)0x00))
           

模式:推挽输出 GPIO_Mode_Out_PP

typedef enum
{ GPIO_Mode_AIN = 0x0,
  GPIO_Mode_IN_FLOATING = 0x04,
  GPIO_Mode_IPD = 0x28,
  GPIO_Mode_IPU = 0x48,
  GPIO_Mode_Out_OD = 0x14,
  GPIO_Mode_Out_PP = 0x10,
  GPIO_Mode_AF_OD = 0x1C,
  GPIO_Mode_AF_PP = 0x18
}GPIOMode_TypeDef;
#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_AIN) || ((MODE) == GPIO_Mode_IN_FLOATING) || \
                            ((MODE) == GPIO_Mode_IPD) || ((MODE) == GPIO_Mode_IPU) || \
                            ((MODE) == GPIO_Mode_Out_OD) || ((MODE) == GPIO_Mode_Out_PP) || \
                            ((MODE) == GPIO_Mode_AF_OD) || ((MODE) == GPIO_Mode_AF_PP))
           

频率:GPIO_Speed_50MHz

typedef enum
{ 
  GPIO_Speed_10MHz = 1,
  GPIO_Speed_2MHz, 
  GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;
#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Speed_10MHz) || ((SPEED) == GPIO_Speed_2MHz) || \
                              ((SPEED) == GPIO_Speed_50MHz))

           

GPIO_SetBits() 和GPIO_ResetBits()

操作IO口,使其输出高低电平,让其点亮。

函数原型

`void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)`
           

GPIO_SetBits():给IO口输入高电平

GPIO_ResetBits():给IO口输出低电平

里面的参数参照与GPIO_Init()函数中的参数。

完整代码

Led.h

#ifndef __LED_H
#define __LED_H

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

void LED_Init(void); //初始化
void LED_Dispaly(void); //点亮一个LED灯
void LED_OneCycle(void); //LED0闪烁,LED1常量
void LED_Cycle(void);//LED0、LED1交替闪烁
void LED_TogetherCycle(void);//LED灯一起闪烁

#endif
           

意思:如果

Led.h

第一次被引用,那么

__LED_H

没有被定义,因此

#define __LED_H

#endif

中间的头文件内容就被执行。如果

Led.h

第二次被引用(不是第一次使用 ),由于

__LED_H

已经被第一次引用时定义了,所以不会执行

#define __LED_H

#endif

中间的头文件内容,也就是不会重复定义头文件内容。

为什么这样写:可以避免头文件的内容被重复定义。头文件中定义的变量不存在重复声明或定义。

Led.c

#include"Led.h"
#include"delay.h"
#include"stm32f10x.h"

void LED_Init()
{
	GPIO_InitTypeDef GPIO_Int;
	//使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);
	// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA  | RCC_APB2Periph_GPIOD,ENABLE); //减少内存空间
	//配置IO口 初始化
	GPIO_Int.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
	GPIO_Int.GPIO_Pin = GPIO_Pin_8;
	GPIO_Int.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOA,&GPIO_Int);
	
	GPIO_Int.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
	GPIO_Int.GPIO_Pin = GPIO_Pin_2;
	GPIO_Int.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOD,&GPIO_Int);
}

void LED_Dispaly(void)
{
	while(1)
	{
		//GPIO_ResetBits(GPIOA,GPIO_Pin_8);//LED0
		//GPIO_SetBits(GPIOD,GPIO_Pin_2);
		GPIO_ResetBits(GPIOD,GPIO_Pin_2);//LED1
		GPIO_SetBits(GPIOA,GPIO_Pin_8);
	}
}

void LED_OneCycle(void)
{
	delay_init();
	LED1 = 0; //点亮
	while(1)
	{
		LED0 =! LED0;
		delay_ms(500);
	}
}

void LED_Cycle(void)
{
	delay_init();
	//一开始让其熄灭
	GPIO_SetBits(GPIOD,GPIO_Pin_2);
	GPIO_SetBits(GPIOA,GPIO_Pin_8);
	while(1)
	{

		GPIO_ResetBits(GPIOA,GPIO_Pin_8);
		delay_ms(500);
		GPIO_ResetBits(GPIOD,GPIO_Pin_2);
		delay_ms(500);
		
		GPIO_SetBits(GPIOA,GPIO_Pin_8);
		delay_ms(500);
		GPIO_SetBits(GPIOD,GPIO_Pin_2);
		delay_ms(500);
	}
}

void LED_TogetherCycle(void)
{
	delay_init();
	while(1)
	{
		//GPIO_ResetBits(GPIOA,GPIO_Pin_8);//LED0
		//GPIO_ResetBits(GPIOD,GPIO_Pin_2);//LED1
		//delay_ms(500);
		//GPIO_SetBits(GPIOA,GPIO_Pin_8);
		//GPIO_SetBits(GPIOD,GPIO_Pin_2);
		//delay_ms(500);
		
		LED0 = 1;
		LED1 = 1;
		delay_ms(500);
		LED0 = 0;
		LED1 = 0;
		delay_ms(500);
	}
}
           

main.c

#include"Led.h"
#include"stm32f10x.h"
#include"delay.h"

//点亮LED灯
int main()
{
	LED_Init();
	//LED_Dispaly(); //点亮一个LED灯
	LED_OneCycle(); //LED0闪烁,LED1常亮
	//LED_Cycle();//LED0、LED1交替闪烁
	//LED_TogetherCycle();//LED灯一起闪烁
}
           

函数功能

LED_Dispaly():点亮一个LED灯

LED_OneCycle():LED0闪烁,LED1常亮

LED_Cycle();//LED0、LED1交替闪烁

LED_TogetherCycle();//LED灯一起闪烁

实验步骤

注:不同的stm32所使用的IO口会有所不同,以下步骤对ALIENTEK miniSTM32F103 的 STM32F103RTC6有效,至于其他型号的stm32请参照相关的资料进行配置。但是对于大致的步骤都基本相同

1、使能IO口时钟。调用函数:RCC_APB2PeriphColckCmd();不同的IO组,调用的时钟使能函数里面的参数不一样不一样。

2、初始化IO口模式。调用函数GPIO_Init();

3、操作IO口,输出高低电平。

GPIO_SetBits(); 高电平

GPIO_ResetBits(); 低电平

其他资源

stm32 新建工程模板