【雅特力 AT32F421评测】EXTI中断使用
<p><span style="font-size:24px;"> 上回使用了I2C读取CH450按键码,<a href="https://bbs.eeworld.com.cn/thread-1165877-1-1.html">传送门</a> 事实上CH450有提供了一个中断线的,发生有效按键时候会有个低电平脉冲,通知控制器我这有货了。来取下,这样控制器就不需要去轮询是否有有效按键码了。</span><span style="font-size:24px;"> 我把它接到PB6上,相关配置代码如下:</span></p><pre>
<code>/**
* @brief EXTI9_5 Config.Configure PB6 in interrupt mode
* @paramNone
* @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
}</code></pre>
<p><span style="font-size:24px;">CH450 INT脚在内部已经进行了上拉,所以F421这里就不用拉了。把EXTI9_5_Config();加入到rt_hw_board_init()中。it.c中编写中断处理函数,这里我置了标志位CH450_Flag ,具体的处理留给线程去做。</span></p>
<pre>
<code>/**
* @briefThis function handles External lines 9 to 5 interrupt request.
* @paramNone
* @retval None
*/
void EXTI15_4_IRQHandler(void)
{
if(EXTI_GetIntStatus(EXTI_Line6) != RESET)
{
CH450_Flag = 1;
EXTI_ClearIntPendingBit(EXTI_Line6);///<Clear theEXTI line 6 pending bit
}
}</code></pre>
<p><span style="font-size:24px;"> main中新建个KEY线程去处理按键。</span></p>
<pre>
<code> /* 创建按键服务线程 */
rt_thread_init(&KEY_thread,
"KEY",
KEY_thread_entry,
RT_NULL,
&KEY_stack,
sizeof(KEY_stack),
5,
5);
/* 启动线程,开启调度 */
rt_thread_startup(&KEY_thread);</code></pre>
<p><span style="font-size:24px;"> KEY线程入口函数</span></p>
<pre>
<code>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
}
}
</code></pre>
<p> </p>
<p><span style="font-size:24px;">看下结果,I2C-Status是用来打印IIC通讯结果是否有错误的。以下依次为K1~K8的键码值。</span></p>
<p><span style="font-size:24px;">CH450的手册有说读到的键值是键值表中的值加0x40的值。</span></p>
<p><span style="font-size:24px;">串口打印的值是十进制的,这里转换下看读到的键值对不对,键盘我是接在DIG2和SEG0~SEG7上,将2,10,18,26,34,42,50,58转换为十六进制的确是02,0A,12,1A,22,2A,32,3A.结果是正确的。</span></p>
<p> </p>
<p>控制器不轮询查是否有效,用中断处理函数,应该比较常用</p>
<p>中断函数中标志位CH450_Flag,这个怎么讲</p>
Jacktang 发表于 2021-5-19 08:46
控制器不轮询查是否有效,用中断处理函数,应该比较常用
中断函数中标志位CH450_Flag,这个怎么讲
<p>就是一个u8的变量,和裸机一样,中断中置1,while中去处理,昨天太晚了。就先凑合用了</p>
页:
[1]