dirty 发表于 2024-6-9 14:01

【全能小网关|CH32V208】--3.按键中断

<p>&nbsp; &nbsp; &nbsp; 本篇讲述按键IO外部中断。</p>

<p>&nbsp;</p>

<p><strong><span style="color:#0000ff;">一.按键原理与准备</span></strong></p>

<p>&nbsp; &nbsp; &nbsp; 由下原理图知用户按键下降沿低电平触发,我们这里用PA0作为按键检测IO口,并在杜邦线连接排针PA0与KEY引脚。</p>

<div style="text-align: center;"></div>

<div style="text-align: center;">图1:按键原理</div>

<p>&nbsp;</p>

<p><strong><span style="color:#0000ff;">二.代码准备</span></strong></p>

<p>1.初始化配置PA0外部中断,下降沿触发。</p>

<pre>
<code>void EXTI0_INT_INIT(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};
    EXTI_InitTypeDef EXTI_InitStructure = {0};
    NVIC_InitTypeDef NVIC_InitStructure = {0};

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &amp;GPIO_InitStructure);

    /* GPIOA ----&gt; EXTI_Line0 */
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
    EXTI_InitStructure.EXTI_Line = EXTI_Line0;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&amp;EXTI_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&amp;NVIC_InitStructure);
}</code></pre>

<p>2.中断函数。这里简单就打印下日志</p>

<pre>
<code>/*********************************************************************
* @fn      EXTI0_IRQHandler
*
* @brief This function handles EXTI0 Handler.
*
* @return none
*/
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0)!=RESET)
{
    printf("Run at EXTI\r\n");
    EXTI_ClearITPendingBit(EXTI_Line0);   /* Clear Flag */
}
}</code></pre>

<p>3.主函数</p>

<pre>
<code>int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    SystemCoreClockUpdate();
    Delay_Init();
    USART_Printf_Init(115200);
    printf("Uart Initr\n");
    printf("SystemClk:%d\r\n", SystemCoreClock);
    printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
    printf("EXTI0 Test\r\n");
    EXTI0_INT_INIT();
    printf("INT Init\n");

    while(1)
    {
      Delay_Ms(1000);
      //printf("Run at main\r\n");
    }
}</code></pre>

<p>&nbsp;</p>

<p><strong><span style="color:#0000ff;">三.测验</span></strong></p>

<p>&nbsp; &nbsp; &nbsp; 编译烧录,上电运行,查看日志有初始化,当按下用户按键S2,可以看到触发IO中断。</p>

<div style="text-align: center;"></div>

<div style="text-align: center;">图2:按键中断日志</div>

<p>&nbsp; &nbsp; &nbsp; 至此,实现按键IO外部中断功能。</p>

<p>&nbsp;</p>

lugl4313820 发表于 2024-6-10 18:58

<p>中断回调中打印日志,会不会拖慢中断的响应呢?</p>

dirty 发表于 2024-6-12 09:16

lugl4313820 发表于 2024-6-10 18:58
中断回调中打印日志,会不会拖慢中断的响应呢?

<p>这个还好的,不放心在中断里可以把打印放在清标志之后。中断里不宜放阻塞比较久的应用程需,也可置标志main函数处理。</p>

lugl4313820 发表于 2024-6-12 14:25

dirty 发表于 2024-6-12 09:16
这个还好的,不放心在中断里可以把打印放在清标志之后。中断里不宜放阻塞比较久的应用程需,也可置标志ma ...

<p>这要看你printf重定向的是不是阻塞输出,如果是阻塞的,或者外设有问题了,那就影响整个程序了。</p>
页: [1]
查看完整版本: 【全能小网关|CH32V208】--3.按键中断