当前位置:网站首页>CMT2380F32模块开发3-GPIO例程

CMT2380F32模块开发3-GPIO例程

2022-08-11 05:24:00 andylauren

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

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

gpio_output例程

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

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

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

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

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

    SK_SW1_INIT();
    delay1ms(10);
    while (TRUE == SK_SW1_GET())
        ;

    //初始化外部GPIO
    for (i = 0; i < ARRAY_SZ(gGpiolist); i++) {
        Gpio_InitIOExt(gGpiolist[i].u8Port, gGpiolist[i].u8Pin, GpioDirOut, TRUE, FALSE, FALSE, FALSE);
    }

    //设置GPIO值(翻转)
    while (1) {
        for (i = 0; i < ARRAY_SZ(gGpiolist); i++) {
            Gpio_SetIO(gGpiolist[i].u8Port, gGpiolist[i].u8Pin, u8val);
        }

        u8val = !u8val;
        delay1ms(1000);
    }

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

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

gpio_input例程

    //检测K1,如果有输入为低电平,则Led1_red输出3秒
    while (1) {
        for (i = 0; i < ARRAY_SZ(gGpiolist); i++)

        {
            u8val = Gpio_GetIO(gGpiolist[i].u8Port, gGpiolist[i].u8Pin);

            if (FALSE == u8val) {
                Gpio_SetIO(gLed1list[0].u8Port, gLed1list[0].u8Pin, TRUE);
                delay1ms(3000);
                Gpio_SetIO(gLed1list[0].u8Port, gLed1list[0].u8Pin, FALSE);
            }
        }
    }

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

gpio_irq例程

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

    //将中断触发功能
    for (i = 0; i < ARRAY_SZ(gIrqList); i++) {
        Gpio_EnableIrq(gIrqList[i].u8Port, gIrqList[i].u8Pin, GpioIrqFalling);
    }

    //开启GPIO总中断
    EnableNvic(PORT0_IRQn, DDL_IRQ_LEVEL_DEFAULT, TRUE);

    while (1)
        ;

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

void Gpio_IRQHandler(uint8_t u8Param)
{
    SK_LED_SET(1);
    delay1ms(3000);
    SK_LED_SET(0);
    delay1ms(2000);

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

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

gpio_lpm例程

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

    //将中断触发功能
    for (i = 0; i < ARRAY_SZ(gIrqList); i++) {
        Gpio_EnableIrq(gIrqList[i].u8Port, gIrqList[i].u8Pin, GpioIrqFalling);
    }

    EnableNvic(PORT0_IRQn, DDL_IRQ_LEVEL_DEFAULT, TRUE);

    M0P_GPIO->CTRL0_f.IESEL = 1;

    Clk_SetFunc(ClkFuncWkupRCH, TRUE);
    SCB->SCR |= 0x4;  // sleepdeep
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();

    while (1) {
        SK_LED_SET(1);
        delay1ms(2000);
        SK_LED_SET(0);
        delay1ms(2000);
        __WFI();  // goto LPM Mode
    }

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

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

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

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

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

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

原网站

版权声明
本文为[andylauren]所创,转载请带上原文链接,感谢
https://blog.csdn.net/andylauren/article/details/126048262