文章目录
一、前言
1.1 开发环境
①Keil MDK V5.38a
②STM32CubemxV6.10.0
③正点原子战舰板(STM32F103ZET6)
④高速DAP仿真器
1.2 GPIO电路原理
1.3 板卡电路原理
1.3.1 按键电路原理
由下图可知,Key0、Key1和Key2会在按键按下时,将对应的Gpio管脚连接到GND,即将Gpio管脚拉低,当按键没有按下时Gpio管脚应该默认为高电平,用来区分按键按下和未按下两种状态;所以需要使能Gpio管脚的输入模式,并配置GPIO管脚上拉。
1.3.2 Led电路原理
由下图可知,当Gpio管脚输出低电平时,会在Led的两端产生电压差,从而驱动Led点亮,当Gpio管脚输出高电平时,会在Led的两端没有电压差,Led熄灭;所以需要使能Gpio管脚为输出模式,并配置Gpio管脚上拉。
1.3.3 Beep电路原理
由下图可知,当Gpio管脚输出高电平时,会在导通三极管,同时Beep的两端会产生电压差,从而驱动Beep鸣叫,当Gpio管脚输出低电平时,会在关断三极管,同时Beep的两端没有电压差,Beep停止鸣叫;所以需要使能Gpio管脚为输出模式,并配置Gpio管脚下拉。
二、功能实现
2.1 配置STM32Cubemx工程
1、配置MCU调试功能(PS:若不配置该参数可能导致程序下载一次后,再次下载失败的情况)
根据实际调试器与MCU引脚的连接数量选择调试参数,通常只连接2个管脚选择Serial Wire。
2、配置连接LED1的GPIO管脚(鼠标左键选择GPIO_Output即可,鼠标右键选择Enter User Label即可设置GPIO管脚名称)
3、配置连接BEEP的GPIO管脚
4、配置连接KEY2的GPIO管脚
5、配置连接KEY1的GPIO管脚
6、配置连接KEY0的GPIO管脚
7、配置MCU时钟树,默认使用外部时钟源,并配置系统时钟为72MHz
8、生成Keil MDK工程
2.2 Keil MDK工程编码
2.2.1 按键功能代码
uint32_t Independent_Button_Scan(void)
{
if(GPIO_PIN_SET == HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin))
{
return 1;
}
else if(GPIO_PIN_SET == HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin))
{
return 2;
}
else if(GPIO_PIN_SET == HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin))
{
return 3;
}
return 0;
}
2.2.2 LED灯功能代码
void Led1_Open(void)
{
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
}
void Led1_Close(void)
{
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
}
void Led1_Toggle(void)
{
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
}
2.2.3 Beep功能代码
void Beep_Open(void)
{
HAL_GPIO_WritePin(BEEP_GPIO_Port, BEEP_Pin, GPIO_PIN_SET);
}
void Beep_Close(void)
{
HAL_GPIO_WritePin(BEEP_GPIO_Port, BEEP_Pin, GPIO_PIN_RESET);
}
void Bepp_Toggle(void)
{
HAL_GPIO_TogglePin(BEEP_GPIO_Port, BEEP_Pin);
}
2.2.4 Main函数代码
/* 重定义HAL_Delay,优化低延时的延时误差 */
void HAL_Delay(uint32_t Delay)
{
uint32_t tickstart = HAL_GetTick();
uint32_t wait = Delay;
/* Add a freq to guarantee minimum wait */
if (0 == wait)
{
wait += (uint32_t)(uwTickFreq);
}
while ((HAL_GetTick() - tickstart) < wait)
{
}
}
void Main_Handle(void)
{
static uint32_t beep_cnt = 0;
static uint32_t beep_flag = 0;
static uint32_t button_cnt = 0;
static uint32_t filter_cnt = 0;
Led1_Open();
Beep_Open();
HAL_Delay(100);
Led1_Close();
Beep_Close();
while(1)
{
if(button_cnt++ >= 10)
{
button_cnt = 0;
/* 按键抖动滤波 */
if(0 == filter_cnt)
{
switch(Independent_Button_Scan())
{
case 1:Led1_Toggle();filter_cnt = 30;break;
case 2:Beep_Toggle();filter_cnt = 30;break;
case 3:beep_flag = 1;Beep_Toggle();filter_cnt = 30;break;
default:break;
}
}
else
{
filter_cnt--;
}
}
if((0 != beep_flag) && (beep_cnt++ >= 300))
{
beep_cnt = 0;
beep_flag = 0;
Beep_Toggle();
}
HAL_Delay(1);
}
}
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
Main_Handle();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
2.2.5 Keil MDK调试参数配置
2.2.6 下载验证
①板卡上电后,Beep鸣叫100ms后关闭,同时Led1常亮100ms后关闭
②按下Key0后,Led1状态翻转
③按下Key1后,Beep状态翻转
④按下Key2后,Beep鸣叫300ms后关闭
三、参考资料
标签:Beep,HAL,void,输入输出,STM32,GPIO,2.2,Gpio,管脚 From: https://blog.csdn.net/qq_45216743/article/details/137053589[1]正点原子战舰板原理图-WarShip STM32F1_V3.4_SCH
[2]STM32F1开发指南-HAL库版本_V1.1
[3]STM32中文参考手册_V10
[4]Cortex-M3权威指南(中文)