> 文档中心 > 小熊派鸿蒙开发

小熊派鸿蒙开发


上机实验三:鸿蒙内核程序开发

一、GPIO介绍&演练场景 路灯控制 1.1

1. GPIO API介绍

wifiiot_gpio.h接口简介:包含声明GPIO接口函数,用于初始化GPIO。

接口名 功能描述
GpioInit 初始化GPIO
GpioDeinit 取消初始化GPIO
GpioSetDir 设置GPIO引脚方向
GpioGetDir 获取GPIO引脚方向
GpioSetOutputVal 设置GPIO引脚输出电平值
GpioGetOutputVal 获取GPIO引脚输出电平值

2.视频拓展实验源码

#include #include #include "ohos_init.h"#include "cmsis_os2.h"#include "wifiiot_gpio.h"#include "wifiiot_gpio_ex.h"​static void LedTask(void){    //初始化GPIO    GpioInit();​    //设置GPIO_2的复用功能为普通GPIO    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_IO_FUNC_GPIO_2_GPIO);​    //设置GPIO_2为输出模式    GpioSetDir(WIFI_IOT_GPIO_IDX_2, WIFI_IOT_GPIO_DIR_OUT);        //获取输出方向    WifiIotGpioDir val = {0};    GpioGetDir(WIFI_IOT_GPIO_IDX_2,&val);    printf("GPIO_2 Dir is %d\r\n",val);​    WifiIotGpioValue OutputVal = {0};//记录电平​    while (1)    {        //设置GPIO_2输出高电平点亮LED灯        GpioSetOutputVal(WIFI_IOT_GPIO_IDX_2, 1);                GpioGetOutputVal(WIFI_IOT_GPIO_IDX_2,&OutputVal);        printf("GPIO_2 OutputVal is %d\n",OutputVal);​        //延时1s        usleep(1000000);​        //设置GPIO_2输出低电平熄灭LED灯        GpioSetOutputVal(WIFI_IOT_GPIO_IDX_2, 0);​        GpioGetOutputVal(WIFI_IOT_GPIO_IDX_2,&OutputVal);        printf("GPIO_2 OutputVal is %d\n",OutputVal);​        //延时1s        usleep(1000000);    }}​static void LedExampleEntry(void){    osThreadAttr_t attr;​    attr.name = "LedTask";    attr.attr_bits = 0U;    attr.cb_mem = NULL;    attr.cb_size = 0U;    attr.stack_mem = NULL;    attr.stack_size = 1024 * 4;    attr.priority = 25;​    if (osThreadNew((osThreadFunc_t)LedTask, NULL, &attr) == NULL)    {        printf("Falied to create LedTask!\n");    }}​APP_FEATURE_INIT(LedExampleEntry);

3.实验现象及结果分析

开发板的GPIO2控制的灯每隔一秒亮一次,COM3控制台输出LED灯的电平情况(1亮0灭),一直重复循环。

控制LED灯亮步骤

  1. 初始化对应GPIO

    GpioInit();

  2. 设置GPIO的复用功能

    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_IO_FUNC_GPIO_2_GPIO);

  3. 设置GPIO的输出模式

    GpioSetDir(WIFI_IOT_GPIO_IDX_2, WIFI_IOT_GPIO_DIR_OUT);

  4. 设置点亮LED灯

    GpioSetOutputVal(WIFI_IOT_GPIO_IDX_2, 1);

  5. 设置熄灭LED灯

    GpioSetOutputVal(WIFI_IOT_GPIO_IDX_2, 0);

获取部分中间量的方法

  • 获取输出方向(1输出0输入)

WifiIotGpioDir val = {0}; ​ GpioGetDir(WIFI_IOT_GPIO_IDX_2,&val);

  • 获取电平信号(1亮0灭)

WifiIotGpioValue OutputVal = {0};

GpioGetOutputVal(WIFI_IOT_GPIO_IDX_2,&OutputVal);

3.实验小坑 ^V^

视频中有一个坑是没有提到的,如下:

attr.stack_size = 512;//  =>attr.stack_size = 1024 * 4;

源码中的栈大小512,是不够的需要修改大一些,建议1024 * 4。

如果不修改的话是无法正常运行的,会查看日志后会发现以下报错:

keywords: stack overflow!

二、GPIO中断&演练场景 路灯控制 1.2

1.GPIO中断 API介绍

wifiiot_gpio.h接口简介:包含声明GPIO中断函数。

接口名 功能描述
GpioRegisterisrFunc 设置GPIO引脚中断功能
GpioUnregisterIsrFunc 取消GPIO引脚中断功能
GpioSetIsrMask 屏蔽GPIO引脚中断功能
GpioSetIsrMode 设置GPIO引脚中断触发模式

2.视频扩展实验源码

#include #include ​#include "ohos_init.h"#include "cmsis_os2.h"#include "wifiiot_gpio.h"#include "wifiiot_gpio_ex.h"​static void F1_Pressed(char *arg){    (void)arg;    GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, 1);    printf("F1 button pressed\r\n");    GpioSetIsrMode(WIFI_IOT_GPIO_IDX_11,WIFI_IOT_INT_TYPE_EDGE,WIFI_IOT_GPIO_EDGE_RISE_LEVEL_HIGH);}static void F2_Pressed(char *arg){    (void)arg;    GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, 0);    printf("F2 button pressed\r\n");    GpioSetIsrMask(WIFI_IOT_IO_NAME_GPIO_12,1);}static void ButtonExampleEntry(void){    GpioInit();​    //初始化LED灯    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_IO_FUNC_GPIO_2_GPIO);​    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_GPIO_DIR_OUT);​    //初始化F1按键,设置为下降沿触发中断    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_11, WIFI_IOT_IO_FUNC_GPIO_11_GPIO);​    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_11, WIFI_IOT_GPIO_DIR_IN);    IoSetPull(WIFI_IOT_IO_NAME_GPIO_11, WIFI_IOT_IO_PULL_UP);//默认引脚上拉,高电平,灯亮    GpioRegisterIsrFunc(WIFI_IOT_IO_NAME_GPIO_11, WIFI_IOT_INT_TYPE_EDGE, WIFI_IOT_GPIO_EDGE_FALL_LEVEL_LOW, F1_Pressed, NULL);//边缘触发,下降沿触发​    //初始化F2按键,设置为下降沿触发中断    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_12, WIFI_IOT_IO_FUNC_GPIO_12_GPIO);​    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_12, WIFI_IOT_GPIO_DIR_IN);    IoSetPull(WIFI_IOT_IO_NAME_GPIO_12, WIFI_IOT_IO_PULL_UP);    GpioRegisterIsrFunc(WIFI_IOT_IO_NAME_GPIO_12, WIFI_IOT_INT_TYPE_EDGE, WIFI_IOT_GPIO_EDGE_FALL_LEVEL_LOW, F2_Pressed, NULL);}​APP_FEATURE_INIT(ButtonExampleEntry);

3.实验现象及结果分析

单独按键F1时上升沿灯亮,单独按F2键下降沿灯灭,第二次按键F2时不再有反应。

核心代码

  1. 设置LED灯上升沿亮

    IoSetPull(WIFI_IOT_IO_NAME_GPIO_11, WIFI_IOT_IO_PULL_UP);//默认引脚上拉,高电平,灯亮 GpioRegisterIsrFunc(WIFI_IOT_IO_NAME_GPIO_11, WIFI_IOT_INT_TYPE_EDGE, WIFI_IOT_GPIO_EDGE_FALL_LEVEL_LOW, F1_Pressed, NULL);//边缘触发,下降沿触发

  2. 按F2键下降沿灯灭

    GpioRegisterIsrFunc(WIFI_IOT_IO_NAME_GPIO_12, WIFI_IOT_INT_TYPE_EDGE, WIFI_IOT_GPIO_EDGE_FALL_LEVEL_LOW, F2_Pressed, NULL);

  3. 第二次按键F2时不再有反应

GpioSetIsrMask(WIFI_IOT_IO_NAME_GPIO_12,1);//执行一次后一直阻塞

本实验较简单,整个过程很流畅。

三、PWM介绍&演练场景 2:呼吸灯

1.PWM API介绍

wifiiot_pwm.h接口简介:包含声明PWM接口函数。

接口名 功能描述
PwmInit 初始化PWM
PwmDeinit 取消初始化PWM
PwmStart 根据输入参数输出PWM
PwmStop 停止PWM输出

2.视频扩展实验源码

#include #include #include "ohos_init.h"#include "cmsis_os2.h"#include "wifiiot_pwm.h"#include "wifiiot_gpio.h"#include "wifiiot_gpio_ex.h"​#define PWM_TASK_STACK_SIZE 512#define PWM_TASK_PRIO 25​static void PWMTask(void){    unsigned int i;​    //初始化GPIO    GpioInit();​    //设置GPIO_2引脚复用功能为PWM    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_IO_FUNC_GPIO_2_PWM2_OUT);​    //设置GPIO_2引脚为输出模式    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_GPIO_DIR_OUT);​    //初始化PWM2端口    PwmInit(WIFI_IOT_PWM_PORT_PWM2);​    uint16_t j=0;    while (1)    {        for (i = 0; i < 40000; i += 100)        {            //输出不同占空比的PWM波            PwmStart(WIFI_IOT_PWM_PORT_PWM2, i, 40000);            // if(i==10000){            //     PwmStop(WIFI_IOT_PWM_PORT_PWM2);            // }            j++;            if(j == 20000){                PwmDeinit(WIFI_IOT_PWM_PORT_PWM2);            }            usleep(10);        }        i = 0;    }}​static void PWMExampleEntry(void){    osThreadAttr_t attr;​    attr.name = "PWMTask";    attr.attr_bits = 0U;    attr.cb_mem = NULL;    attr.cb_size = 0U;    attr.stack_mem = NULL;    attr.stack_size = 512;    attr.priority = 25;​    if (osThreadNew((osThreadFunc_t)PWMTask, NULL, &attr) == NULL)    {        printf("Falied to create PWMTask!\n");    }}​APP_FEATURE_INIT(PWMExampleEntry);

3.实验现象及结果分析

本实验的核心部分是通过调整pwm占空比来控制灯的亮度,核心代码如下:

 while (1) {     for (i = 0; i < 40000; i += 100)     {  //输出不同占空比的PWM波  PwmStart(WIFI_IOT_PWM_PORT_PWM2, i, 40000);         usleep(10);    }    i = 0;}

其余部分如:

PwmStop(WIFI_IOT_PWM_PORT_PWM2);

PwmStart(WIFI_IOT_PWM_PORT_PWM2);

PwmDeinit(WIFI_IOT_PWM_PORT_PWM2);

只需要在对应时刻实用变量控制停止和开始即可,不同的应用场景有不同的应用需求。