注意其Vgs即对应其输出控制G。。。
PD13设置为推挽输出模式设置:
GPIOD_MODER对应分组13设置为01也即通用输出模式(从0开始计数)-> GPIO_OTYPER对应OT13设置为0也即推挽输出 -> 注意其输出还要设置速度(而输入则不需要),相应在GPIO_OSPEEDR中同样13分组中进行设置 -> 注意其GPIO_PUPDR对应13分组也要设置为无上拉或无下拉状态。。。
操了(跟着走一遍发现真牛逼,豁然开朗的感觉。。。在高阶学习中其硬件难的不是其冗杂的代码和硬件实现的细节,难的是对硬件架构的理解。。。(当然%99的人都还未到架构阶段))
外设寄存器基地址。。。
注意其对应结构体元素都是有参考值的。。。(切记不可自己乱设。。。)
关于其GPIO_PIN_SET不理解的可以补补C语言枚举类型相关知识。。。
关于其调用。。。
注意对下面逻辑地址的理解。。。
先编译进而有利于进一步的查找。。。
因为还没有传参数这里编译错误很正常。。。
关于 Error: L6200E: Symbol led_init multiply defined (by led.o and main.o). 的解决办法(简单来说就是其变量重复定义了,需要通过全局查找来解决其重复问题)。。。
注释掉多余的定义相应即可正确编译。。。
刚写完函数烧录进去发现没有反应(问题就是调试设置中没有选中Reset and run选项,程序下载进去了,就是没有运行!)。。。
OK了
main.c
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"//其内包含LED初始化函数声明
//对应其已在头文件中声明故不再需要
//void led_init(void); /* LED初始化函数声明 */
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */
delay_init(168); /* 延时初始化 */
led_init(); /* 初始化LED */
while(1)
{
HAL_GPIO_WritePin(GPIOF,GPIO_PIN_9,GPIO_PIN_RESET); /* LED0 亮 */
//HAL_GPIO_WritePin(GPIOF,GPIO_PIN_10,GPIO_PIN_SET); /* LED1 灭 */
delay_ms(500);
HAL_GPIO_WritePin(GPIOF,GPIO_PIN_9,GPIO_PIN_SET); /* LED0 灭 */
//HAL_GPIO_WritePin(GPIOF,GPIO_PIN_10,GPIO_PIN_RESET); /* LED1 亮 */
delay_ms(500);
}
}
/**
* @brief 初始化LED相关IO口, 并使能时钟
* @param 无
* @retval 无
*/
//void led_init(void)
//{
// GPIO_InitTypeDef gpio_init_struct;
//
// __HAL_RCC_GPIOF_CLK_ENABLE(); /* LED0,LED1时钟使能 */
// gpio_init_struct.Pin = GPIO_PIN_9; /* LED0引脚 */
// gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */
// gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
// gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
// HAL_GPIO_Init(GPIOF, &gpio_init_struct); /* 初始化LED0引脚 */
// gpio_init_struct.Pin = GPIO_PIN_10; /* LED1引脚 */
// HAL_GPIO_Init(GPIOF, &gpio_init_struct); /* 初始化LED1引脚 */
// HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, GPIO_PIN_SET); /* LED0 灭 */
// HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, GPIO_PIN_SET);/* LED1 灭 */
//}
led.h
#ifndef __LED_H//防止其重复包含和编译。。。
#define __LED_H
#include "./SYSTEM/sys/sys.h"
void led_init(void);
#endif
led.c
#include "./BSP/LED/led.h"
void led_init(void){
GPIO_InitTypeDef gpio_init_struct;//定义结构体,为了下面的传参
__HAL_RCC_GPIOF_CLK_ENABLE();//对该GPIO组进行使能
gpio_init_struct.Pin = GPIO_PIN_9;//选择组内IO口
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;//推挽输出模式
gpio_init_struct.Pull = GPIO_PULLUP;//上拉
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;//高速
HAL_GPIO_Init(GPIOF,&gpio_init_struct);//对应组内IO口初始化
//对组内另一口进行初始化
gpio_init_struct.Pin = GPIO_PIN_10;
HAL_GPIO_Init(GPIOF,&gpio_init_struct);
//其中其GPIOF是对应的组,接着其参数即对应其组内IO口
//注意其GPIO_PIN_SET在相应的枚举类型中定义为1,故1和1之间没有电压故LED灯不亮
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, GPIO_PIN_SET) ;
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, GPIO_PIN_SET) ;
}
//void led_init(void)
//{
// GPIO_InitTypeDef gpio_init_struct;
//
// __HAL_RCC_GPIOF_CLK_ENABLE(); /* LED0,LED1时钟使能 */
// gpio_init_struct.Pin = GPIO_PIN_9; /* LED0引脚 */
// gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */
// gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
// gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
// HAL_GPIO_Init(GPIOF, &gpio_init_struct); /* 初始化LED0引脚 */
// gpio_init_struct.Pin = GPIO_PIN_10; /* LED1引脚 */
// HAL_GPIO_Init(GPIOF, &gpio_init_struct); /* 初始化LED1引脚 */
// //HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, GPIO_PIN_SET); /* LED0 灭 */
// //HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, GPIO_PIN_SET);/* LED1 灭 */
// HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, GPIO_PIN_RESET); /* LED0 亮 */
// HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, GPIO_PIN_RESET);/* LED1 亮 */
//}
附:
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
typedef struct
{
uint32_t Pin; /*!< Specifies the GPIO pins to be configured.
This parameter can be any value of @ref GPIO_pins_define */
uint32_t Mode; /*!< Specifies the operating mode for the selected pins.
This parameter can be a value of @ref GPIO_mode_define */
uint32_t Pull; /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.
This parameter can be a value of @ref GPIO_pull_define */
uint32_t Speed; /*!< Specifies the speed for the selected pins.
This parameter can be a value of @ref GPIO_speed_define */
uint32_t Alternate; /*!< Peripheral to be connected to the selected pins.
This parameter can be a value of @ref GPIO_Alternate_function_selection */
}GPIO_InitTypeDef;
typedef enum
{
GPIO_PIN_RESET = 0,
GPIO_PIN_SET
}GPIO_PinState;
#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 GPIO_PIN_MASK 0x0000FFFFU /* PIN mask for assert test */
#define GPIO_MODE_INPUT MODE_INPUT /*!< Input Floating Mode */
#define GPIO_MODE_OUTPUT_PP (MODE_PP | MODE_OUTPUT) /*!< Output Push Pull Mode */
#define GPIO_MODE_OUTPUT_OD (MODE_OD | MODE_OUTPUT) /*!< Output Open Drain Mode */
#define GPIO_MODE_AF_PP (MODE_PP | MODE_AF) /*!< Alternate Function Push Pull Mode */
#define GPIO_MODE_AF_OD (MODE_OD | MODE_AF) /*!< Alternate Function Open Drain Mode */
#define GPIO_MODE_ANALOG MODE_ANALOG /*!< Analog Mode */
接下来用翻转方式点亮LED灯。。。
main.c
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"//其内包含LED初始化函数声明
//对应其已在头文件中声明故不再需要
//void led_init(void); /* LED初始化函数声明 */
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */
delay_init(168); /* 延时初始化 */
led_init(); /* 初始化LED */
while(1)
{
HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);
delay_ms(1000);
HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);
delay_ms(1000);
}
}
注意初始化(不初始化其编译器也不报错。。。)
通过一个按键控制LED灯的亮灭。。。
main.c
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"//其内包含LED初始化函数声明
#include "./BSP/KEY/key.h"
//对应其已在头文件中声明故不再需要
//void led_init(void); /* LED初始化函数声明 */
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */
delay_init(168); /* 延时初始化 */
led_init(); /* 初始化LED */
key_init();
while(1)
{
// HAL_GPIO_WritePin(GPIOF,GPIO_PIN_9,GPIO_PIN_RESET); /* LED0 亮 */
// //HAL_GPIO_WritePin(GPIOF,GPIO_PIN_10,GPIO_PIN_SET); /* LED1 灭 */
// delay_ms(500);
// HAL_GPIO_WritePin(GPIOF,GPIO_PIN_9,GPIO_PIN_SET); /* LED0 灭 */
// //HAL_GPIO_WritePin(GPIOF,GPIO_PIN_10,GPIO_PIN_RESET); /* LED1 亮 */
// delay_ms(500);
// HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);
// delay_ms(1000);
// HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);
// delay_ms(1000);
if(key_scan()){
HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);
}
else{
delay_ms(10);
}
}
}
key.h
#ifndef __KEY_H//防止其重复包含和编译。。。
#define __KEY_H
#include "./SYSTEM/sys/sys.h"
void key_init(void);
uint8_t key_scan(void);
#endif
//固定搭配
key.c
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
void key_init(void){
GPIO_InitTypeDef gpio_init_struct;//定义结构体,为了下面的传参
__HAL_RCC_GPIOE_CLK_ENABLE();//对该GPIO组进行使能
//KEY0
gpio_init_struct.Pin = GPIO_PIN_4;//选择组内IO口
gpio_init_struct.Mode = GPIO_MODE_INPUT;//输入模式(按键)
gpio_init_struct.Pull = GPIO_PULLUP;//上拉(对应其按键不按下时得到一个稳定的高电平)
//输入用不到速度配置
//gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;//高速
HAL_GPIO_Init(GPIOE,&gpio_init_struct);//对应组内IO口初始化(上拉输入)
// //KEY1
// gpio_init_struct.Pin = GPIO_PIN_3;//选择组内IO口
// gpio_init_struct.Mode = GPIO_MODE_INPUT;//输入模式(按键)
// gpio_init_struct.Pull = GPIO_PULLUP;//上拉(对应其按键不按下时得到一个稳定的高电平)
// //输入用不到速度配置
// //gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;//高速
// HAL_GPIO_Init(GPIOE,&gpio_init_struct);//对应组内IO口初始化(上拉输入)
// //KEY2
// gpio_init_struct.Pin = GPIO_PIN_2;//选择组内IO口
// gpio_init_struct.Mode = GPIO_MODE_INPUT;//输入模式(按键)
// gpio_init_struct.Pull = GPIO_PULLUP;//上拉(对应其按键不按下时得到一个稳定的高电平)
// //输入用不到速度配置
// //gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;//高速
// HAL_GPIO_Init(GPIOE,&gpio_init_struct);//对应组内IO口初始化(上拉输入)
//
// //KEYUP
// gpio_init_struct.Pin = GPIO_PIN_0;//选择组内IO口
// gpio_init_struct.Mode = GPIO_MODE_INPUT;//输入模式(按键)
// gpio_init_struct.Pull = GPIO_PULLDOWN;//上拉(对应其按键不按下时得到一个稳定的高电平)
// //输入用不到速度配置
// //gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;//高速
// HAL_GPIO_Init(GPIOA,&gpio_init_struct);//对应组内IO口初始化(上拉输入)
}
uint8_t key_scan(void){
if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==0){
delay_ms(10);
if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==0){
while(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==0);
return 1;
}
}
return 0;
}
注意别忘了使能。。。
下面的这种判断逻辑有BUG。。。
换成下面这种逻辑就正常了。。。
通过四个按键控制LED灯的亮灭
main.c
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"//其内包含LED初始化函数声明
#include "./BSP/KEY/key.h"
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */
delay_init(168); /* 延时初始化 */
led_init(); /* 初始化LED */
key_init();
while(1)
{
uint8_t num = key_scan();
if(num==0){
//在调试模式下其四个按键功能均正常但实际运行中其只相应第一个按键。。。
//if(key_scan()==0){//注意此种循环判断逻辑结合其按键判断中的while()循环会导致其只能识别第一个按键,
//由其按键判断函数while()循环故只有当按键结束时对应按键才判断完成而若其!=1则此次按下过程作废,因此会存在
//按下无效的情况,而其为什么是只响应第一个就不得而知了。。。
HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);
}
if(num==1){
//if(key_scan()==1){
HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);
}
if(num==2){
//if(key_scan()==2){
HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);
HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);
}
if(num==3){
//if(key_scan()==3){
//delay_ms(10);
HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);
}
else{
delay_ms(10);
}
}
}
key.h
#ifndef __KEY_H//防止其重复包含和编译。。。
#define __KEY_H
#include "./SYSTEM/sys/sys.h"
#define KEY0 HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4) /* 读取KEY0引脚 */
#define KEY1 HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3) /* 读取KEY1引脚 */
#define KEY2 HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2) /* 读取KEY2引脚 */
#define WK_UP HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) /* 读取WKUP引脚 */
void key_init(void);
uint8_t key_scan(void);
#endif
//固定搭配
key.c
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
void key_init(void){
GPIO_InitTypeDef gpio_init_struct;//定义结构体,为了下面的传参
//__HAL_RCC_GPIOF_CLK_ENABLE();//对该GPIO组进行使能
__HAL_RCC_GPIOA_CLK_ENABLE();//对该GPIO组进行使能
__HAL_RCC_GPIOE_CLK_ENABLE();//对该GPIO组进行使能
//KEY0
gpio_init_struct.Pin = GPIO_PIN_4;//选择组内IO口
gpio_init_struct.Mode = GPIO_MODE_INPUT;//输入模式(按键)
gpio_init_struct.Pull = GPIO_PULLUP;//上拉(对应其按键不按下时得到一个稳定的高电平)
//输入用不到速度配置
//gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;//高速
HAL_GPIO_Init(GPIOE,&gpio_init_struct);//对应组内IO口初始化(上拉输入)
//KEY1
gpio_init_struct.Pin = GPIO_PIN_3;//选择组内IO口
gpio_init_struct.Mode = GPIO_MODE_INPUT;//输入模式(按键)
gpio_init_struct.Pull = GPIO_PULLUP;//上拉(对应其按键不按下时得到一个稳定的高电平)
//输入用不到速度配置
//gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;//高速
HAL_GPIO_Init(GPIOE,&gpio_init_struct);//对应组内IO口初始化(上拉输入)
//KEY2
gpio_init_struct.Pin = GPIO_PIN_2;//选择组内IO口
gpio_init_struct.Mode = GPIO_MODE_INPUT;//输入模式(按键)
gpio_init_struct.Pull = GPIO_PULLUP;//上拉(对应其按键不按下时得到一个稳定的高电平)
//输入用不到速度配置
//gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;//高速
HAL_GPIO_Init(GPIOE,&gpio_init_struct);//对应组内IO口初始化(上拉输入)
//KEYUP
gpio_init_struct.Pin = GPIO_PIN_0;//选择组内IO口
gpio_init_struct.Mode = GPIO_MODE_INPUT;//输入模式(按键)
gpio_init_struct.Pull = GPIO_PULLDOWN;//下拉(对应其按键不按下时得到一个稳定的低电平)
//输入用不到速度配置
//gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;//高速
HAL_GPIO_Init(GPIOA,&gpio_init_struct);//对应组内IO口初始化(上拉输入)
}
uint8_t key_scan(void){
uint8_t keyval = 5;
if(KEY0 == 0 || KEY1 == 0 || KEY2 == 0 || WK_UP == 1){//对应有按键被按下
delay_ms(10);
if(KEY0==0){
while(KEY0==0);
//keyval = 0;
return 0;
}
if(KEY1==0){
while(KEY1==0);
//keyval = 1;
return 1;
}
if(KEY2==0){
while(KEY2==0);
//keyval = 2;
return 2;
}
if(WK_UP){
while(WK_UP==1);
//keyval = 3;
return 3;
}
}
return keyval;
}
四个按键控制LED和蜂鸣器
main.
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"//其内包含LED初始化函数声明
#include "./BSP/KEY/key.h"
#include "./BSP/BEEP/beep.h"
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */
delay_init(168); /* 延时初始化 */
led_init(); /* 初始化LED */
key_init();
beep_init();
while(1)
{
uint8_t num = key_scan();
if(num==0){
//在调试模式下其四个按键功能均正常但实际运行中其只相应第一个按键。。。
//if(key_scan()==0){//注意此种循环判断逻辑结合其按键判断中的while()循环会导致其只能识别第一个按键,
//由其按键判断函数while()循环故只有当按键结束时对应按键才判断完成而若其!=1则此次按下过程作废,因此会存在
//按下无效的情况,而其为什么是只响应第一个就不得而知了。。。
HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);
}
if(num==1){
//if(key_scan()==1){
HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);
}
if(num==2){
//if(key_scan()==2){
HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);
HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);
}
if(num==3){
//if(key_scan()==3){
//delay_ms(10);
//HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);
HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_8);
}
else{
delay_ms(10);
}
}
}
beep.h
#ifndef __BEEP_H//防止其重复包含和编译。。。
#define __BEEP_H
#include "./SYSTEM/sys/sys.h"
void beep_init(void);
#endif
//固定搭配
beep.c
#include "./BSP/BEEP/beep.h"
void beep_init(void)
{
GPIO_InitTypeDef gpio_init_struct;
__HAL_RCC_GPIOF_CLK_ENABLE();//对该GPIO组进行使能
gpio_init_struct.Pin = GPIO_PIN_8; /* 蜂鸣器引脚 */
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */
//注意其推挽输出其无论设置上拉还是下拉相应都是无效的
//gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
HAL_GPIO_Init(GPIOF, &gpio_init_struct); /* 初始化蜂鸣器引脚 */
//BEEP(0); /* 关闭蜂鸣器 */
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_8, GPIO_PIN_RESET);
}
蜂鸣器同上(关键要注意对应的GPIO组要使能且按键判断对应的端口别搞错了)。。。