在不懈的申请下,终于中奖一次,周一一早就收到了安信可发来的Ai-WB2开发板。整个开发板的布局中规中矩,很贴心的带了串口转换芯片和板载了3色led灯,对我等初学者还是特别的友好,开始本次的点灯之路。
根据论坛的教程先把开发环境搭建起来,这里推荐安信可官方账号发布的教程https://blog.csdn.net/Boantong_/article/details/128480919,保险一点儿,保险一点儿,从网盘慢慢把三个文件下载下来。按照文档安装。这里特别需要注意的是Ai-WB2系列SDK开发包的路径问题,一定要注意。我在完全按照指导做完后,Clean project时出现错误。

手动在cmd界面进行make后看到提示如图,这里可以肯定是sdk的路径有问题,造成找不到mk文件,重新修改路径和环境变量后,正常编译示例。参照Ai-Thinker-WB2/applications/peripherals/demo_pwm/里面的代码,我们来实现pwm控制led实现呼吸灯效果。
#include <stdio.h>
#include <string.h>
#include <FreeRTOS.h>
#include <task.h>
#include <bl_gpio.h>
#include <bl602.h>
#include <bl602_gpio.h>
#include <bl602_glb.h>
#include <bl_pwm.h>
#define PWM_Get_Channel_Reg(ch) (PWM_BASE+PWM_CHANNEL_OFFSET+(ch)*0x20)
#define PWM_STOP_TIMEOUT_COUNT (160*1000)
#define GPIO_BLUELED_PIN 3 //蓝色
#define GPIO_REDLED_PIN 14
#define GPIO_GREENLED_PIN 17
/// @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;
}
void led_pwm()
{
uint8_t value = 1;
uint8_t flag = 0;
while (1)
{
if(flag == 0)
{
value++;
if(value == 255)
flag = 1;
}
if(flag == 1)
{
value--;
if(value == 0)
flag = 0;
}
//PWM_Smart_Configure2(3, 1, 255, value);
//PWM_Channel_Enable(3);
PWM_Smart_Configure2(4, 1, 255, value);
PWM_Channel_Enable(4);
//PWM_Smart_Configure2(2, 1, 255, value);
//PWM_Channel_Enable(2);
vTaskDelay(10);
}
}
void 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);
}
xTaskCreate(led_pwm, "led_pwm", 1024, NULL, 15, NULL);
}
这里要注意几个关键的头文件,需要包含
#include <bl602.h>
#include <bl602_gpio.h>
#include <bl602_glb.h>
#include <bl_pwm.h>
最终实现效果如下
