本帖最后由 yuyy1989 于 2023-7-13 20:37 编辑
#申请原创# @21小跑堂
4.按键+定时器测试
先整理了一下开发板支持文件,因为工程只针对APM32F407IG Tiny Board,便将其它板子的文件都删掉了,目录结构变成了这样
把目录下的几个bsp文件也都加到了工程中
bsp的头文件有包含main.h,但是我自己创建的这个工程并没有这个文件,就都改成了Board_APM32F407_TINY.h,另外修改的时候发现Board_APM32F407_TINY中的bsp_usart.c中的串口初始化函数中写的还是APM_MINI_COMInit,应该是官方漏改了,不过也在这里给官方提个意见,这些开发板支持函数还是不要加什么MINI TINY的了,不然的话如果要把例程移植到其它板子上还要去替换这些函数名,一不小心就会有像前面提到的那样有漏掉的,如果能保持一致就省事多了
4.1 按键轮询
通过不断的查询按键电平状态来判断按键是否有按下,由于按下键时有可能会抖动所以延时一下再次判断电平,简单实现按键1 2控制LED2 3亮灭的代码
代码示例
- #include "Board_APM32F407_TINY.h"
- #include "bsp_delay.h"
- int main(void)
- {
- APM_DelayInit();
- APM_TINY_LEDInit(LED2);
- APM_TINY_LEDInit(LED3);
- APM_TINY_PBInit(BUTTON_KEY1,BUTTON_MODE_GPIO);
- APM_TINY_PBInit(BUTTON_KEY2,BUTTON_MODE_GPIO);
- while (1)
- {
- if(APM_TINY_PBGetState(BUTTON_KEY1) == BIT_RESET)
- {
- APM_DelayMs(30);
- if(APM_TINY_PBGetState(BUTTON_KEY1) == BIT_RESET)
- {
- while(APM_TINY_PBGetState(BUTTON_KEY1) == BIT_RESET);
- APM_TINY_LEDToggle(LED2);
- }
- }
- if(APM_TINY_PBGetState(BUTTON_KEY2) == BIT_RESET)
- {
- APM_DelayMs(30);
- if(APM_TINY_PBGetState(BUTTON_KEY2) == BIT_RESET)
- {
- while(APM_TINY_PBGetState(BUTTON_KEY2) == BIT_RESET);
- APM_TINY_LEDToggle(LED3);
- }
- }
- }
- }
- void SysTick_Handler(void)
- {
- APM_DelayTickDec();
- }
编译烧录查看效果
4.2 按键中断
配置按键IO在下降沿时产生中断,由于按下键时有可能会抖动导致多次中断,还是需要延时判断一下按键电平
代码示例
- #include "Board_APM32F407_TINY.h"
- #include "bsp_delay.h"
- uint8_t key1down = 0;
- uint8_t key2down = 0;
- int main(void)
- {
- APM_DelayInit();
- APM_TINY_LEDInit(LED2);
- APM_TINY_LEDInit(LED3);
- APM_TINY_PBInit(BUTTON_KEY1,BUTTON_MODE_EINT);
- APM_TINY_PBInit(BUTTON_KEY2,BUTTON_MODE_EINT);
- while (1)
- {
- if(key1down > 0)
- {
- key1down = 0;
- APM_DelayMs(30);
- if(APM_TINY_PBGetState(BUTTON_KEY1) == BIT_RESET)
- APM_TINY_LEDToggle(LED2);
- }
- if(key2down > 0)
- {
- key2down = 0;
- APM_DelayMs(30);
- if(APM_TINY_PBGetState(BUTTON_KEY2) == BIT_RESET)
- APM_TINY_LEDToggle(LED3);
- }
- }
- }
- void EINT15_10_IRQHandler(void)
- {
- if(EINT_ReadIntFlag(KEY1_BUTTON_EINT_LINE))
- {
- key1down = 1;
- EINT_ClearIntFlag(KEY1_BUTTON_EINT_LINE);
- }
- if(EINT_ReadIntFlag(KEY2_BUTTON_EINT_LINE))
- {
- key2down = 1;
- EINT_ClearIntFlag(KEY2_BUTTON_EINT_LINE);
- }
- }
- void SysTick_Handler(void)
- {
- APM_DelayTickDec();
- }
编译烧录查看效果
4.3 定时器
APM32F407有很多定时器定时器可用
用timer3做一个闪灯程序,按键切换闪烁速度
timer3是一个16位的定时器,从这张图中可以看到timer3的最大时钟是42M
之前对定时器时钟理解有误,对于定时器的频率还有额外描述
再来看看系统初始化时APB1和2的分频系数
所以timer3的时钟频率为84MHz,将timer3的时钟设置为1分频,预分频系数设置为42,计数周期设置为,1000就能得到一个每0.5ms触发一次的定时器
代码示例
- #include "Board_APM32F407_TINY.h"
- #include "bsp_delay.h"
- #include "apm32f4xx_tmr.h"
- volatile uint16_t tim3count = 0;
- volatile uint16_t tim3countmax = 200;
- void tim3_init()
- {
- TMR_BaseConfig_T TMR_TimeBaseStruct;
- RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR3);
- TMR_TimeBaseStruct.clockDivision = TMR_CLOCK_DIV_1;
- TMR_TimeBaseStruct.countMode = TMR_COUNTER_MODE_UP;
- TMR_TimeBaseStruct.division = 41;
- TMR_TimeBaseStruct.repetitionCounter = 0;
- TMR_TimeBaseStruct.period = 999;
- TMR_ConfigTimeBase(TMR3, &TMR_TimeBaseStruct);
- TMR_EnableInterrupt(TMR3,TMR_INT_UPDATE);
- NVIC_EnableIRQRequest(TMR3_IRQn, 0, 0);
- TMR_Enable(TMR3);
- }
- int main(void)
- {
- APM_DelayInit();
- APM_TINY_PBInit(BUTTON_KEY1,BUTTON_MODE_GPIO);
- APM_TINY_PBInit(BUTTON_KEY2,BUTTON_MODE_GPIO);
- tim3_init();
- while (1)
- {
- if(APM_TINY_PBGetState(BUTTON_KEY1) == BIT_RESET)
- {
- APM_DelayMs(30);
- if(APM_TINY_PBGetState(BUTTON_KEY1) == BIT_RESET)
- {
- while(APM_TINY_PBGetState(BUTTON_KEY1) == BIT_RESET);
- tim3countmax = 500;
- }
- }
- if(APM_TINY_PBGetState(BUTTON_KEY2) == BIT_RESET)
- {
- APM_DelayMs(30);
- if(APM_TINY_PBGetState(BUTTON_KEY2) == BIT_RESET)
- {
- while(APM_TINY_PBGetState(BUTTON_KEY2) == BIT_RESET);
- tim3countmax = 200;
- }
- }
- }
- }
- void SysTick_Handler(void)
- {
- APM_DelayTickDec();
- }
- void TMR3_IRQHandler(void)
- {
- if(TMR_ReadIntFlag(TMR3, TMR_INT_UPDATE) == SET)
- {
- if(tim3count < tim3countmax)
- tim3count++;
- else
- {
- tim3count = 0;
- APM_TINY_LEDToggle(LED2);
- APM_TINY_LEDToggle(LED3);
- }
- TMR_ClearIntFlag(TMR3, TMR_INT_UPDATE);
- }
- }
编译烧录查看效果
4.4 PWM输出
板子上的2个LED接的是PE5 PE6,可以使用timer9来实现pwm输出
写个程序两个按键分别控制LED的不同亮度,注意LED是低电平点亮,所以PWM要设置为低电平有效
代码示例
- #include "Board_APM32F407_TINY.h"
- #include "bsp_delay.h"
- #include "apm32f4xx_tmr.h"
- void pwm_init()
- {
- TMR_BaseConfig_T TMR_TimeBaseStruct;
- TMR_OCConfig_T OCcongigStruct;
- GPIO_Config_T GPIO_ConfigStruct;
-
- RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOE);
-
- GPIO_ConfigPinAF(GPIOE, GPIO_PIN_SOURCE_5, GPIO_AF_TMR9);
- GPIO_ConfigPinAF(GPIOE, GPIO_PIN_SOURCE_6, GPIO_AF_TMR9);
-
- GPIO_ConfigStruct.pin = GPIO_PIN_5 | GPIO_PIN_6;
- GPIO_ConfigStruct.mode = GPIO_MODE_AF;
- GPIO_ConfigStruct.otype = GPIO_OTYPE_PP;
- GPIO_ConfigStruct.speed = GPIO_SPEED_100MHz;
- GPIO_Config(GPIOE, &GPIO_ConfigStruct);
-
- RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR9);
- TMR_TimeBaseStruct.clockDivision = TMR_CLOCK_DIV_1;
- TMR_TimeBaseStruct.countMode = TMR_COUNTER_MODE_UP;
- TMR_TimeBaseStruct.division = 83;
- TMR_TimeBaseStruct.repetitionCounter = 0;
- TMR_TimeBaseStruct.period = 999; //频率1k 占空比调节0-1000
- TMR_ConfigTimeBase(TMR9, &TMR_TimeBaseStruct);
-
- OCcongigStruct.mode = TMR_OC_MODE_PWM1; //PWM模式1,计数小于比较值时输出有效电平
- OCcongigStruct.outputState = TMR_OC_STATE_ENABLE; //通道使能
- OCcongigStruct.idleState = TMR_OC_IDLE_STATE_SET; //空闲高电平
- OCcongigStruct.polarity = TMR_OC_POLARITY_LOW; //有效电平为低电平
- OCcongigStruct.outputNState = TMR_OC_NSTATE_DISABLE; //互补通道失能
- OCcongigStruct.nIdleState = TMR_OC_NIDLE_STATE_RESET;//互补通道空闲电平
- OCcongigStruct.nPolarity = TMR_OC_NPOLARITY_HIGH; //互补通道有效电平
- OCcongigStruct.pulse = 500; //初始50%
- TMR_ConfigOC1(TMR9, &OCcongigStruct);
- TMR_ConfigOC2(TMR9, &OCcongigStruct);
-
- TMR_ConfigOC1Preload(TMR9, TMR_OC_PRELOAD_ENABLE);
- TMR_EnableAutoReload(TMR9);
- TMR_Enable(TMR9);
- TMR_EnablePWMOutputs(TMR9);
- }
- int main(void)
- {
- APM_DelayInit();
- APM_TINY_LEDInit(LED2);
- APM_TINY_LEDInit(LED3);
- APM_TINY_PBInit(BUTTON_KEY1,BUTTON_MODE_GPIO);
- APM_TINY_PBInit(BUTTON_KEY2,BUTTON_MODE_GPIO);
- pwm_init();
- while (1)
- {
- if(APM_TINY_PBGetState(BUTTON_KEY1) == BIT_RESET)
- {
- APM_DelayMs(30);
- if(APM_TINY_PBGetState(BUTTON_KEY1) == BIT_RESET)
- {
- while(APM_TINY_PBGetState(BUTTON_KEY1) == BIT_RESET);
- TMR_ConfigCompare1(TMR9,900);
- TMR_ConfigCompare2(TMR9,900);
- }
- }
- if(APM_TINY_PBGetState(BUTTON_KEY2) == BIT_RESET)
- {
- APM_DelayMs(30);
- if(APM_TINY_PBGetState(BUTTON_KEY2) == BIT_RESET)
- {
- while(APM_TINY_PBGetState(BUTTON_KEY2) == BIT_RESET);
- TMR_ConfigCompare1(TMR9,100);
- TMR_ConfigCompare2(TMR9,100);
- }
- }
- }
- }
- void SysTick_Handler(void)
- {
- APM_DelayTickDec();
- }
编译烧录,查看效果
|