[DemoCode下载] GPIO的控制方式

[复制链接]
 楼主| 发表于 2024-2-19 22:42 | 显示全部楼层 |阅读模式
  1. /**************************************************************************//**
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     main.c
  3. * [url=home.php?mod=space&uid=895143]@version[/url]  V3.00
  4. * [url=home.php?mod=space&uid=247401]@brief[/url]    GPIO function for level1 training course
  5. *
  6. *
  7. * SPDX-License-Identifier: Apache-2.0
  8. * [url=home.php?mod=space&uid=17282]@CopyRight[/url] (C) 2018 Nuvoton Technology Corp. All rights reserved.
  9. *
  10. ******************************************************************************/

  11. #include <stdio.h>
  12. #include "NuMicro.h"

  13. #define LED_R   PC4
  14. #define LED_G   PC5
  15. #define LED_B   PC3

  16. #define LED_ON      0
  17. #define LED_OFF     1

  18. volatile uint32_t sw1_int_cnt = 0;
  19. volatile uint32_t sw2_int_cnt = 0;

  20. void SYS_Init(void)
  21. {
  22.     /* Enable HXT clock (external XTAL 12MHz) */
  23.     CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);

  24.     /* Wait for HXT clock ready */
  25.     CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);

  26.     /* Enable LIRC clock */
  27.     CLK_EnableXtalRC(CLK_PWRCTL_LIRCEN_Msk);

  28.     /* Wait for LIRC clock ready */
  29.     CLK_WaitClockReady(CLK_STATUS_LIRCSTB_Msk);

  30.     /* Set core clock as PLL_CLOCK from PLL */
  31.     CLK_SetCoreClock(FREQ_48MHZ);

  32.     /* Set PCLK0/PCLK1 to HCLK/2 */
  33.     CLK->PCLKDIV = (CLK_PCLKDIV_APB0DIV_DIV2 | CLK_PCLKDIV_APB1DIV_DIV2);

  34.     /* Enable module clock */
  35.     CLK_EnableModuleClock(UART0_MODULE);

  36.     /* Set module clock */
  37.     CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HXT, CLK_CLKDIV0_UART0(1));
  38. }

  39. void UART0_Init()
  40. {
  41.     /* Set GPB multi-function pins to UART0 RXD and TXD */
  42.     SYS->GPB_MFPH = (SYS->GPB_MFPH & ~(SYS_GPB_MFPH_PB12MFP_Msk | SYS_GPB_MFPH_PB13MFP_Msk)) |
  43.                     (SYS_GPB_MFPH_PB12MFP_UART0_RXD | SYS_GPB_MFPH_PB13MFP_UART0_TXD);

  44.     /* Configure UART0 and set UART0 baud rate */
  45.     UART_Open(UART0, 115200);
  46. }

  47. void LED_Init(void)
  48. {
  49.     /* Set PC.3 ~ PC.5 to GPIO */
  50.     SYS->GPC_MFPL = (SYS->GPC_MFPL & ~(SYS_GPC_MFPL_PC3MFP_Msk | SYS_GPC_MFPL_PC4MFP_Msk | SYS_GPC_MFPL_PC5MFP_Msk)) |
  51.                     (SYS_GPC_MFPL_PC3MFP_GPIO | SYS_GPC_MFPL_PC4MFP_GPIO | SYS_GPC_MFPL_PC5MFP_GPIO);

  52.     /* Set PC.3 ~ PC.5 to GPIO output */
  53.     GPIO_SetMode(PC, (BIT3 | BIT4 | BIT5), GPIO_MODE_OUTPUT);

  54.     /* Let LED off after initialize */
  55.     LED_R = LED_OFF;
  56.     LED_G = LED_OFF;
  57.     LED_B = LED_OFF;
  58. }

  59. void BTN_Init(void)
  60. {

  61.     /**************  SW1 ***************/
  62.     /* Set PB.4 to GPIO */
  63.     SYS->GPB_MFPL = (SYS->GPB_MFPL & ~(SYS_GPB_MFPL_PB4MFP_Msk)) | (SYS_GPB_MFPL_PB4MFP_GPIO);
  64.     /* Set PB.4 to GPIO intput */
  65.     GPIO_SetMode(PB, BIT4, GPIO_MODE_INPUT);
  66.     GPIO_EnableInt(PB, 4, GPIO_INT_FALLING);
  67.     NVIC_EnableIRQ(GPIO_PAPB_IRQn);

  68.     /**************  SW2 ***************/
  69.     /* Set PB.0 to GPIO */
  70.     SYS->GPB_MFPL = (SYS->GPB_MFPL & ~(SYS_GPB_MFPL_PB0MFP_Msk)) | (SYS_GPB_MFPL_PB0MFP_GPIO);
  71.     /* Set PB.0 to GPIO intput */
  72.     GPIO_SetMode(PB, BIT0, GPIO_MODE_INPUT);
  73.     GPIO_EnableInt(PB, 0, GPIO_INT_FALLING);

  74.     /* Set de-bounce function */
  75.     GPIO_SET_DEBOUNCE_TIME(GPIO_DBCTL_DBCLKSRC_LIRC, GPIO_DBCTL_DBCLKSEL_512);
  76.     GPIO_ENABLE_DEBOUNCE(PB, BIT4);
  77. }

  78. int main(void)
  79. {
  80.     uint32_t sw1_cnt = 0, sw2_cnt = 0;

  81.     /* Unlock protected registers */
  82.     SYS_UnlockReg();

  83.     /* Init System, peripheral clock and multi-function I/O */
  84.     SYS_Init();

  85.     /* Lock protected registers */
  86.     SYS_LockReg();

  87.     /* Init UART0 for printf */
  88.     UART0_Init();

  89.     printf("+---------------------------------------+\n");
  90.     printf("|    Level1 GPIO control Sample Code    |\n");
  91.     printf("+---------------------------------------+\n\n");

  92.     /* Init LED */
  93.     LED_Init();

  94.     /* Init BTN */
  95.     BTN_Init();

  96.     while(1)
  97.     {
  98.         /* Check if the SW1 is pressed */
  99.         if (sw1_int_cnt != sw1_cnt)
  100.         {
  101.             sw1_cnt = sw1_int_cnt;
  102.             printf("SW1 interrupt count: %d\n", sw1_cnt);
  103.         }
  104.         /* Check if the SW2 is pressed */
  105.         if (sw2_int_cnt != sw2_cnt)
  106.         {
  107.             sw2_cnt = sw2_int_cnt;
  108.             printf("SW2 interrupt count: %d\n", sw2_cnt);
  109.         }
  110.     }
  111. }

  112. void GPABGH_IRQHandler(void)
  113. {
  114.     /* Check if PB.4 the interrupt occurred */
  115.     if(GPIO_GET_INT_FLAG(PB, BIT4))
  116.     {
  117.         LED_R ^= 1;
  118.         sw1_int_cnt++;
  119.         /* Clear PB.4 interrupt flag */
  120.         GPIO_CLR_INT_FLAG(PB, BIT4);
  121.         /* Check if PB.0 the interrupt occurred */
  122.     }
  123.     else if(GPIO_GET_INT_FLAG(PB, BIT0))
  124.     {
  125.         LED_G ^= 1;
  126.         sw2_int_cnt++;
  127.         /* Clear PB.0 interrupt flag */
  128.         GPIO_CLR_INT_FLAG(PB, BIT0);
  129.     }
  130.     else
  131.     {
  132.         /* Un-expected interrupt. Just clear all PB interrupts */
  133.         PB->INTSRC = PB->INTSRC;
  134.         printf("Un-expected interrupts.\n");
  135.     }
  136. }

  137. /*** (C) COPYRIGHT 2019 Nuvoton Technology Corp. ***/


 楼主| 发表于 2024-2-19 22:43 | 显示全部楼层
这段代码实现了一个简单的GPIO控制示例,包括LED的初始化和控制,以及两个按钮(SW1和SW2)的初始化和中断处理。

首先,在 SYS_Init 函数中进行了系统时钟的初始化设置,包括启用外部晶振(HXT,12MHz)和低速内部晶振(LIRC),设置核心时钟为48MHz,配置PCLK0和PCLK1为HCLK的一半,并且启用了UART0模块的时钟,并将UART0的时钟源选择为HXT。

UART0_Init 函数初始化了UART0模块,将GPB的引脚配置为UART0的RX和TX功能,并设置UART0的波特率为115200。

LED_Init 函数初始化了LED的控制引脚(PC3、PC4、PC5),将它们配置为GPIO输出,并将LED默认状态设置为关闭。

BTN_Init 函数初始化了两个按钮(SW1和SW2)的控制引脚(PB4和PB0),将它们配置为GPIO输入,并启用了下降沿触发的中断。此外,还配置了GPIO的去抖动功能。

在 main 函数中,通过调用 SYS_Init、UART0_Init、LED_Init 和 BTN_Init 进行系统初始化,然后进入了一个无限循环,在循环中不断检查两个按钮的中断计数是否有变化,如果有变化,则打印出对应的中断计数值。

GPABGH_IRQHandler 函数是GPIO的中断处理函数,当按钮的中断触发时,会进入这个函数进行处理。在这个函数中,首先判断中断是由哪个引脚(PB4或PB0)触发的,然后根据情况反转对应的LED,并增加对应的中断计数值,并清除中断标志位。

总体来说,这段代码实现了一个简单的GPIO控制示例,通过按钮来控制LED,并通过中断方式来处理按钮的按下事件,同时通过UART0输出按钮按下的次数。
 楼主| 发表于 2024-2-19 22:43 | 显示全部楼层
你这么处理过按键吗?》
发表于 2024-2-27 21:31 | 显示全部楼层
轮巡和中断都可以用的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

183

主题

2309

帖子

3

粉丝
快速回复 返回顶部 返回列表