编辑语:
芯片开放社区(OCC)面向广大开发者推出应用实战系列内容,通过分享开发者实战开发案例,总结应用开发经验,梳理开发中的常见问题及解决方案,为后续参与的开发者提供更多参考与借鉴。
基于RVB2601开发板的应用实战,我们已经分别为大家介绍了基础环境搭建、LVGL移植和设备连接上云。为了帮助大家实现更多对RVB2601的控制,本期内容我们将解析控制台、自定义命令、PWM呼吸灯等相关内容。
01 控制台解读与自定义命令
在HelloWorld中我发现可以通过在串口助手输入help可以获取可以键入的命令:
包括了系统命令和用户命令。
但是在做LED实验时输入help却没有反应,但是这个控制台确实是比较方便调试,还有系统的状态查看,所以我对比了两个工程的异同。
在进入main函数后先进行yoc初始化,这里面初始化了RX,TX引脚和功能,然后进行波特率的设置,设置LOG打印等级,最后就是关键的cli初始化,这个就是控制台的初始化,在cli初始化里面,aos_cli_init就是前面看到的系统Commands,cli_reg_cmd_ps、cli_reg_cmd_free()就是User Commands。
添加完这些代码之后再编译烧录就可以使用控制台命令了!!
那我们可不可以自己定义自己的命令呢?
照着ps和free的命令,ps命令初始化函数如下:
cli_command是命令的结构体,有三个成员变量,分别为名字还有命令的具体描述信息还有回调函数。
我们可以自定义一个命令,取名test:然后编写回调函数:(这里argc是输入参数的个数,我们将输入的参数全部打印出来作为测试用),最后调用注册命令函数传入自定义命令结构体:
编译烧录控制台键入help可以看到test出现在了用户命令中了:
然后输入带参数的test命令,可以看到与预期的结果一致(注意这里是得到字符串,我们可以用strcmp或用atoi将数字字符串转为int形进一步去判断然后实现自己想要的业务逻辑功能):
02 点RGB灯
从原理图看出LED低电平亮:我们可以用通用IO口点亮还可以将GPIO复用为PWM来实现呼吸灯的效果。
① GPIO方式:(以PA7为例)
设置引脚模式为通用IO口:
csi_pin_set_mux(PA7, PIN_FUNC_GPIO);
引脚初始化:
csi_gpio_pin_init(&r, PA7);
设置引脚输出方向:
csi_gpio_pin_dir(&r, GPIO_DIRECTION_OUTPUT);
设置引脚电平:
csi_gpio_pin_write(&r, GPIO_PIN_LOW);
了解完主要的API后我们在主函数创建一个led任务,在任务中初始化,接着每1000ms调用led样式刷新函数(也就是一秒切换一个led颜色):
int main(void) { board_yoc_init(); aos_task_new("demo", demo_task, NULL, 10 * 1024); aos_task_new("led_task", led_task, NULL, 1 * 1024); return 0; /*****************************************************************/ static void led_task(void *arg) { led_pinmux_init(); while (1) { aos_msleep(1000); led_refresh(); } } /*********************************************************/ void led_refresh() { g_ctr++; if (g_ctr == 3)g_ctr=0; if (g_ctr == 0) { csi_gpio_pin_write(&r, GPIO_PIN_HIGH); csi_gpio_pin_write(&g, GPIO_PIN_HIGH); csi_gpio_pin_write(&b, GPIO_PIN_LOW); } else if (g_ctr == 1) { csi_gpio_pin_write(&r, GPIO_PIN_LOW); csi_gpio_pin_write(&g, GPIO_PIN_HIGH); csi_gpio_pin_write(&b, GPIO_PIN_HIGH); } else { csi_gpio_pin_write(&r, GPIO_PIN_HIGH); csi_gpio_pin_write(&g, GPIO_PIN_LOW); csi_gpio_pin_write(&b, GPIO_PIN_HIGH); } }
② PWM方式:
设置引脚功能复用为PWM模式:
csi_pin_set_mux(PA7, PA7_PWM_CH7);
初始化PWM:
csi_pwm_init(&r, 0);
配置PWM周期、有效电平时间和有效电平极性:
csi_pwm_out_config(&r, 7 / 2, 300, 100, PWM_POLARITY_HIGH);
使能PWM
csi_pwm_out_start(&r, 7 / 2);
用逻辑分析仪测出来占空比差不多为100/300即33.3%
然后我们在main函数依然创建一个led任务,led刷新函数里每5ms对g_ctr++或--,取决于dir值,dir就要用到刚刚的控制台用户自定义命令了,在控制台对dir值修改可以改变呼吸灯的变亮或变暗。
static void led_task(void *arg) { led_pinmux_init(); while (1) { aos_msleep(5); led_refresh(); } } /************************************************/ void led_pinmux_init() { // 7 csi_error_t ret; csi_pin_set_mux(PA7, PA7_PWM_CH7); csi_pin_set_mux(PA25, PA25_PWM_CH2); csi_pin_set_mux(PA4, PA4_PWM_CH4); ret = csi_pwm_init(&r, 0); if(ret != CSI_OK) { printf("===%s, %d\n", __FUNCTION__, __LINE__); return; } ret = csi_pwm_out_config(&r, 7 / 2, 300, 100, PWM_POLARITY_HIGH); if(ret != CSI_OK) { printf("===%s, %d\n", __FUNCTION__, __LINE__); return; } ret = csi_pwm_out_start(&r, 7 / 2); if(ret != CSI_OK) { printf("===%s, %d\n", __FUNCTION__, __LINE__); return; } // 25 ret = csi_pwm_out_config(&r, 2 / 2, 300, 100, PWM_POLARITY_HIGH); if(ret != CSI_OK) { printf("===%s, %d\n", __FUNCTION__, __LINE__); return; } ret = csi_pwm_out_start(&r, 2 / 2); if(ret != CSI_OK) { printf("===%s, %d\n", __FUNCTION__, __LINE__); return; } // 4 ret = csi_pwm_out_config(&r, 4 / 2, 300, 100, PWM_POLARITY_HIGH); if(ret != CSI_OK) { printf("===%s, %d\n", __FUNCTION__, __LINE__); return; } ret = csi_pwm_out_start(&r, 4 / 2); if(ret != CSI_OK) { printf("===%s, %d\n", __FUNCTION__, __LINE__); return; } csi_pwm_out_stop(&r, 2 / 2); csi_pwm_out_stop(&r, 7/ 2); } /**********************************************************/ void led_refresh() { switch(dir) { case 0: g_ctr++; if(g_ctr == 300) { g_ctr = 0; } csi_pwm_out_config(&r,1, 300, g_ctr, PWM_POLARITY_HIGH); break; case 1: g_ctr--; if(g_ctr == 0) { g_ctr = 300; } csi_pwm_out_config(&r,1, 300, g_ctr, PWM_POLARITY_HIGH); break; default: g_ctr++; if(g_ctr == 300) { g_ctr = 0; } csi_pwm_out_config(&r, 1, 300, g_ctr, PWM_POLARITY_HIGH); break; } } /**************************************************/ void mycmd_func(char *wbuf, int wbuf_len, int argc, char **argv) { extern uint dir; dir=atoi(argv[1]); }
03 舵机
csi_pwm_out_config(&r, 2, 300, g_ctr, PWM_POLARITY_HIGH);
04 下期预告
以上即为本期全部内容,下期我们将为大家推荐关于RVB2601的以太网通讯测试,欢迎大家持续关注应用实战系列内容。