基于Keil_uVision5中的STM32F103C8编程(一)简易流水灯的实现及拓展

简易流水灯的实现及拓展

  • 基本信息
  • 流水灯原理
    • 流水灯
    • 如何定义时间
    • 如何点亮小灯
  • 项目文件同代码实现
  • 拓展与思考
  • 备注

基本信息

最后一次修改时间:2019/8/29
参考文献:STM32固件库说明(中文版)

流水灯原理

流水灯

流水灯指的是若干盏灯的一种明暗组合,简单来说,就是一排小灯依次点亮,在视觉上形成流水的效果。实现流水灯需要初始化外设时钟、初始化灯的管脚

如何定义时间

1.函数 RCC_APB2PeriphClockCmd
作用:初始化外设时钟,可以理解为就是让你的板子的外设时钟GPIOA初始化,它就可以认知时间。

函数名 RCC_APB2PeriphClockCmd 备注
函数原形 void RCC_APB2PeriphClockCmd(u32 RCC_APB2Periph, FunctionalState NewState)
功能描述 使能或者失能 APB2 外设时钟
输入参数 1 RCC_APB2Periph: 门控 APB2 外设时钟 参数取RCC_APB2Periph_GPIOA,意义是GPIOA时钟
输入参数 2 NewState:指定外设时钟的新状态 参数取ENABLE 或者 DISABLE

如何点亮小灯

1.首先认识一下GPIO_InitTypeDef类型;连接管脚以后,就可以通过修改代码中的变量来指定板子中小灯的行为逻辑。
GPIO_InitTypeDef 定义于文件“stm32f10x_gpio.h”

typedef struct 
{ 
u16 GPIO_Pin; 
GPIOSpeed_TypeDef GPIO_Speed; 
GPIOMode_TypeDef GPIO_Mode; 
} GPIO_InitTypeDef;

GPIO_Pin改参数选择管脚,使用操作符“|”可以一次选中多个管脚;GPIO_Speed用以设置选中管脚的速率;
GPIO_Mode 用以设置选中管脚的工作状态
2.函数 GPIO_Init;初始化外设寄存器

函数名 GPIO_Init
函数原形 void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
功能描述 根据 GPIO_InitStruct 中指定的参数初始化外设 GPIOx 寄存器
输入参数 1 GPIOx:x 可以是 A,B,C,D 或者 E,来选择 GPIO 外设
输入参数 2 GPIO_InitStruct:指向结构 GPIO_InitTypeDef 的指针,包含了外设 GPIO 的配置信息

3.函数GPIO_SetBits;设置数据端口位就像是把管脚从0置为1,实现了点亮管脚连接的小灯

函数名 GPIO_SetBits
函数原形 void GPIO_SetBits(GPIO_TypeDef* GPIOx, u16 GPIO_Pin)
功能描述 设置指定的数据端口位
输入参数 1 GPIOx:x 可以是 A,B,C,D 或者 E,来选择 GPIO 外设
输入参数 2 GPIO_Pin:待设置的端口位

4.函数GPIO_ResetBits;同上,把管脚从1置为0,实现了熄灭管教连接的小灯

函数名 GPIO_ResetBits
函数原形 void GPIO_ResetBits(GPIO_TypeDef* GPIOx, u16 GPIO_Pin)
清除指定的数据端口位
输入参数 1 GPIOx:x 可以是 A,B,C,D 或者 E,来选择 GPIO 外设
输入参数 2 GPIO_Pin:待清除的端口位,该参数可以取 GPIO_Pin_x(x 可以是 0-15)的任意组合

项目文件同代码实现

1.led.c文件
包含了初始化灯以及全亮,全灭,闪烁以及流水灯等函数,设置好led.h的头文件以后可以根据需要直接在main.c上使用


#include "led.h"

/*一个延迟函数,本质是双重循环。在8MHZ的晶振下,达到延时的目的。(不能控制具体的时间,只能做到有个明显的延迟,time的单位约为秒)*/
void delay(int time){
		for(int i = 0;i < time ;i++){
				int j = 1000000;
				while(j--){};
		}
		return;
}

/*初始化管脚,GPIO_PIN_1即为灯1的管脚*/
void led_configer(){
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//Clock initialize
	
		GPIO_InitTypeDef GPIO_LED_INIT;//define a Variable of GPIO_InitTypeDef
		GPIO_LED_INIT.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
		GPIO_LED_INIT.GPIO_Speed = GPIO_Speed_2MHz;
		GPIO_LED_INIT.GPIO_Mode = GPIO_Mode_Out_PP;//Push-pull output
	
		GPIO_Init(GPIOA,&GPIO_LED_INIT);		//GPIO initialize
}

/*逻辑同上,但是用4个变量来连接4个灯的管脚,这样可以实现分别控制4个灯的明暗变化,用于流水灯*/
void _4led_configer(){
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
		
		GPIO_InitTypeDef GPIO_LED_INIT1;
		GPIO_InitTypeDef GPIO_LED_INIT2;
		GPIO_InitTypeDef GPIO_LED_INIT3;
		GPIO_InitTypeDef GPIO_LED_INIT4;
	
		GPIO_LED_INIT1.GPIO_Pin = GPIO_Pin_1;
		GPIO_LED_INIT1.GPIO_Speed = GPIO_Speed_2MHz;
		GPIO_LED_INIT1.GPIO_Mode = GPIO_Mode_Out_PP;
	
		GPIO_LED_INIT2.GPIO_Pin = GPIO_Pin_2;
		GPIO_LED_INIT2.GPIO_Speed = GPIO_Speed_2MHz;
		GPIO_LED_INIT2.GPIO_Mode = GPIO_Mode_Out_PP;
	
		GPIO_LED_INIT3.GPIO_Pin = GPIO_Pin_3;
		GPIO_LED_INIT3.GPIO_Speed = GPIO_Speed_2MHz;
		GPIO_LED_INIT3.GPIO_Mode = GPIO_Mode_Out_PP;
	
		GPIO_LED_INIT4.GPIO_Pin = GPIO_Pin_4;
		GPIO_LED_INIT4.GPIO_Speed = GPIO_Speed_2MHz;
		GPIO_LED_INIT4.GPIO_Mode = GPIO_Mode_Out_PP;
		
		GPIO_Init(GPIOA,&GPIO_LED_INIT1);
		GPIO_Init(GPIOA,&GPIO_LED_INIT2);
		GPIO_Init(GPIOA,&GPIO_LED_INIT3);
		GPIO_Init(GPIOA,&GPIO_LED_INIT4);
}

/*全亮*/
void led_all_on(){
		GPIO_SetBits(GPIOA,GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4);
}

/*全灭*/
void led_all_off(){
		GPIO_ResetBits(GPIOA,GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4);
}

/* 4个灯同时闪烁,注意使用了一个while(1)的死循环*/
void led_on_off(int time){
		while(1){
				GPIO_SetBits(GPIOA,GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4);
				delay(time);
				GPIO_ResetBits(GPIOA,GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4);
				delay(time);
		}
}

/* 流水灯 */
void water_led(int time){
		GPIO_SetBits(GPIOA,GPIO_Pin_1);
		GPIO_ResetBits(GPIOA,GPIO_Pin_2);
	  	GPIO_ResetBits(GPIOA,GPIO_Pin_3);
		GPIO_ResetBits(GPIOA,GPIO_Pin_4);
		while(1){
				delay(time);
				GPIO_ResetBits(GPIOA,GPIO_Pin_4);
				GPIO_SetBits(GPIOA,GPIO_Pin_1);
				delay(time);
				GPIO_ResetBits(GPIOA,GPIO_Pin_1);
				GPIO_SetBits(GPIOA,GPIO_Pin_2);
				delay(time);
				GPIO_ResetBits(GPIOA,GPIO_Pin_2);
				GPIO_SetBits(GPIOA,GPIO_Pin_3);
				delay(time);
				GPIO_ResetBits(GPIOA,GPIO_Pin_3);
				GPIO_SetBits(GPIOA,GPIO_Pin_4);
		}
}

2.led.h

#ifndef _LED_H
#define _LED_H

#include//引入驱动STM32的头文件,必须得有

void delay(int time);	//delay to execute
void led_configer(void);	//Intialize all the light by 1 GPIO_InitTypeDef
void _4led_configer(void);	// Intialize all the light by 4 GPIO_InitTypeDef
void led_all_on(void);	//Open all the light
void led_all_off(void);	//Close all the light	
void led_on_off(int time); // Glint the light by time
void water_led(int time);  //Open the light in a sequence

#endif

拓展与思考

1.在初始化管脚以后,4个灯的亮灭可以任意组合,只要使用GPIO_SetBits(GPIOx,GPIO_Pin_x);和GPIO_ResetBits(GPIOx,GPIO_Pin_x)在delay延时函数的配合下做出想要的任何变化。
2.未完成,待修改

备注

1.这是编者的第一篇小博客,如有不对的地方或是不规范的地方,请及时指出。
2.关于使用的函数的详细信息,可以通过上传的STM32固件库说明(中文版)查看

你可能感兴趣的:(基于Keil_uVision5中的STM32F103C8编程(一)简易流水灯的实现及拓展)