众所周知,偌大的合泰开发板上只有一个复位键;要想拥有其他的按键就必须外扩。
一、硬件电路
只做出了一个测试电路,比较简陋😂
二、软件实现
一种方法是直接读取GPIO口的电平,但这种方法有一个弊端就是响应不及时,在执行其他时就完全响应不了,只能等空闲状态不断地在那里检测才能响应。
因此,我采用的是外部中断的方法,只要设置好中断就OK了,比较简单。
1、外部中断初始化及中断服务函数
void Key_Init(void)
{
EXTI_InitTypeDef EXTI_InitStruct;
CKCU_PeripClockConfig_TypeDef CKCUClock= {{0}};
CKCUClock.Bit.PB = 1; //开启GPIOB时钟
CKCUClock.Bit.AFIO = 1;
CKCUClock.Bit.EXTI = 1; //开启中断时钟
CKCU_PeripClockConfig(CKCUClock, ENABLE);
GPIO_InputConfig(HT_GPIOB, GPIO_PIN_4, ENABLE);
GPIO_PullResistorConfig(HT_GPIOB, GPIO_PIN_4, GPIO_PR_DOWN);
AFIO_GPxConfig( GPIO_PB, AFIO_PIN_4, AFIO_FUN_GPIO);
AFIO_EXTISourceConfig(AFIO_EXTI_CH_4, AFIO_ESS_PB);//中断来源选择PB3
EXTI_InitStruct.EXTI_Channel=EXTI_CHANNEL_4;
EXTI_InitStruct.EXTI_Debounce=EXTI_DEBOUNCE_ENABLE;//决定是否去抖
EXTI_InitStruct.EXTI_DebounceCnt = 65535;
EXTI_InitStruct.EXTI_IntType=EXTI_POSITIVE_EDGE; //上升沿触发
EXTI_Init(&EXTI_InitStruct);
NVIC_EnableIRQ(EXTI4_15_IRQn);//
EXTI_IntConfig(EXTI_CHANNEL_4, ENABLE);//检测中断源状态函数
}
void EXTI4_15_IRQHandler(void)
{
UsartPrintf(HT_USART0, "inter_ok\r\n");
led_on(LED1_GPIO_PIN);
EXTI_ClearEdgeFlag(EXTI_CHANNEL_4);
}
2、main函数
int main(void)
{
USART0_Configuration();
UsartPrintf(HT_USART0, "in_ok\r\n");
Key_Init();
Key2_Init();
LED_Init();
led_off(LED1_GPIO_PIN);
UsartPrintf(HT_USART0, "main_ok\r\n");
}
三、中断那些事
(1)由于ht32f5xxxx_01.h文件不可被修改(stm32该文件可以修改因此不够的时候可以自己加),因此最多只能同时设置三个外部中断
(2)如果想使用PB2作为外部中断的IO口的话,通道需设置为EXTI_CHANNEL_2,中断也只能使用EXTI2_3_IRQn
(3)如果按键的一端接的是VCC,那么就要采用上升沿触发,则设置EXTI_InitStruct.EXTI_IntType=EXTI_POSITIVE_EDGE;
同时,GPIO_PullResistorConfig(HT_GPIOB, GPIO_PIN_4, GPIO_PR_DOWN);
而如果按键的一端接的是GND,那么就要采用下降沿触发,则设置EXTI_InitStruct.EXTI_IntType=EXTI_NEGATIVE_EDGE;
同时,GPIO_PullResistorConfig(HT_GPIOB, GPIO_PIN_4, GPIO_PR_UP);
🐬附上整个程序文件:HT32.Key_3
(该程序实现的功能是按下key1或key2,led1会亮起并串口打印相应的文本)