【教程】【Ai-M62-32S】点灯,但是FreeRTOS

[复制链接]
查看540 | 回复2 | 2023-11-20 21:35:13 | 显示全部楼层 |阅读模式
本帖最后由 aHaoii 于 2023-11-20 21:40 编辑

继续点灯。。。。。。。
没什么可玩的,其它元件都在家里放着,在学校只能先凑合点灯玩了。

                               
登录/注册后可看大图

这次的想法是RGB灯珠的红色灯做一个呼吸灯,板载两颗LED灯进行交替闪烁同步进行。
呼吸灯的逻辑是在循环里面每10ms改变一次占空比,LED的闪烁是250ms翻转一次电平状态。
这个逻辑比较简单,其实可以写在一个循环里面,用几个变量进行控制即可。
但是,有现成的FreeRTOS系统给我们用,肯定直接上操作系统啦!!!!
开始。

                               
登录/注册后可看大图

【1】找例程
官方examples里面提供一份FreeRTOS的示例,里面的大致内容是设置了两个信号量,一个互斥锁,
两个任务,实现了一个生产者消费者模型。我们在此基础上进行改动。
复制该文件夹一份,起名freertos_my,如图:
QQ截图20231120212151.png
【2】初始化代码
这部分没什么好说的,前面两个帖子已经做过。包括PWM初始化和LED初始化:
  1. static void my_pwm_init(void)
  2. {
  3.     struct bflb_device_s* gpio = bflb_device_get_by_name("gpio");
  4.     bflb_gpio_init(gpio, GPIO_PIN_12, GPIO_FUNC_PWM0 | GPIO_ALTERNATE | GPIO_PULLDOWN | GPIO_SMT_EN | GPIO_DRV_1);
  5.     ledr_pwm = bflb_device_get_by_name("pwm_v2_0");

  6.     /* period = .XCLK / .clk_div / .period = 40MHz / 40 / 1000 = 1KHz */
  7.     struct bflb_pwm_v2_config_s cfg = {
  8.         .clk_source = BFLB_SYSTEM_XCLK,
  9.         .clk_div = 40,
  10.         .period = 1000,
  11.     };

  12.     bflb_pwm_v2_init(ledr_pwm, &cfg);
  13.     bflb_pwm_v2_channel_set_threshold(ledr_pwm, PWM_CH0, 1, 900); /* duty = (500-100)/1000 = 40% */
  14.     bflb_pwm_v2_channel_positive_start(ledr_pwm, PWM_CH0);
  15.     bflb_pwm_v2_start(ledr_pwm);
  16. }
  17. static void my_led_init(void)
  18. {
  19.     struct bflb_device_s* gpio = bflb_device_get_by_name("gpio");
  20.     bflb_gpio_init(gpio, GPIO_PIN_27, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0);
  21.     bflb_gpio_init(gpio, GPIO_PIN_29, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0);
  22. }
复制代码
【3】任务代码
设置两个任务,一个任务调节PWM占空比,一个任务控制LED电平翻转,两个任务同步执行。
其中,VTaskDelay将任务阻塞,单位为毫秒。
  1. static void pwm_task(void *pvParameters)
  2. {
  3.     uint32_t val = 20;
  4.     bool flag = true;
  5.     while (1) {
  6.         if(flag){
  7.             val+=10;
  8.         }
  9.         else{
  10.             val-=10;
  11.         }
  12.         if(val>=970 || val <= 20){
  13.             flag = !flag;
  14.         }
  15.         bflb_pwm_v2_channel_set_threshold(ledr_pwm, PWM_CH0, 1, val);
  16.         vTaskDelay(10);
  17.     }
  18.     vTaskDelete(NULL);
  19. }
  20. static void led_task(void *pvParameters)
  21. {
  22.     struct bflb_device_s* gpio = bflb_device_get_by_name("gpio");
  23.     while (1) {
  24.         bflb_gpio_set(gpio, GPIO_PIN_27);
  25.         bflb_gpio_reset(gpio, GPIO_PIN_29);
  26.         vTaskDelay(250);
  27.         bflb_gpio_reset(gpio, GPIO_PIN_27);
  28.         bflb_gpio_set(gpio, GPIO_PIN_29);
  29.         vTaskDelay(250);
  30.     }
  31.     vTaskDelete(NULL);
  32. }
复制代码
【4】编写主函数
主函数比较简单,初始化以后创建任务,开启调度器即可。
其中xTaskCreate函数为创建任务,参数依次为该任务函数名、提示字符串、栈大小、任务函数参数、优先级、任务句柄。
  1. int main(void)
  2. {
  3.     board_init();
  4.     my_led_init();
  5.     my_pwm_init();

  6.     configASSERT((configMAX_PRIORITIES > 4));

  7.     xTaskCreate(pwm_task, (char *)"pwm_task", 128, NULL, configMAX_PRIORITIES - 2, &pwm_task_handle);
  8.     xTaskCreate(led_task, (char *)"led_task", 128, NULL, configMAX_PRIORITIES - 3, &led_task_handle);

  9.     vTaskStartScheduler();

  10.     while (1) {
  11.     }
  12. }
复制代码
【5】注意加头文件和全局变量
这是全局变量,前两个为任务句柄,用来控制任务的挂起恢复删除等。第三个为pwm的设备指针,用来修改pwm参数。如下:
  1. static TaskHandle_t pwm_task_handle;
  2. static TaskHandle_t led_task_handle;
  3. struct bflb_device_s* ledr_pwm;
复制代码
以下头文件包含了一些pwm初始化和gpio初始化所用到的一些函数和宏定义:
  1. #include "bflb_gpio.h"
  2. #include "bflb_pwm_v2.h"
  3. #include "bflb_clock.h"
复制代码
————————————————————
2023.11.20


本帖被以下淘专辑推荐:

回复

使用道具 举报

爱笑 | 2023-12-13 17:24:37 | 显示全部楼层
用心做好保姆工作
回复

使用道具 举报

心云 | 2023-12-17 10:00:54 | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则