eew_Violet 发表于 2021-5-19 01:06

【雅特力 AT32F421评测】EXTI中断使用

<p><span style="font-size:24px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;上回使用了I2C读取CH450按键码,<a href="https://bbs.eeworld.com.cn/thread-1165877-1-1.html">传送门</a>&nbsp; 事实上CH450有提供了一个中断线的,发生有效按键时候会有个低电平脉冲,通知控制器我这有货了。来取下,这样控制器就不需要去轮询是否有有效按键码了。</span><span style="font-size:24px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我把它接到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);         ///&lt;Enable GPIOB clock
        GPIO_StructInit(&amp;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, &amp;GPIO_InitStructure);                        ///&lt;Configure PB6 pin as input
       
        RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_SYSCFGCOMP, ENABLE);    ///&lt;Enable SYSCFG clock
        SYSCFG_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinsSource6);///&lt;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(&amp;EXTI_InitStructure);                               ///&lt;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(&amp;NVIC_InitStructure);///&lt;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);///&lt;Clear theEXTI line 6 pending bit
        }
}</code></pre>

<p><span style="font-size:24px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;main中新建个KEY线程去处理按键。</span></p>

<pre>
<code>                /* 创建按键服务线程 */
    rt_thread_init(&amp;KEY_thread,
                                   "KEY",
                   KEY_thread_entry,
                   RT_NULL,
                                   &amp;KEY_stack,                        
                   sizeof(KEY_stack),
                   5,
                   5);
   /* 启动线程,开启调度 */       
   rt_thread_startup(&amp;KEY_thread);</code></pre>

<p><span style="font-size:24px;">&nbsp; &nbsp; &nbsp; &nbsp; 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>&nbsp;</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>&nbsp;</p>

Jacktang 发表于 2021-5-19 08:46

<p>控制器不轮询查是否有效,用中断处理函数,应该比较常用</p>

<p>中断函数中标志位CH450_Flag,这个怎么讲</p>

eew_Violet 发表于 2021-5-19 12:40

Jacktang 发表于 2021-5-19 08:46
控制器不轮询查是否有效,用中断处理函数,应该比较常用

中断函数中标志位CH450_Flag,这个怎么讲

<p>就是一个u8的变量,和裸机一样,中断中置1,while中去处理,昨天太晚了。就先凑合用了</p>
页: [1]
查看完整版本: 【雅特力 AT32F421评测】EXTI中断使用