发帖
2 0 0

菜鸟的Ai-WB2-32S-Kit模块点灯初尝试

GCSC
注册会员

1

主题

1

回帖

69

积分

注册会员

积分
69
Ai-WB2系列 20 2 4 小时前

搭建开发环境

按照贴吧教程搭建开发环境,过程不多说,整体比较顺利。

不理解的是为啥写代码时ECLIPSE这么多XX和小虫虫啊,代码不能正常索引关联,但是编译过程是没有报错。这对强迫症来说太痛苦了,捣鼓半天没解决,望高手指点。

实在解决不了,后面看看能不能问豆包要个脚本将代码放进SourceInsight编辑,ESP32已这样搞定。

image.png

码代码

从参考历程入手

寻思这个BL602咱也不熟,直接使用SDK参考例程上手学习吧!

这里我导入的是demo pwm例程,计划用PWM控制三色灯实现调光、渐变、闪烁、混色之类的效果。导入过程如下:

image.png

核对硬件电路和代码发现示例的三路PWM输出脚刚好就是RGB三色灯控制脚,IO也不用配置了。

image.png

代码逻辑

逻辑框架

主要通过PWM_Channel_Set_Threshold2分别控制三路pwm占空比实现调光,具体为:

  • main 函数
    • GPIO 和 PWM 初始化
    • 创建四个点灯任务,控制执行顺序
    • 主循环(打印系统运行信息)
  • 调光任务 1(Task1
    • 循环控制 R、G、B 灯周期性变亮变暗
    • 切换任务到 Task2
  • 闪灯任务 2(Task2
    • 循环控制 RGB 灯半亮交替闪烁
    • 切换任务到 Task3
  • 混色任务 3(Task3
    • 循环控制某灯渐亮,另一灯全亮,剩余灯熄灭
    • 切换任务到 Task4
  • 混色任务 4(Task4
    • 循环控制某灯渐亮,另外两灯全亮
    • 切换任务到 Task1

代码展示

#include <FreeRTOS.h>
#include <task.h>
#include <blog.h>
#include <bl602.h>
#include <bl602_gpio.h>
#include <bl602_glb.h>
#include <bl_pwm.h>
#include <event_groups.h>


#define R_LED_PIN (14)
#define G_LED_PIN (17)
#define B_LED_PIN (3)

#define R_LED_PWM_CH   (4)
#define G_LED_PWM_CH   (2)
#define B_LED_PWM_CH   (3)

#define R_FULL   (1<<0)
#define G_FULL   (1<<1)
#define B_FULL   (1<<2)

#define PWM_PERIOD_VALUE (400)
#define ADJUST_DELAY (3)
#define RETRY_TIME (3)

#define PWM_Get_Channel_Reg(ch)  (PWM_BASE+PWM_CHANNEL_OFFSET+(ch)*0x20)
#define PWM_STOP_TIMEOUT_COUNT          (160*1000)



TaskHandle_t task1Handle, task2Handle, task3Handle, task4Handle;
int currentTask = 1;

/// @brief Copy from PWM_Smart_Configure. Use Bus Clock instead of External Crystal Clock for PWM Timer
/// @param ch PWM Channel
/// @param clkDiv PWM clock divider
/// @param period PWM period
/// @param threshold2 
/// @return 
BL_Err_Type PWM_Smart_Configure2(PWM_CH_ID_Type ch, uint16_t clkDiv, uint16_t period,uint16_t threshold2)
{
    uint32_t tmpVal;
    uint32_t timeoutCnt = PWM_STOP_TIMEOUT_COUNT;
    /* Get channel register */
    uint32_t PWMx = PWM_Get_Channel_Reg(ch);
  
    tmpVal = BL_RD_REG(PWMx, PWM_CONFIG);
    // if(BL_GET_REG_BITS_VAL(tmpVal, PWM_REG_CLK_SEL) != PWM_CLK_XCLK){
    if(BL_GET_REG_BITS_VAL(tmpVal, PWM_REG_CLK_SEL) != PWM_CLK_BCLK){
        BL_WR_REG(PWMx, PWM_CONFIG, BL_SET_REG_BIT(tmpVal, PWM_STOP_EN));
        while(!BL_IS_REG_BIT_SET(BL_RD_REG(PWMx, PWM_CONFIG), PWM_STS_TOP)){
            timeoutCnt--;
            if(timeoutCnt == 0){
                return TIMEOUT;
            }
        }
        // tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PWM_REG_CLK_SEL, PWM_CLK_XCLK);
        tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PWM_REG_CLK_SEL, PWM_CLK_BCLK);
    }
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PWM_OUT_INV, PWM_POL_NORMAL);
    tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PWM_STOP_MODE, PWM_STOP_GRACEFUL);
    BL_WR_REG(PWMx, PWM_CONFIG, tmpVal);

    /* Config pwm division */
    BL_WR_REG(PWMx, PWM_CLKDIV, clkDiv);

    /* Config pwm period and duty */
    BL_WR_REG(PWMx, PWM_PERIOD, period);
    BL_WR_REG(PWMx, PWM_THRE1, 0);
    BL_WR_REG(PWMx, PWM_THRE2, threshold2);
  
    return SUCCESS;
}

// 1. 分别控制R、G、B三色灯周期性变亮,再周期性变暗
void Task1(void *param)
{
    for(uint8_t j=0;j<RETRY_TIME;j++)
    {
        // R 灯变亮再变暗
        for (uint16_t cnt = 0; cnt <= PWM_PERIOD_VALUE; cnt++)
        {
            PWM_Channel_Set_Threshold2(R_LED_PWM_CH, cnt);
            vTaskDelay(ADJUST_DELAY);
        }
        for (uint16_t cnt = PWM_PERIOD_VALUE; cnt > 0; cnt--)
        {
            PWM_Channel_Set_Threshold2(R_LED_PWM_CH, cnt);
            vTaskDelay(ADJUST_DELAY);
        }

        // G 灯变亮再变暗
        for (uint16_t cnt = 0; cnt <= PWM_PERIOD_VALUE; cnt++)
        {
            PWM_Channel_Set_Threshold2(G_LED_PWM_CH, cnt);
            vTaskDelay(ADJUST_DELAY);
        }
        for (uint16_t cnt = PWM_PERIOD_VALUE; cnt > 0; cnt--)
        {
            PWM_Channel_Set_Threshold2(G_LED_PWM_CH, cnt);
            vTaskDelay(ADJUST_DELAY);
        }

        // B 灯变亮再变暗
        for (uint16_t cnt = 0; cnt <= PWM_PERIOD_VALUE; cnt++)
        {
            PWM_Channel_Set_Threshold2(B_LED_PWM_CH, cnt);
            vTaskDelay(ADJUST_DELAY);
        }
        for (uint16_t cnt = PWM_PERIOD_VALUE; cnt > 0; cnt--)
        {
            PWM_Channel_Set_Threshold2(B_LED_PWM_CH, cnt);
            vTaskDelay(ADJUST_DELAY);
        }
    }
    currentTask = 2;
    vTaskResume(task2Handle);
    vTaskSuspend(NULL);
}

// 2. 控制RGB三色灯半亮交替闪烁
void Task2(void *param)
{
    if (currentTask == 2)
    {
        for(uint8_t j=0;j<RETRY_TIME;j++)
        {
            // R 半亮
            PWM_Channel_Set_Threshold2(R_LED_PWM_CH, PWM_PERIOD_VALUE / 2);
            PWM_Channel_Set_Threshold2(G_LED_PWM_CH, 0);
            PWM_Channel_Set_Threshold2(B_LED_PWM_CH, 0);
            vTaskDelay(500);

            // G 半亮
            PWM_Channel_Set_Threshold2(R_LED_PWM_CH, 0);
            PWM_Channel_Set_Threshold2(G_LED_PWM_CH, PWM_PERIOD_VALUE / 2);
            PWM_Channel_Set_Threshold2(B_LED_PWM_CH, 0);
            vTaskDelay(500);

            // B 半亮
            PWM_Channel_Set_Threshold2(R_LED_PWM_CH, 0);
            PWM_Channel_Set_Threshold2(G_LED_PWM_CH, 0);
            PWM_Channel_Set_Threshold2(B_LED_PWM_CH, PWM_PERIOD_VALUE / 2);
            vTaskDelay(500);
        }
        currentTask = 3;
        vTaskResume(task3Handle);
        vTaskSuspend(NULL);
    }
    vTaskDelay(10);
}

// 3. 控制某颜色灯由熄灭逐渐全亮,同时某色灯全亮,剩下保持颜色熄灭,该逻辑三色都要轮流一遍
void Task3(void *param)
{
    if (currentTask == 3)
    {
        for(uint8_t j=0;j<RETRY_TIME;j++)
        {
            // R 灯渐亮,G 灯全亮
            for (uint16_t cnt = 0; cnt <= PWM_PERIOD_VALUE; cnt++)
            {
                PWM_Channel_Set_Threshold2(R_LED_PWM_CH, cnt);
                PWM_Channel_Set_Threshold2(G_LED_PWM_CH, PWM_PERIOD_VALUE);
                PWM_Channel_Set_Threshold2(B_LED_PWM_CH, 0);
                vTaskDelay(ADJUST_DELAY);
            }
            vTaskDelay(500);

            // G 灯渐亮,B 灯全亮
            for (uint16_t cnt = 0; cnt <= PWM_PERIOD_VALUE; cnt++)
            {
                PWM_Channel_Set_Threshold2(G_LED_PWM_CH, cnt);
                PWM_Channel_Set_Threshold2(B_LED_PWM_CH, PWM_PERIOD_VALUE);
                PWM_Channel_Set_Threshold2(R_LED_PWM_CH, 0);
                vTaskDelay(ADJUST_DELAY);
            }
            vTaskDelay(500);

            // B 灯渐亮,R 灯全亮
            for (uint16_t cnt = 0; cnt <= PWM_PERIOD_VALUE; cnt++)
            {
                PWM_Channel_Set_Threshold2(B_LED_PWM_CH, cnt);
                PWM_Channel_Set_Threshold2(R_LED_PWM_CH, PWM_PERIOD_VALUE);
                PWM_Channel_Set_Threshold2(G_LED_PWM_CH, 0);
                vTaskDelay(ADJUST_DELAY);
            }
            vTaskDelay(500);
        }
        currentTask = 4;
        vTaskResume(task4Handle);
        vTaskSuspend(NULL);
    }
    vTaskDelay(10);
}

// 4. 控制某颜色灯由熄灭逐渐全亮,同时剩下两色某色灯全亮,该逻辑三色都要轮流一遍
void Task4(void *param)
{
    if (currentTask == 4)
    {
        for(uint8_t j=0;j<RETRY_TIME;j++)
        {
            // R 灯渐亮,G 灯全亮,B 灯全亮
            for (uint16_t cnt = 0; cnt <= PWM_PERIOD_VALUE; cnt++)
            {
                PWM_Channel_Set_Threshold2(R_LED_PWM_CH, cnt);
                PWM_Channel_Set_Threshold2(G_LED_PWM_CH, PWM_PERIOD_VALUE);
                PWM_Channel_Set_Threshold2(B_LED_PWM_CH, PWM_PERIOD_VALUE);
                vTaskDelay(ADJUST_DELAY);
            }
            vTaskDelay(500);

            // G 灯渐亮,R 灯全亮,B 灯全亮
            for (uint16_t cnt = 0; cnt <= PWM_PERIOD_VALUE; cnt++)
            {
                PWM_Channel_Set_Threshold2(G_LED_PWM_CH, cnt);
                PWM_Channel_Set_Threshold2(R_LED_PWM_CH, PWM_PERIOD_VALUE);
                PWM_Channel_Set_Threshold2(B_LED_PWM_CH, PWM_PERIOD_VALUE);
                vTaskDelay(ADJUST_DELAY);
            }
            vTaskDelay(500);

            // B 灯渐亮,R 灯全亮,G 灯全亮
            for (uint16_t cnt = 0; cnt <= PWM_PERIOD_VALUE; cnt++)
            {
                PWM_Channel_Set_Threshold2(B_LED_PWM_CH, cnt);
                PWM_Channel_Set_Threshold2(R_LED_PWM_CH, PWM_PERIOD_VALUE);
                PWM_Channel_Set_Threshold2(G_LED_PWM_CH, PWM_PERIOD_VALUE);
                vTaskDelay(ADJUST_DELAY);
            }
            vTaskDelay(500);
        }
        currentTask = 1;
        vTaskResume(task1Handle);
        vTaskSuspend(NULL);
    }
    vTaskDelay(10);
}


int main(void)
{
    GLB_GPIO_Cfg_Type cfg[3] = {
        {
            .drive = 0,
            .smtCtrl = 1,
            .gpioMode = GPIO_MODE_OUTPUT,
            .pullType = GPIO_PULL_DOWN,
            .gpioPin = 14,  /// red
            .gpioFun = 8,
        },
        {
            .drive = 0,
            .smtCtrl = 1,
            .gpioMode = GPIO_MODE_OUTPUT,
            .pullType = GPIO_PULL_DOWN,
            .gpioPin = 17,  /// green
            .gpioFun = 8,
        },
        {
            .drive = 0,
            .smtCtrl = 1,
            .gpioMode = GPIO_MODE_OUTPUT,
            .pullType = GPIO_PULL_DOWN,
            .gpioPin = 3,  /// blue
            .gpioFun = 8,
        },
    };


    for (int i = 0; i < 3; i++) {
        GLB_GPIO_Init(cfg + i);

        PWM_CH_ID_Type ch = cfg[i].gpioPin % PWM_CH_MAX;
        PWM_Channel_Disable(ch);
    }
    /// PWM Frequency = 80 Hz / Divider / Period

    /// set pwm channel 2 for 50% duty, 40MHz
    PWM_Smart_Configure2(2, 1, PWM_PERIOD_VALUE, 0);
    PWM_Channel_Enable(2);

    /// set pwm channel 3 for 75% duty, 5MHz
    PWM_Smart_Configure2(3, 1, PWM_PERIOD_VALUE, 0);
    PWM_Channel_Enable(3);

    /// set pwm channel 3 for 10% duty, 1MHz
    PWM_Smart_Configure2(4, 1, PWM_PERIOD_VALUE, 0);
    PWM_Channel_Enable(4);

   // ColorFullEvent=xEventGroupCreate();
  //  xEventGroupClearBits(ColorFullEvent,R_FULL|G_FULL);

    xTaskCreate(Task1, "Task1", 1024, NULL, 15, &task1Handle);
    vTaskSuspend(task1Handle);
    xTaskCreate(Task2, "Task2", 1024, NULL, 15, &task2Handle);
    vTaskSuspend(task2Handle);
    xTaskCreate(Task3, "Task3", 1024, NULL, 15, &task3Handle);
    vTaskSuspend(task3Handle);
    xTaskCreate(Task4, "Task4", 1024, NULL, 15, &task4Handle);
    vTaskSuspend(task4Handle);
    vTaskResume(task1Handle);

    for (;;)
    {
        vTaskDelay(pdMS_TO_TICKS(1000));
        printf("system running! \r\n");
    }
    return 0;
}

流程图描述

  1. 开始:程序启动,进入 main 函数。
  2. GPIO 和 PWM 初始化
    • 定义并初始化 RGB 三色灯的 GPIO 配置数组 cfg
    • 遍历 cfg 数组,对每个 GPIO 引脚进行初始化,并禁用对应的 PWM 通道。
    • 分别配置 PWM 通道 2、3、4 的参数(频率、占空比等)并启用这些通道。
  3. 创建任务并控制执行顺序
    • 创建四个任务 Task1Task2Task3Task4,并分别挂起它们。
    • 恢复 Task1 任务的执行。
  4. 任务 1(Task1
    • 循环 RETRY_TIME 次。
      • 控制 R 灯周期性变亮再变暗(通过改变 PWM 阈值并延时)。
      • 控制 G 灯周期性变亮再变暗。
      • 控制 B 灯周期性变亮再变暗。
    • 任务完成后,设置 currentTask = 2,恢复 Task2 任务并挂起自身。
  5. 任务 2(Task2
    • currentTask == 2 时,循环 RETRY_TIME 次。
      • 使 R 灯半亮,G 灯和 B 灯熄灭,延时 500ms。
      • 使 G 灯半亮,R 灯和 B 灯熄灭,延时 500ms。
      • 使 B 灯半亮,R 灯和 G 灯熄灭,延时 500ms。
    • 任务完成后,设置 currentTask = 3,恢复 Task3 任务并挂起自身。
  6. 任务 3(Task3
    • currentTask == 3 时,循环 RETRY_TIME 次。
      • 使 R 灯渐亮,G 灯全亮,B 灯熄灭(通过改变 PWM 阈值并延时),然后延时 500ms。
      • 使 G 灯渐亮,B 灯全亮,R 灯熄灭,然后延时 500ms。
      • 使 B 灯渐亮,R 灯全亮,G 灯熄灭,然后延时 500ms。
    • 任务完成后,设置 currentTask = 4,恢复 Task4 任务并挂起自身。
  7. 任务 4(Task4
    • currentTask == 4 时,循环 RETRY_TIME 次。
      • 使 R 灯渐亮,G 灯和 B 灯全亮(通过改变 PWM 阈值并延时),然后延时 500ms。
      • 使 G 灯渐亮,R 灯和 B 灯全亮,然后延时 500ms。
      • 使 B 灯渐亮,R 灯和 G 灯全亮,然后延时 500ms。
    • 任务完成后,设置 currentTask = 1,恢复 Task1 任务并挂起自身。
  8. 主循环:在 main 函数的主循环中,每隔 1000ms 打印 "system running! \r\n"。
  9. 结束:程序持续运行,不断循环执行上述任务。

点灯效果

见视频附件

──── 0人觉得很赞 ────

使用道具 举报

4 小时前
视频上传一直失败,截点图算了
GCSC 发表于 2025-4-24 17:34
视频上传一直失败,截点图算了

你把视频发我,我给你上传。
您需要登录后才可以回帖 立即登录
高级模式
返回
统计信息
  • 会员数: 28580 个
  • 话题数: 40693 篇