STM32F407系列文章目录
第一章 获取相关组件(注意:下载或安装不要有中文路径)
第二章 新建工程
第三章 GPIO相关配置实验
文章目录
前言
本文章采用Keil5及STM32F4(SDK-设计资源)进行STM32F407(ARM芯片)系列学习
- 萌新入坑,如有不对的地方请大佬多多指教,谢谢!->欢迎评论区留言
- 对于萌新来说,学习无非就是多看博文,但是…0.0大佬们的思维大多都有些跳跃,真的很难理解(当然大佬们估计都是为了记录或者提醒自己的工作及学习例程),所以想通过慢慢学习,把每一步都解释出来(保姆版)
第三章 GPIO相关配置实验
1.跑马灯实验
1.1 原理图
- MCU引脚
- 涉及外设
1.2 代码示例
- led.c
- 库函数版本
#include "led.h"
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); // 使能GPIOF时钟
// GPIOF9,F10初始化设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // LED0和LED1对应IO口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; // 普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // 上拉
GPIO_Init(GPIOF, &GPIO_InitStructure); // 初始化GPIO
GPIO_SetBits(GPIOF, GPIO_Pin_9 | GPIO_Pin_10); // GPIOF9,F10设置高,灯灭
}
- 寄存器版本
#include "led.h"
void LED_Init(void)
{
RCC->AHB1ENR |= 1 << 5; // 使能PORTF时钟
GPIO_Set(GPIOF, PIN9|PIN10, GPIO_MODE_OUT, GPIO_OTYPE_PP, GPIO_SPEED_100M, GPIO_PUPD_PU); // PF9,PF10设置
LED0 = 1; // LED0关闭
LED1 = 1; // LED1关闭
}
- led.h
#ifndef __LED_H
#define __LED_H
#include "sys.h"
#define LED0 PFout(9) // DS0
#define LED1 PFout(10) // DS1
void LED_Init(void); // 初始化
#endif
- main.c
#include "sys.h"
#include "delay.h"
#include "led.h"
int main(void)
{
//Stm32_Clock_Init(336, 8, 2, 7); // 设置时钟,168Mhz
delay_init(168); // 初始化延时函数
LED_Init(); // 初始化LED端口
while(1)
{
/* 库函数操作 */
GPIO_ResetBits(GPIOF, GPIO_Pin_9); // LED0对应引脚GPIOF.9拉低,亮 等同LED0=0
GPIO_SetBits(GPIOF, GPIO_Pin_10); // LED1对应引脚GPIOF.10拉高,灭 等同LED1=1
delay_ms(500); // 延时300ms
GPIO_SetBits(GPIOF, GPIO_Pin_9); // LED0对应引脚GPIOF.0拉高,灭 等同LED0=1
GPIO_ResetBits(GPIOF, GPIO_Pin_10); // LED1对应引脚GPIOF.10拉低,亮 等同LED1=0
delay_ms(500); // 延时300ms
/* 位带操作 */
LED0 = 0; // LED0亮
LED1 = 1; // LED1灭
delay_ms(500);
LED0 = 1; // LED0灭
LED1 = 0; // LED1亮
delay_ms(500);
/* 寄存器操作 */
GPIOF->BSRRH = GPIO_Pin_9; // LED0亮
GPIOF->BSRRL = GPIO_Pin_10; // LED1灭
delay_ms(500);
GPIOF->BSRRL = GPIO_Pin_9; // LED0灭
GPIOF->BSRRH = GPIO_Pin_10; // LED1亮
delay_ms(500);
}
}
2.蜂鸣器实验
2.1 原理图
- MCU引脚
- 涉及外设
2.2 代码示例
- beep.c
- 库函数版本
#include "beep.h"
void BEEP_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); // 使能GPIOF时钟
//初始化蜂鸣器对应引脚GPIOF8
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; // 普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; // 下拉
GPIO_Init(GPIOF, &GPIO_InitStructure); // 初始化GPIO
GPIO_ResetBits(GPIOF, GPIO_Pin_8); // 蜂鸣器对应引脚GPIOF8拉低
}
- 寄存器版本
#include "beep.h"
void BEEP_Init(void)
{
RCC->AHB1ENR |= 1 << 5; // 使能PORTF时钟
GPIO_Set(GPIOF, PIN8, GPIO_MODE_OUT, GPIO_OTYPE_PP, GPIO_SPEED_100M, GPIO_PUPD_PD); // PF8设置,下拉
BEEP = 0; // 关闭蜂鸣器
}
- beep.h
#ifndef __BEEP_H
#define __BEEP_H
#include "sys.h"
#define BEEP PFout(8) // 蜂鸣器控制IO
void BEEP_Init(void); // 初始化
#endif
- main.c
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "beep.h"
int main(void)
{
//Stm32_Clock_Init(336, 8, 2, 7); // 设置时钟,168Mhz
delay_init(168); // 初始化延时函数
BEEP_Init(); // 初始化蜂鸣器端口
while(1)
{
/* 库函数操作 */
GPIO_ResetBits(GPIOF,GPIO_Pin_8); // BEEP引脚拉低,等同BEEP=0
delay_ms(300); // 延时300ms
GPIO_SetBits(GPIOF,GPIO_Pin_8); // BEEP引脚拉高,等同BEEP=1
delay_ms(300); // 延时300ms
/* 位带操作 */
BEEP = 0;
delay_ms(300);
BEEP = 1;
delay_ms(300);
}
}
3.按键输入实验
3.1 原理图
- MCU引脚
- 涉及外设
3.2 代码示例
- key.c
- 库函数版本
#include "key.h"
#include "delay.h"
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOE, ENABLE); // 使能GPIOA,GPIOE时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; // KEY0 KEY1 KEY2对应引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; // 普通输入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // 上拉
GPIO_Init(GPIOE, &GPIO_InitStructure); // 初始化GPIOE2,3,4
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // WK_UP对应引脚PA0
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; // 下拉
GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化GPIOA0
}
//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//0,没有任何按键按下
//1,KEY0按下
//2,KEY1按下
//3,KEY2按下
//4,WKUP按下 WK_UP
//注意此函数有响应优先级,KEY0>KEY1>KEY2>WK_UP!!
u8 KEY_Scan(u8 mode)
{
static u8 key_up = 1; // 按键按松开标志
if (mode) key_up = 1; // 支持连按
if (key_up && ((KEY0==0) || (KEY1==0) || (KEY2==0) || (WK_UP==1)))
{
delay_ms(10); // 去抖动
key_up = 0;
if (KEY0==0) return 1;
else if (KEY1==0) return 2;
else if (KEY2==0) return 3;
else if (WK_UP==1) return 4;
}
else if ((KEY0 == 1) && (KEY1 == 1) && (KEY2 == 1) && (WK_UP == 0)) key_up = 1;
return 0; // 无按键按下
}
- 寄存器版本
#include "key.h"
#include "delay.h"
void KEY_Init(void)
{
RCC->AHB1ENR |= 1 << 0; // 使能PORTA时钟
RCC->AHB1ENR |= 1 << 4; // 使能PORTE时钟
GPIO_Set(GPIOE, PIN2|PIN3|PIN4, GPIO_MODE_IN, 0, 0, GPIO_PUPD_PU); // PE2~4设置上拉输入
GPIO_Set(GPIOA, PIN0, GPIO_MODE_IN, 0, 0, GPIO_PUPD_PD); // PA0设置为下拉输入
}
//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//0,没有任何按键按下
//1,KEY0按下
//2,KEY1按下
//3,KEY2按下
//4,WKUP按下 WK_UP
//注意此函数有响应优先级,KEY0>KEY1>KEY2>WK_UP!!
u8 KEY_Scan(u8 mode)
{
static u8 key_up = 1; // 按键按松开标志
if (mode) key_up = 1; // 支持连按
if (key_up && ((KEY0==0) || (KEY1==0) || (KEY2==0) || (WK_UP==1)))
{
delay_ms(10); // 去抖动
key_up = 0;
if (KEY0==0) return 1;
else if (KEY1==0) return 2;
else if (KEY2==0) return 3;
else if (WK_UP==1) return 4;
}
else if ((KEY0 == 1) && (KEY1 == 1) && (KEY2 == 1) && (WK_UP == 0)) key_up = 1;
return 0; // 无按键按下
}
- key.h
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
/*下面的方式是通过直接操作库函数方式读取IO*/
#define KEY0 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4) // PE4
#define KEY1 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3) // PE3
#define KEY2 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2) // PE2
#define WK_UP GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) // PA0
/*下面方式是通过位带操作方式读取IO*/
#define KEY0 PEin(4) //PE4
#define KEY1 PEin(3) //PE3
#define KEY2 PEin(2) //P32
#define WK_UP PAin(0) //PA0
#define KEY0_PRES 1
#define KEY1_PRES 2
#define KEY2_PRES 3
#define WKUP_PRES 4
void KEY_Init(void); // IO初始化
u8 KEY_Scan(u8); // 按键扫描函数
#endif
- main.c
#include "sys.h"
#include "delay.h"
#include "key.h"
int main(void)
{
u8 key; // 保存键值
//Stm32_Clock_Init(336, 8, 2, 7); // 设置时钟,168Mhz
delay_init(168); // 初始化延时函数
KEY_Init(); // 初始化与按键连接的硬件接口
while(1)
{
key = KEY_Scan(0); // 得到键值
if (key)
{
switch (key)
{
case WKUP_PRES: // 控制蜂鸣器
BEEP = !BEEP;
break;
case KEY0_PRES: // 控制LED0翻转
LED0 = !LED0;
break;
case KEY1_PRES: // 控制LED1翻转
LED1 = !LED1;
break;
case KEY2_PRES: // 同时控制LED0,LED1翻转
LED0 = !LED0;
LED1 = !LED1;
break;
}
}
else delay_ms(10);
}
}
总结
本章为TMS320F280049学习系列文章 第三章:GPIO相关配置实验