• CMT2380F32模块开发3-GPIO例程


    从今天开始就进入例程的讲解过程,今天讲解GPIO部分,对应《AN220-CMT2380F32用户指南(微控制器部分)-CN-V1.0-20200107.pdf》7 端口控制器(GPIO)章节。

    例程位置在\example\gpio文件夹中,有4个例程,下面一一进行讲解。

    gpio_output例程

    这个例程是输出例程,该例程功能是在按键1按下后,led灯进行闪烁。下面说一下主要代码。

    1. #define SK_SW1_INIT() Gpio_InitIOExt(0, 2, GpioDirIn, TRUE, FALSE, FALSE, TRUE)
    2. #define SK_SW1_GET() Gpio_GetIO(0, 2)

    这两个宏定义是对按键1的函数,INIT是将按键1,P02配置为输入,上拉模式。GET是获取P02的IO值。根据我的开发板电路,当按键按下时IO口被拉低,get值为0,当没被按下时,由于配置为上拉电阻,所以get值为非0。

    1. const stc_gpio_list_t gGpiolist[] = {
    2. {2, 3}, // red
    3. {1, 4}, // green
    4. {1, 5}, // blue
    5. };

    这个是LED的IO管脚配置,因为我们开发板有3个LED,所以这里数组为3个。

    1. SK_SW1_INIT();
    2. delay1ms(10);
    3. while (TRUE == SK_SW1_GET())
    4. ;
    5. //初始化外部GPIO
    6. for (i = 0; i < ARRAY_SZ(gGpiolist); i++) {
    7. Gpio_InitIOExt(gGpiolist[i].u8Port, gGpiolist[i].u8Pin, GpioDirOut, TRUE, FALSE, FALSE, FALSE);
    8. }
    9. //设置GPIO值(翻转)
    10. while (1) {
    11. for (i = 0; i < ARRAY_SZ(gGpiolist); i++) {
    12. Gpio_SetIO(gGpiolist[i].u8Port, gGpiolist[i].u8Pin, u8val);
    13. }
    14. u8val = !u8val;
    15. delay1ms(1000);
    16. }

    以上是main函数中的主要代码,首先初始化P02,然后通过get等待按键按下。

    按键按下后初始化LED为上拉输出。然后就进入while循环使用Gpio_SetIO进行IO 翻转。

    gpio_input例程

    1. //检测K1,如果有输入为低电平,则Led1_red输出3秒
    2. while (1) {
    3. for (i = 0; i < ARRAY_SZ(gGpiolist); i++)
    4. {
    5. u8val = Gpio_GetIO(gGpiolist[i].u8Port, gGpiolist[i].u8Pin);
    6. if (FALSE == u8val) {
    7. Gpio_SetIO(gLed1list[0].u8Port, gLed1list[0].u8Pin, TRUE);
    8. delay1ms(3000);
    9. Gpio_SetIO(gLed1list[0].u8Port, gLed1list[0].u8Pin, FALSE);
    10. }
    11. }
    12. }

    初始化流程和之前的大同小异,只是在while循环中进行了按键检测,有按键按下就把LED1点亮3秒。

    gpio_irq例程

    该例程是展示IO的中断功能。上电时led2,led3电量,按键1按下后led2会熄灭3秒,然后点亮。

    1. //将中断触发功能
    2. for (i = 0; i < ARRAY_SZ(gIrqList); i++) {
    3. Gpio_EnableIrq(gIrqList[i].u8Port, gIrqList[i].u8Pin, GpioIrqFalling);
    4. }
    5. //开启GPIO总中断
    6. EnableNvic(PORT0_IRQn, DDL_IRQ_LEVEL_DEFAULT, TRUE);
    7. while (1)
    8. ;

    主函数中将P02配置为下降沿触发,GpioIrqFalling。EnableNvic使能中断。

    1. void Gpio_IRQHandler(uint8_t u8Param)
    2. {
    3. SK_LED_SET(1);
    4. delay1ms(3000);
    5. SK_LED_SET(0);
    6. delay1ms(2000);
    7. *((uint32_t *)((uint32_t)&M0P_GPIO->P0ICLR + u8Param * 0x40)) = 0;
    8. }

    在中断函数中将led2关闭3秒后打开,整个中断占用5秒时间,整个只是示例,真正代码中要尽量减小中断中的时间。

    gpio_lpm例程

    该例程功能是通过配置IO 中断,将睡眠的模块唤醒。上电后,按下按键1,LED2,LED3点亮,然后LED2熄灭2秒,然后在过2秒后模块进入睡眠,这时如果再按下按键1,LED2会熄灭2秒,然后再亮起。下面看一下逻辑。

    1. //将中断触发功能
    2. for (i = 0; i < ARRAY_SZ(gIrqList); i++) {
    3. Gpio_EnableIrq(gIrqList[i].u8Port, gIrqList[i].u8Pin, GpioIrqFalling);
    4. }
    5. EnableNvic(PORT0_IRQn, DDL_IRQ_LEVEL_DEFAULT, TRUE);
    6. M0P_GPIO->CTRL0_f.IESEL = 1;
    7. Clk_SetFunc(ClkFuncWkupRCH, TRUE);
    8. SCB->SCR |= 0x4; // sleepdeep
    9. __NOP();
    10. __NOP();
    11. __NOP();
    12. __NOP();
    13. __NOP();
    14. while (1) {
    15. SK_LED_SET(1);
    16. delay1ms(2000);
    17. SK_LED_SET(0);
    18. delay1ms(2000);
    19. __WFI(); // goto LPM Mode
    20. }

    设置中断,然后点亮LED2,LED3。然后在while中先熄灭LED2两秒后在点亮,两秒后在进入睡眠,等待IO中断唤醒,继续进行while逻辑。

    这次的中断处理中只是清除了中断标志位。

    void Gpio_IRQHandler(uint8_t u8Param) { *((uint32_t *)((uint32_t)&M0P_GPIO->P0ICLR + u8Param * 0x40)) = 0; }

    这个函数初始化的等待按键1按下的逻辑是必须的,因为模块进入睡眠后就无法链接调试器进行下载了。

    1. // SW1 控制程序继续运行
    2. //注:此处如程序继续运行,因演示需要会将SWD及RESET配置为IO功能,如使用该Demo请勿删除如下两行代码。
    3. SK_SW1_INIT();
    4. NextStep();

    GPIO就是这些,也是比较简单的例程,没有太多东西,提供的库都有很详细的汉语注释,参数什么的都可以很容易的理解用途,对开发很友好。

  • 相关阅读:
    Power Apps-组件属性
    【毕业设计】基于php+mysql+apache的二手物品交易网站设计与实现(毕业论文+程序源码)——二手物品交易网站
    ROS 节点初始化步骤、topic/service创建及使用
    Shell
    Linux磁盘分区机制及虚拟机扩容案例
    定时器的使用和线程安全
    独立游戏开发的 6 个步骤
    XSS平台与cookie获取
    vue3 + quasar 弹窗的几种方式
    关于算法复杂度的几张表
  • 原文地址:https://blog.csdn.net/andylauren/article/details/126048262