BC0004-CSR uEnergy例子讲解之PIO操作

uEnergy安装完毕后,会在安装目录下看到apps文件夹,里面有很多的例子,从这一节开始我将会挑选部分例子进行讲解,掌握这些例子后,会对CSR uEnergy的开发有一个大致的了解。

今天我们以示例代码中的PIO为例,讲解PIO的一些用法。

首先,打开SDK的安装目录,找到PIO文件夹:

打开后,双击pio.xiw打开:

打开后会有以下界面:

左侧为Workspace,我们点击C Files,打开main.c文件:

打开后,我们会看到main.c文件的内容,这里重点讲几个函数:

1.      AppPowerOnReset

2.      AppInit

3.      AppProcessSystemEvent

4.      AppProcessLmEvent

首先来讲解AppPowerOnReset函数,在pio的例子中,此函数为空:

其实多数的应用中,此函数都为空。看官方的解释,此函数只有在reset或者Hibernate or Dormant sleep状态醒来才会被调用,而我们多数的应用中,将此函数留空即可。

AppInit函数:

此函数比较重要,整个程序起来后会进入此函数,用户可以在此函数中添加一些初始化函数,此函数只被调用一次,且不能在此函数中添加死循环,否则系统会崩溃。

AppProcessSystemEvent函数:

此函数是系统事件的入口,系统事件有4种sys_event_wakeup、sys_event_battery_low、sys_event_pio_changed、sys_event_pio_ctrlr:

Sys_event_wakeup:芯片通过wakeup引脚起来会产生此事件;

Sys_event_battery_low:电池电量低会触发此事件;

Sys_event_pio_changed:io口状态改变会触发;

Sys_event_pio_ctrlr:pio controller产生的中断会引起此事件。

最后一个函数AppProcessLmEvent:

此函数在pio的例子中也是空,因为此函数处理了一些蓝牙事件,此例子只是对PIO口操作,没有涉及到蓝牙,所以,此函数也必然为空,关于蓝牙事件,会在以后的章节中说明。

看完这些,相信你会明白哪里才是我们看代码的切入点了吧,自然是AppInit函数,这里为了看起来方便,我将解释放在了代码中:

void AppInit(sleep_state last_sleep_state)

{

//首先这里初始化两个LED口

//设置PIO_LED0和PIO_LED1口为pio_mode_user

    PioSetModes((1UL << PIO_LED0) | (1UL << PIO_LED1), pio_mode_user);

    //设置PIO_LED0口为输出

    PioSetDir(PIO_LED0, PIO_DIR_OUTPUT);

     //设置PIO_LED1口为输出

    PioSetDir(PIO_LED1, PIO_DIR_OUTPUT);

    //设置PIO_LED0和LED1为强上拉

    PioSetPullModes((1UL << PIO_LED0) | (1UL << PIO_LED1),

                    pio_mode_strong_pull_up);

    //接下去设置了一个按钮

    //设置BUTTON为pio_mode_user

    PioSetMode(PIO_BUTTON, pio_mode_user);

    //设置BUTTON口为输入

    PioSetDir(PIO_BUTTON, PIO_DIR_INPUT);

    //设置BUTTON口为弱上拉

    PioSetPullModes((1UL << PIO_BUTTON), pio_mode_weak_pull_up);  

    //设置上升沿和下降沿都触发Sys_event_pio_changed事件

 PioSetEventMask((1UL << PIO_BUTTON), pio_event_mode_both);

    restartLedSeq();

}

PIO口的操作基本上是在appinit函数中设置PIO口的模式,普通IO口为pio_mode_user,然后设置PIO口为输入或者输出,然后配置上拉下拉或者浮空,如果为输入,还可以配置是否触发Sys_event_pio_changed事件。

在初始化函数的最后,调用restartLedSeq函数并结束整个初始化:

restartLedSeq函数内,我们看到一个PioSets函数,从注释很容易理解是将LED0和LED1设置为0,即关闭LED。

这里,就告诉我们设置IO口状态可以用PioSets函数,关于此函数的具体说明,可以查看API说明。

接下来我们看按键被按下后程序做了哪些处理:

void AppProcessSystemEvent(sys_event_id id, void *data)

{

    //这里为sys_ event_pio_changed事件的入口

    if (id == sys_event_pio_changed)

    {

        const pio_changed_data *pPioData = (const pio_changed_data *)data;

        //判断是不是按键导致sys_event_pio_changed事件

        if (pPioData->pio_cause & (1UL << PIO_BUTTON))

        {

            bool validStateChange = FALSE;

            //判断当前是否为高,如果是高,则表明刚刚发生的事件是由低到高,即上升沿触发,表示按键是被松开的

            if (pPioData->pio_state & (1UL << PIO_BUTTON))

            {

                g_cur_button_state = button_state_up;

            }

            //相反,如果不是高,则表明按键是被按下

            else

            {

                if (g_cur_button_state == button_state_up)

                {

                    validStateChange = TRUE;

                }

                g_cur_button_state = button_state_down;

            }

            //如果一个完整的按键发生,则切换LED闪烁状态

            if (validStateChange)

            {

                goToNextLedSeq();

            }

        }

    }

}

关于goToNextLedSeq()函数,其中也没有新的PIO口操作知识点,这里就不做过多的解释了,读者可以自己去研究一下每一个LED状态是怎么样的。

好了,关于PIO口操作的解释就说明到这里,另外IO口不仅仅只有输入输出两种功能,还有UART功能,IIC功能,SPI功能等等,会在后续章节中逐一讲解。

留下评论

邮箱地址不会被公开。 必填项已用*标注