【平头哥RVB2601创意应用开发】流水灯渐变灯
[复制链接]
本帖最后由 full_stack 于 2022-5-11 16:11 编辑
学习完调试方法,也建立helloworld并调试工程之后,
再体验一下最简单的人机交互应用——点亮LED灯
老样子,在CDK欢迎界面新建工程中搜索2601,上下翻找,就能找到一个ch2601_marquee_demo的工程,就从这个工程开始。
打开工程之后编译下载运行,复位之后看到左下角RGB灯依次亮起三种不同颜色,说明工程正常没有问题,基本上算是一个跑马灯例程。
但是看到main函数就几句话,从软件的角度,以及找到方法分析一下例程。
int main(void)
{
board_yoc_init();
printf("===%s, %d\n", __FUNCTION__, __LINE__);
printf("===%s, %d\n", __FUNCTION__, __LINE__);
aos_task_new("demo", demo_task, NULL, 10 * 1024);
return 0;
}
程序运行到main之后,第一个函数看函数名是板子的初始化,然后接下来的两个函数是打印函数以及行数。
此时
右键aos_task_new函数名选择Goto Declaration或者按住键盘ALT健可查看函数声明,
右键aos_task_new函数名选择Goto Implementation或者按住键盘Ctrl健可查看函数原型,
/**
* Create a task.
*
* @param[in] name task name.
* @param[in] fn function to run.
* @param[in] arg argument of the function.
* @param[in] stacksize stack-size in bytes.
*
* @return 0: success.
*/
int aos_task_new(const char *name, void (*fn)(void *), void *arg, int stack_size);
接口定义
动态创建一个任务
int aos_task_new(const char name, void (fn)(void ), void arg, int stack_size);
动态创建一个任务,任务句柄不返回,创建完后自动运行 采用默认优先级AOS_DEFAULT_APP_PRI(32),受宏RHINO_CONFIG_KOBJ_DYN_ALLOC开关控制
参数:
name:任务名
fn:任务处理函数
Arg: 任务处理函数参数
stack_size:任务栈大小(单位:字节)
返回值:
类型:0 返回成功 小于0返回失败
通过查看函数原型,大概可以明白这个函数意思是创建一个任务
如果看英文不习惯可以选择查看官方操作系统API:
https://yoc.docs.t-head.cn/yocbook/Chapter3-AliOS/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E6%8E%A5%E5%8F%A3/%E4%BB%BB%E5%8A%A1.html
搜索 aos_task_new 点击第一个 任务,就能找到该函数的详细说明。
创建完后自动运行 采用默认优先级。
然后找到这个函数,稍微懂点C语言的基本就能看懂了,
一系列的初始化之后,一秒钟更新一次LED,就出现了跑马灯的效果。
static void demo_task(void *arg)
{
lv_init();
oled_init();
lable_test();
led_pinmux_init();
while (1)
{
lv_task_handler();
udelay(1000 * 1000);
lv_tick_inc(1);
led_refresh();
}
}
细心的还能发现,main.c文件和led.c文件有相同的void led_pinmux_init()和void led_refresh()函数,其实,这是历程中用不同的实现方式实现跑马灯的效果,实际执行中只有一个被编译,在app_config.h中可以切换,突然想到,这种通过宏定义没被编译的代码,改变下颜色,成灰色,可视化就更好了。
#define CONFIG_PWM_MODE
//#define CONFIG_GPIO_MODE
接下来做个升级,共享一篇我移植的WS2812的程序,主要是实现渐变灯的效果,但是我发现拍视频之后效果很不明显,然后又加了个流水灯的效果。
程序用到的IO口为PA7,灯条电源外接(12V),刚开始没共地,灯一直闪闪的不停,后来共地之后很稳定。视频效果及源代码如下。
渐变灯流水灯.mp4
(8.61 MB, 下载次数: 0)
渐变灯流水灯
volatile uint32_t g_debug = 0;
volatile uint32_t g_debug_v = 0;
static void demo_task(void *arg);
#define delay_250ns() do { \
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); \
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); \
__NOP(); __NOP(); \
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); \
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); \
__NOP(); __NOP(); \
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); \
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); \
__NOP(); __NOP(); \
} while (0)
#define delay_100ns() do { \
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); \
__NOP(); \
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); \
__NOP(); \
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); \
__NOP(); \
} while (0)
#include "csi_core.h"
/**
* main
*/
int main(void)
{
board_yoc_init();
printf("===%s, %d\n", __FUNCTION__, __LINE__);
printf("===%s, %d\n", __FUNCTION__, __LINE__);
aos_task_new("demo", demo_task, NULL, 10 * 1024);
return 0;
}
static void lable_test(void)
{
lv_obj_t *p = lv_label_create(lv_scr_act(), NULL);
lv_label_set_long_mode(p, LV_LABEL_LONG_BREAK);
lv_label_set_align(p, LV_LABEL_ALIGN_CENTER);
lv_obj_set_pos(p, 0, 4);
lv_obj_set_size(p, 128, 60);
lv_label_set_text(p, "WS2812B\nColorToColor\nTest");
}
#ifdef CONFIG_GPIO_MODE
static uint32_t g_ctr = 0;
static csi_gpio_pin_t r;
static csi_gpio_pin_t g;
static csi_gpio_pin_t b;
void WS_Set_One(uint32_t dat)
{
uint32_t i;
for(i=0; i<24; i++)
{
if(0x800000 == (dat & 0x800000) ) {csi_gpio_pin_write(&r, GPIO_PIN_HIGH); delay_250ns(); delay_250ns(); delay_250ns(); csi_gpio_pin_write(&r, GPIO_PIN_LOW); delay_100ns(); delay_100ns();}
else {csi_gpio_pin_write(&r, GPIO_PIN_HIGH); delay_250ns(); csi_gpio_pin_write(&r, GPIO_PIN_LOW); delay_100ns(); delay_250ns(); delay_250ns();}
dat <<= 1;
}
}
void WS_SetAll( uint32_t color, uint32_t led_num) //发送同样的颜色color_num,led_num个数量的灯,颜色序号
{
uint32_t j;
for(j=0; j<led_num; j++)
{
WS_Set_One(color);
}
csi_gpio_pin_write(&r, GPIO_PIN_LOW);
}
int32_t abs0(int32_t num)
{
if(num>0) return num;
num = -num;
return num;
}
void ColorToColor(uint32_t color0, uint32_t color1, uint32_t len)
{
unsigned char Red0, Green0, Blue0; // 起始三原色
unsigned char Red1, Green1, Blue1; // 结果三原色
int RedMinus, GreenMinus, BlueMinus; // 颜色差(color1 - color0)
unsigned char NStep; // 需要几步
float RedStep, GreenStep, BlueStep; // 各色步进值
uint32_t color; // 结果色
unsigned char i;
// 绿 红 蓝 三原色分解
Red0 = (color0>>8) ;
Green0 = (color0>>16) ;
Blue0 = color0 ;
Red1 = (color1>>8);
Green1 = (color1>>16);
Blue1 = color1;
// 计算需要多少步(取差值的最大值)
RedMinus = Red1 - Red0 ;
GreenMinus = Green1 - Green0;
BlueMinus = Blue1 - Blue0;
NStep = ( abs0(RedMinus) > abs0(GreenMinus) ) ? abs0(RedMinus):abs0(GreenMinus);
NStep = ( NStep > abs0(BlueMinus) ) ? NStep:abs0(BlueMinus);
// 计算出各色步进值
RedStep = (float)RedMinus / NStep;
GreenStep = (float)GreenMinus / NStep;
BlueStep = (float)BlueMinus / NStep;
// 渐变开始
for(i=0; i< NStep; i++)
{
Red1 = Red0 + (int)(RedStep * i);
Green1 = Green0 + (int)(GreenStep * i);
Blue1 = Blue0 + (int)(BlueStep * i);
color = Green1<<16 | Red1<<8 | Blue1; // 合成 绿红蓝
WS_SetAll(color, 30);
udelay(8*1000); // 渐变速度
}
}
void led_pinmux_init()
{
csi_pin_set_mux(PA7, PIN_FUNC_GPIO);
csi_pin_set_mux(PA25, PIN_FUNC_GPIO);
csi_pin_set_mux(PA4, PIN_FUNC_GPIO);
csi_gpio_pin_init(&r, PA7);
csi_gpio_pin_dir(&r, GPIO_DIRECTION_OUTPUT);
csi_gpio_pin_init(&g, PA25);
csi_gpio_pin_dir(&g, GPIO_DIRECTION_OUTPUT);
csi_gpio_pin_init(&b, PA4);
csi_gpio_pin_dir(&b, GPIO_DIRECTION_OUTPUT);
g_ctr = 0;
}
void led_refresh()
{
g_ctr++;
if (g_ctr % 3 == 0)
{
csi_gpio_pin_write(&r, GPIO_PIN_HIGH);
csi_gpio_pin_write(&g, GPIO_PIN_LOW);
csi_gpio_pin_write(&b, GPIO_PIN_LOW);
}
else if (g_ctr % 2 == 0)
{
csi_gpio_pin_write(&r, GPIO_PIN_LOW);
csi_gpio_pin_write(&g, GPIO_PIN_HIGH);
csi_gpio_pin_write(&b, GPIO_PIN_LOW);
}
else
{
csi_gpio_pin_write(&r, GPIO_PIN_LOW);
csi_gpio_pin_write(&g, GPIO_PIN_LOW);
csi_gpio_pin_write(&b, GPIO_PIN_HIGH);
}
}
void marquee_test(void)
{
while (1)
{
udelay(1000 * 1000);
led_refresh();
}
}
#endif
static void demo_task(void *arg)
{
lv_init();
oled_init();
lable_test();
led_pinmux_init();
while (1)
{
unsigned char arg;
lv_task_handler();
udelay(1000 * 1000);
lv_tick_inc(1);
//WS_SetAll(0xFFFFFF, 30);
ColorToColor(0xFF0000, 0x00FF00,30); //红到绿
ColorToColor(0x0000FF, 0xFFFFFF,30); //蓝到白
ColorToColor(0x0000FF, 0xFF0000,30); //蓝到白
while(1)
{
for(arg = 0; arg <= 30; arg++)
WS_SetAll(0xFF0000, arg),udelay(25 * 1000);
WS_SetAll(0x00, 30);
}
//led_refresh();
}
}
|