GPIO应用——跑马灯+蜂鸣器实验
跑马灯和蜂鸣器的实验都是使用的 GPIO 的通用推挽输出模式,这是 GPIO 最简单的一个基本功能。
1跑马灯实验
1.1硬件设计
如图所示跑马灯使用的 LED 只有 DS0(红灯)和 DS1(绿灯)两个,DS0 接 PB5,DS1 接 PE5
LED 是发光二极管,既然是二极管,就具备二极管的正向导通,反向截止的特性。DS0 的正极通过电阻R909 连接电源正极(即 VCC_3V3),负极连接到 PB5,注意 LED0 是网络标号,网络标号相同的,在原理图上表示是相连接的。这个 R909 我们俗称为限流电阻,因为 LED 灯点亮有一个导通电流,这个电流不能太大,太大容易烧毁 LED 灯,因此我们通过串联一个来减少导通时的电流,电阻的阻值大小根据 LED 种类的不同可以灵活选取。
根据二极管的单向导通特性,如果我们给 PB5 设置输出高电平(3.3V),那么 DS0 应该不点亮,而如果给 PB5 设置输出低电平,那么由于存在正向压降,DS0 导通,因此点亮发光。
总结一下,针对本例的电路原理图,LED 灯低电平点亮,高电平熄灭。
1.2软件设计
首先我们需要新建bsp_led.c和bsp_led.h文件
接下来我们看一下 bsp_led.h 的程序构成
#ifndef _BSP_LED_H
#define _BSP_LED_H
#include "sys.h"
#define RCC_LED_ALL (LED0_GPIO_CLK | LED1_GPIO_CLK) //定义两个LED灯的端口时钟
#define LED0_GPIO_PIN GPIO_Pin_5 //LED0引脚号
#define LED0_PIN_ID 5 //LED0引脚序号
#define LED0_GPIO_PORT GPIOB //LED0端口号
#define LED0_GPIO_CLK RCC_APB2Periph_GPIOB //LED0时钟
#define LED0_FUN_OUT PBout //LED0端口输出配置
#define LED1_GPIO_PIN GPIO_Pin_5 //LED1引脚号
#define LED1_PIN_ID 5 //LED1引脚序号
#define LED1_GPIO_PORT GPIOE //LED1端口号
#define LED1_GPIO_CLK RCC_APB2Periph_GPIOE //LED1时钟
#define LED1_FUN_OUT PEout //LED1端口输出配置
#define LED0 LED0_FUN_OUT(LED0_PIN_ID) //定义LED的输出
#define LED1 LED1_FUN_OUT(LED0_PIN_ID)
//函数声明
void bsp_InitLed(void);
void bsp_LedOn(uint8_t _on);
void bsp_LedOff(uint8_t _off);
void bsp_LedToggle(uint8_t _no);
uint8_t bsp_IsLedOn(uint8_t _no);
#endif
/***************************** (END OF FILE) *********************************/
时钟,引脚和端口全部采用宏定义的方式,主要是方便以后程序修改,后面的例子都采用这种方式来实现。在讲解这个文件构成前,我们先看一下该头文件包含的 sys.h 头文件的构成,这对我们了解 bsp_led.h 和 bsp_led.c 至关重要,==sys.h 程序==构成如下所示。
#ifndef __SYS_H
#define __SYS_H
#include "stm32f10x.h"
/*
*********************************************************************************************************
*
* 模块名称 : sys模块
* 文件名称 : sys.h
* 说 明 : 这是所有驱动h文件需要包含的h文件,需要在头文件中包含,实现位带操作
*
*********************************************************************************************************
*/
#define WSNEP_V01
//#define TDL_02
/* 检查是否定义了开发板型号 */
#if !defined (WSNEP_V01) && !defined (TDL_02)
#error "Please define the board model : TDL_02 or WSNEP_V01"
#endif
//位带操作,实现51类似的GPIO控制功能
//具体实现思想,参考<<CM3权威指南>>第五章(87页~92页).
//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#