本帖最后由 yuyy1989 于 2023-7-21 15:54 编辑
#申请原创# @21小跑堂
4.按键+定时器测试
NUCLEO-H563ZI预置一个可编程按键,接在了PC13上,高电平触发,打开之前创建的工程,由于选择的是开发板,生成工程时已经将按键的初始化代码写进去了,我们只需要调用即可。
4.1按键轮询测试
按键轮询是间隔很短时间不断查询GPIO状态,从而得知是否有按键动作,按键在按下或释放的过程中,可能会伴随抖动如图示意
在这抖动过程中,会产生多次高低电平,导致被识别为多次按键操作,因此为了避免误判需要进行去抖处理,软件上可以用延时来去抖
用扫描的方式写个按键程序,用按键控制3个LED的亮灭,代码实现
void usercode_loop(void)
{
if(HAL_GPIO_ReadPin(USER_BUTTON_GPIO_Port,USER_BUTTON_Pin) == GPIO_PIN_SET)
{
HAL_Delay(10);
while(HAL_GPIO_ReadPin(USER_BUTTON_GPIO_Port,USER_BUTTON_Pin) == GPIO_PIN_SET);
HAL_GPIO_TogglePin(LED1_GREEN_GPIO_Port,LED1_GREEN_Pin);
HAL_GPIO_TogglePin(LED2_YELLOW_GPIO_Port,LED2_YELLOW_Pin);
HAL_GPIO_TogglePin(LED3_RED_GPIO_Port,LED3_RED_Pin);
}
}
编译烧录查看效果
4.2按键中断测试
与上面的轮询方法不同,这种方式并不用一直查询GPIO的状态,按键状态改变时会产生中断,程序在检测到中断后再判断按键状态,接下来用STM32CubeMX配置这个按键的中断
双击工程目录中的这个.ioc文件打开STM32CubeMX
找到这个按键,发现已经设置为上升沿中断了
切换到NVIC标签,发现有2个中断但是都没使能
怎么判断哪一个是这个按键的中断呢,很简单,把鼠标停在右侧按键的GPIO上就能显示GPIO对应的中断名了
把对应的中断Enable勾选上,点击GENERATE CODE,再重新打开MDK,可以看到中断初始化和中断处理方法都添加好了
用中断再实现一下按键程序,这次改成每按一次按键改变一个LED的状态,代码实现
uint8_t ledindex = 0;
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
if(HAL_GPIO_ReadPin(USER_BUTTON_GPIO_Port,USER_BUTTON_Pin) == GPIO_PIN_SET)
{
switch(ledindex)
{
case 1:
HAL_GPIO_TogglePin(LED2_YELLOW_GPIO_Port,LED2_YELLOW_Pin);
break;
case 2:
HAL_GPIO_TogglePin(LED3_RED_GPIO_Port,LED3_RED_Pin);
break;
default:
HAL_GPIO_TogglePin(LED1_GREEN_GPIO_Port,LED1_GREEN_Pin);
ledindex = 0;
break;
}
ledindex += 1;
}
}
编译烧录查看效果
4.3定时器测试
STM32H563有多达24个timer可用,接下来选一个timer来写个流水灯程序,用按键调速度
双击工程目录中的这个.ioc文件打开STM32CubeMX,找到Timers,这里选择TIM1,Clock Source选择Internal Clock,预分频设置为249计数周期最大值设置为999,这样就得到了一个1毫秒的定时器
开启中断
点击GENERATE CODE,打开工程,找到Timer1的初始化方法,这里并没有开启定时中断,需要手动加入开启代码
流水灯代码
uint8_t ledindex = 0;
uint16_t timer1count = 0;
uint16_t timer1countmax = 1000;
void runled()
{
switch(ledindex)
{
case 1:
HAL_GPIO_TogglePin(LED2_YELLOW_GPIO_Port,LED2_YELLOW_Pin);
break;
case 2:
HAL_GPIO_TogglePin(LED3_RED_GPIO_Port,LED3_RED_Pin);
break;
default:
HAL_GPIO_TogglePin(LED1_GREEN_GPIO_Port,LED1_GREEN_Pin);
ledindex = 0;
break;
}
ledindex += 1;
}
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
if(HAL_GPIO_ReadPin(USER_BUTTON_GPIO_Port,USER_BUTTON_Pin) == GPIO_PIN_SET)
{
if(timer1countmax == 1000)
timer1countmax = 500;
else if(timer1countmax == 500)
timer1countmax = 250;
else if(timer1countmax == 250)
timer1countmax = 100;
else
timer1countmax = 1000;
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
timer1count+=1;
if(timer1count >= timer1countmax)
{
timer1count = 0;
runled();
}
}
编译烧录查看效果
4.4PWM输出测试
从STM32CubeMX里看了一下这三个LED的GPIO,绿色的可以用PWM输出,用这个LED做个PWM调光程序,按键修改亮度
点击GPIO选择TIM3_CH3
在左边的Timers里选择TIM3,Channel3设置为PWM,其它的设置保持和之前TIM1一样即可
同样PWM也要手动开启输出
按键控制占空比代码
uint16_t timer3pwm = 0;
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
if(HAL_GPIO_ReadPin(USER_BUTTON_GPIO_Port,USER_BUTTON_Pin) == GPIO_PIN_SET)
{
if(timer3pwm == 0)
timer3pwm = 50;
else if(timer3pwm == 50)
timer3pwm = 100;
else if(timer3pwm == 100)
timer3pwm = 250;
else if(timer3pwm == 250)
timer3pwm = 500;
else if(timer3pwm == 500)
timer3pwm = 1000;
else
timer3pwm = 0;
__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_3,timer3pwm);
}
}
编译烧录,看看效果
|