[Yatli AT32F421 Review] EXTI interrupt usage
[Copy link]
Last time I used I2C to read the CH450 key code. In fact , CH450 provides an interrupt line. When a valid key is pressed, there will be a low-level pulse to notify the controller that I have the product. I will remove it, so that the controller does not need to poll for valid key codes.
I connected it to PB6, and the relevant configuration code is as follows:
/**
* [url=home.php?mod=space&uid=159083]@brief[/url] EXTI9_5 Config.Configure PB6 in interrupt mode
* @param None
* @retval None
*/
void EXTI9_5_Config(void)
{
EXTI_InitType EXTI_InitStructure;
GPIO_InitType GPIO_InitStructure;
NVIC_InitType NVIC_InitStructure = {0};
RCC_AHBPeriphClockCmd(RCC_AHBPERIPH_GPIOB, ENABLE); ///<Enable GPIOB clock
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pins = GPIO_Pins_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Pull = GPIO_Pull_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure); ///<Configure PB6 pin as input
RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_SYSCFGCOMP, ENABLE); ///<Enable SYSCFG clock
SYSCFG_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinsSource6);///<Connect EXTI6 Line to PB6pin
EXTI_InitStructure.EXTI_Line = EXTI_Line6;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_InitStructure.EXTI_LineEnable = ENABLE;
EXTI_Init(&EXTI_InitStructure); ///<Configure EXTI6 line
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);///<Enable and set EXTI9_5 Interrupt to the lowest priority
}
The CH450 INT pin is already pulled up internally, so there is no need to pull it up for F421. Add EXTI9_5_Config(); to rt_hw_board_init(). Write the interrupt handling function in it.c. Here I set the flag CH450_Flag, and leave the specific processing to the thread.
/**
* @brief This function handles External lines 9 to 5 interrupt request.
* @param None
* @retval None
*/
void EXTI15_4_IRQHandler(void)
{
if(EXTI_GetIntStatus(EXTI_Line6) != RESET)
{
CH450_Flag = 1;
EXTI_ClearIntPendingBit(EXTI_Line6);///<Clear the EXTI line 6 pending bit
}
}
Create a new KEY thread in main to process key presses.
/* 创建按键服务线程 */
rt_thread_init(&KEY_thread,
"KEY",
KEY_thread_entry,
RT_NULL,
&KEY_stack[0],
sizeof(KEY_stack),
5,
5);
/* 启动线程,开启调度 */
rt_thread_startup(&KEY_thread);
KEY thread entry function
static void KEY_thread_entry(void *parameter)
{
while(1)
{
if(CH450_Flag == 1)
rt_kprintf("KEY_Val:%d\r\n",(CH450_Read()-0x40));
CH450_Flag = 0; //标志位清除
rt_thread_yield(); // 让出cpu
}
}
Look at the result. I2C-Status is used to print whether there is any error in the IIC communication result. The following are the key code values of K1~K8.
The CH450 manual says that the key value read is the value in the key value table plus 0x40.
The value printed by the serial port is in decimal. Convert it here to see if the key value is correct. My keyboard is connected to DIG2 and SEG0~SEG7. Converting 2, 10, 18, 26, 34, 42, 50, 58 to hexadecimal is indeed 02, 0A, 12, 1A, 22, 2A, 32, 3A. The result is correct.
|