上海航芯
直播中

朱工

8年用户 147经验值
擅长:可编程逻辑 模拟技术 嵌入式技术 处理器/DSP
私信 关注
[经验]

【上海航芯ACM32F403开发板首发试用】ACM32F403例程学习1——GPIO、EXTI例程

1.1. GPIO

GPIO例程对GPIO模块的output、interrupt、以及RTC域PC13的interrupt进行测试,代码解读如下:

1.1.1. GPIO_OUTPUT:

  1. 输出GPIO_OUTPUT信息。
  2. 设置PA0/PA1/PA2/PA3四个引脚的推挽输出、上拉、复用功能0。
  3. 将四个引脚设置为高电平、延时1ms,然后设置为低电平,再延时1ms,如此循环往复。

编译下载调试运行后,观察到串口输出如下(由于串口TX接到PA2,因此PA2输出的波形被误识别为字符 “␀” ):

../_images/GPIO_OUTPUT_print.png用示波器观察这几个引脚,可发现输出频率为493Hz的波形(采用的时钟是内部RCH,误差较大,而且设置引脚函数运行指令,也需要耗费一定的时间,因此偏离预期的1/2ms=500Hz):

../_images/GPIO_OUTPUT.jpg

1.1.2. GPIO_INT:

  • 此段代码应当有误,与后面一段的GPIO_PC的代码相同,重复测试此功能明显不对(ModulesDemo_V2.0.2, GPIO/demo/Source_Code/APP/APP.c)。
  • 注意到GPIOAB_IRQHandler函数中是清除PB9的中断标志位,因此推测此段代码应当为测试PB9的输入中断功能,修改代码如下:
  1. 设置PB9引脚为下降沿输入中断,电阻上拉、复用功能0。
  2. 清除GPIOAB_IRQn对应的NVIC中断标志位,并使能该中断。
  3. 在GPIOAB_IRQHandler中断服务例程中,设置中断状态变量 gu32_GPIOIRQ_Flag = true
  4. 在main函数主循环中,不停地检查该中断状态变量 gu32_GPIOIRQ_Flag ,一旦值为true,则重新设置其为false(防止再次进入该if判断语句,重复打印输出中断信息),随后打印输出中断信息;
  5. gu32_GPIOIRQ_Flag 为false之后,只有在PB9上的上升沿再次触发中断,才会进入中断服务例程将其再次设置为true,然后main函数检测到该值为true后才会再次执行前述操作。
caseGPIO_INT:
{
printfS("This is GPIO interrupt TEST. Please press user button to generate interrupt! \r\n");

GPIOB_Handle.Pin=GPIO_PIN_9;
GPIOB_Handle.Mode=GPIO_MODE_IT_FALLING;
GPIOB_Handle.Pull=GPIO_PULLUP;
GPIOB_Handle.Alternate=GPIO_FUNCTION_0;

HAL_GPIO_Init(GPIOB,&GPIOB_Handle);

/* Clear Pending Interrupt */
NVIC_ClearPendingIRQ(GPIOAB_IRQn);

/* Enable External Interrupt */
NVIC_EnableIRQ(GPIOAB_IRQn);

while(1)
{
if(gu32_GPIOIRQ_Flag)
{
gu32_GPIOIRQ_Flag=false;

printfS("Get interrupt flag!!! \r\n");
}
}
}break;

编译下载调试运行后,观察到串口输出如下(通过短接PB9和GND之后,可以触发中断,并在串口观察到相应的输出):

../_images/GPIO_INT.jpg ../_images/GPIO_INT_print.png

1.1.3. GPIO_PC13:

此段代码与前段代码功能接近,都是测试GPIO引脚的输入中断功能,区别点在于PC13/PC14/PC15位于RTC电源域,其设置与其他GPIO引脚稍有差异。具体如下:

  1. 设置PC13引脚为下降沿,复用功能0。
  2. 使能RTC域的读写。
  3. 设置PC13的GPIO功能,上拉,数字模式。
  4. 清除NVIC的GPIOCD_IRQn中断标志位,并使能该中断。
  5. 在main函数主循环中,不停地检查该中断状态变量 gu32_GPIOIRQ_Flag ,一旦值为true,则重新设置其为false(防止再次进入该if判断语句,重复打印输出中断信息),随后打印输出中断信息;
caseGPIO_PC13:
{
printfS("This is GPIO PC13 interrupt TEST \r\n");

GPIOC_Handle.Pin=GPIO_PIN_13;
GPIOC_Handle.Mode=GPIO_MODE_IT_FALLING;
GPIOC_Handle.Alternate=GPIO_FUNCTION_0;

HAL_GPIO_Init(GPIOC,&GPIOC_Handle);

/* RTC access enable */
System_Enable_Disable_RTC_Domain_Access(FUNC_ENABLE);

__HAL_RTC_PC13_SEL(0);// GPIO function
__HAL_RTC_PC13_PULL_UP_ENABLE();
__HAL_RTC_PC13_DIGIT();

/* Clear Pending Interrupt */
NVIC_ClearPendingIRQ(GPIOCD_IRQn);

/* Enable External Interrupt */
NVIC_EnableIRQ(GPIOCD_IRQn);

while(1)
{
if(gu32_GPIOIRQ_Flag)
{
gu32_GPIOIRQ_Flag=false;

printfS("Get PC13 interrupt flag!!! \r\n");
}
}
}break;

1.1.4. LED_BLINK:

  1. 设置PF3引脚为推挽输出、电阻上拉、复用功能0。
  2. 设置PF3为高电平,延时500ms,然后设置PF3为低电平,再延时500ms,如此循环往复。

执行后串口输出如图:

../_images/GPIO_LED_BLINK_print.png电路板上运行效果如下:

../_images/GPIO_LED_BLINK1.gif

1.2. EXTI:

1.2.1. EXTI_PB9

  1. 设置PB9引脚作为输入、电阻上拉、复用功能0。
  2. 设置EXTI为9号线,中断模式,下降沿,GPIOB。
  3. 最后在循环中进入stop模式;
void APP_EXTI_Test(void)
{
        printfS("This is EXTI Test \r\n");

        System_Delay_MS(3000);

        System_Module_Enable(EN_EXTI);

        /* Initialization GPIO */
        GPIO_PB9_Handle.Pin       = GPIO_PIN_9;
        GPIO_PB9_Handle.Mode      = GPIO_MODE_INPUT;
        GPIO_PB9_Handle.Pull      = GPIO_PULLUP;
        GPIO_PB9_Handle.Alternate = GPIO_FUNCTION_0;

        HAL_GPIO_Init(GPIOB, &GPIO_PB9_Handle);

        /* Config EXTI */
        EXTI_Line9_Handle.u32_Line    = EXTI_LINE_9;
        EXTI_Line9_Handle.u32_Mode    = EXTI_MODE_INTERRUPT;
        EXTI_Line9_Handle.u32_Trigger = EXTI_TRIGGER_FALLING;
        EXTI_Line9_Handle.u32_GPIOSel = EXTI_GPIOB;

        HAL_EXTI_SetConfigLine(&EXTI_Line9_Handle);

        while (1)
        {
                printfS("MCU Enter Lowpower, Press User Button To Wakeup MCU!\n");
                HAL_EXTI_ClearAllPending();
                System_Enter_Stop_Mode(STOPENTRY_WFI);

                printfS("MCU is Runing \r\n");
                System_Delay_MS(1000);
                printfS("MCU is Runing \r\n");
                System_Delay_MS(1000);
                printfS("MCU is Runing \r\n");
                System_Delay_MS(1000);

        }
}

执行效果如图(需要使用杜邦线触碰短接GND和PB9):

.. image:: image/EXTI_Test.png

1.2.2. EXTI_PC13:

由于板载的User-Button连接在PC13上,因此可以修改代码为使能EXTI的PC13引脚中断。注意PC13引脚由RTC电源域管理,需要额外设置,参考GPIO_PC13例程代码。

voidAPP_EXTI_Test(void)
{
printfS("This is EXTI Test \r\n");

System_Delay_MS(3000);

System_Module_Enable(EN_EXTI);

/* Initialization GPIO */
GPIO_PB9_Handle.Pin=GPIO_PIN_13;
GPIO_PB9_Handle.Mode=GPIO_MODE_INPUT;
GPIO_PB9_Handle.Pull=GPIO_PULLUP;
GPIO_PB9_Handle.Alternate=GPIO_FUNCTION_0;

HAL_GPIO_Init(GPIOC,&GPIO_PB9_Handle);



/* RTC access enable */
System_Enable_Disable_RTC_Domain_Access(FUNC_ENABLE);

__HAL_RTC_PC13_SEL(0);// GPIO function
__HAL_RTC_PC13_PULL_UP_ENABLE();
__HAL_RTC_PC13_DIGIT();


/* Config EXTI */
EXTI_Line9_Handle.u32_Line=EXTI_LINE_13;
EXTI_Line9_Handle.u32_Mode=EXTI_MODE_INTERRUPT;
EXTI_Line9_Handle.u32_Trigger=EXTI_TRIGGER_FALLING;
EXTI_Line9_Handle.u32_GPIOSel=EXTI_GPIOC;

HAL_EXTI_SetConfigLine(&EXTI_Line9_Handle);

此时按键即可触发EXTI中断

1.2.3. EXTI_EVENT:

同样可以尝试WFI和WFE的差别,将 System_Enter_Stop_Mode(STOPENTRY_WFI); 改为

System_Enter_Stop_Mode(STOPENTRY_WFE);

观察效果类似。

更多回帖

发帖
×
20
完善资料,
赚取积分