小熊派鸿蒙开发

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

一、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 <stdio.h>
#include <unistd.h>
#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 <stdio.h>
#include <unistd.h>
​
#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 <stdio.h>
#include <unistd.h>
#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);

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值