1.项目功能梗概
因为原本使用的为for循环进行遍历,然后依次执行代码,但是由于看门狗的存在,不能使用delay_ms这种死延时。所以现在打算定时器回调函数控制状态机状态这种方法。
2.状态机
作用
当系统需要执行某个任务时,可以根据状态机的状态选择不同的操作,例如:
- 控制系统状态:例如控制器根据状态机的状态选择执行不同的操作,从而控制整个系统的状态,例如开关灯、控制电机等。
- 系统调度:例如操作系统根据状态机的状态选择执行不同的任务,从而实现系统的调度。
- 系统事件处理:例如网络通信系统根据状态机的状态选择不同的数据处理方式,例如处理接收到的数据、发送数据等。
- 系统错误处理:例如系统出现错误时,可以根据状态机的状态选择不同的错误处理方式,例如重新启动系统、输出错误信息等。
总之,状态机可以帮助我们将系统的复杂性分解为多个简单的状态,根据不同的状态选择执行不同的操作,从而更好地实现系统的设计与开发。
主要流程
-
定义状态和事件
首先需要定义系统可能存在的所有状态,通常用枚举类型来表示。同时需要定义可能发生的所有事件,例如输入的数据、定时器到达等。
-
初始化状态机
在程序启动时,需要将状态机初始化为特定的状态。
-
定义状态转换和动作
使用switch-case if-else 函数指针等语句来定义状态转换和动作。当事件发生时,判断当前状态,并根据不同的事件执行相应的动作,并将状态转换为下一个状态。
-
事件处理
当有事件发生时,将事件作为参数传递给状态机,并调用状态转换和动作函数。
-
循环执行
状态机通常作为一个独立的任务运行,并在一个无限循环中等待事件的发生。
3.实现过程相关思考
说实话,尝试了下突然有用标志位的思路了
// 定义全局指针变量
u8 *global_bt_receive_buffer_gradually;
u32 global_length_gradually;
volatile u8 time_flag_gradually = 0;
void handleColor_arrayChange_gradually(u8 *bt_receive_buffer, u32 length)
{
printf("通过数组控制灯颜色状态\n");
static int j = 0;
static int i = 5;
u8 STEPS = 30;
static u8 i_balance = 3;
// 获取初始亮度i-
u8 initial_red_value = bt_receive_buffer[i];
u8 initial_green_value = bt_receive_buffer[i+1];
u8 initial_blue_value = bt_receive_buffer[i+2];
for (; (i < (length - 5)) && (time_flag_gradually == 0);)
{
u8 target_red_value = bt_receive_buffer[i + 3];
u8 target_green_value = bt_receive_buffer[i + 4];
u8 target_blue_value = bt_receive_buffer[i + 5];
printf("i的值为-----------i的值为-----------i的值为-----------i的值为-----------i的值为-----------i的值为-----------i的值为-----------i的值为-----------%d\n", i);
printf("target_red_value------------------target_red_value---------------target_red_value%d\n", target_red_value);
printf("target_red_value------------------target_red_value---------------target_red_value%d\n", target_green_value);
printf("target_red_value------------------target_red_value---------------target_red_value%d\n", target_blue_value);
// 计算每个颜色通道的增量
int red_increment = (target_red_value - initial_red_value) / STEPS;
int green_increment = (target_green_value - initial_green_value) / STEPS;
int blue_increment = (target_blue_value - initial_blue_value) / STEPS;
// 逐步更新颜色值,使其渐变到目标值
for (; (j < STEPS) && (time_flag_gradually == 0); j++)
{
u8 current_red_value = initial_red_value + (red_increment * j);
u8 current_green_value = initial_green_value + (green_increment * j);
u8 current_blue_value = initial_blue_value + (blue_increment * j);
handleColorChange(current_red_value, current_green_value, current_blue_value);
// delay_2ms(24); // 延时一段时间,控制灯的变化速度
printf("initial_red_value----initial_red_value----initial_red_value----initial_red_value----initial_red_value----%d\n", initial_red_value);
printf("initial_green_value-----initial_green_value-------initial_green_value-------initial_green_value-------%d\n", initial_green_value);
printf("initial_blue_valueinitial_blue_valueinitial_blue_valueinitial_blue_valueinitial_blue_valueinitial_b%d\n", initial_blue_value);
printf("红色值每一次增量------红色值每一次增量--------红色值每一次增量--------红色值每一次增量-------红色值每一次增量%d\n", red_increment);
printf("绿色值每一次增量------绿色值每一次增量------绿色值每一次增量------绿色值每一次增量------绿色值每一次增量------绿色值每一次增量------%d\n", green_increment);
printf("蓝色值每一次增量------蓝色值每一次增量------蓝色值每一次增量------蓝色值每一次增量------蓝色值每一次增量------蓝色值每一次增量------蓝色值每一次增量------%d\n", blue_increment);
time_flag_gradually = 1;
printf("jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj===================%d\n", j);
}
if (j >= STEPS)
{
j = 0;
i = i + 3;
}
printf("第一组 RGB 值已经渐变到第二组一样\n");
// 更新初始亮度为目标亮度,以便下一组渐变
initial_red_value = target_red_value;
initial_green_value = target_green_value;
initial_blue_value = target_blue_value;
}
if (i >= (length - 5))
{
i = 5;
}
global_bt_receive_buffer_gradually = bt_receive_buffer;
global_length_gradually = length;
}
u32 timeout_msec_gradually = 5; // 设置定时时间为10毫秒
void timeout_callback_gradually(void *priv)
{
// 每10ms
static u8 i = 5;
// printf("回调函数渐变\n");
printf("回调函数渐变%d\n", time_flag_gradually);
// printf("time_flag_gradually != 0time_flag_gradually != 0time_flag_gradually != 0time_flag_gradually != 0time_flag_gradually != 0\n");
i = i + 5;
if (i == 50)
{
time_flag_gradually = 0;
i = 0;
}
handleColor_arrayChange_gradually(global_bt_receive_buffer_gradually, global_length_gradually);
}
其实就是把第一个for循环里的数组移位转移到了小的for循环里,只有当小的for循环里面已经将颜色渐变全部实现了,才允许i++实现移位。不过有个问题就是颜色渐变完成后,会从最后一个颜色突变到第一个颜色。这里应该是在设置代码初始化时的重新赋值的原因,导致缺失了一段颜色变化。
- 将所要的颜色数据数据提取出来,作为一个数组。每一次颜色渐变完成,就将数组的后三位赋值到前三位,以此类推,重新执行函数。
- 第二种,写死,每次多执行一段最后一个颜色渐变到第一个颜色的代码。
疑惑,有没有使用更简洁的方法,或者说环形数组对这种循环显示的是不是更好。
贴一下目前代码图片
u16 timer_id_color_change_suddenly = 0;
u16 timer_id_color_change_gradually = 0;
void *private_data = NULL; // 设置私有参数为NULL
u32 timeout_msec = 10; // 设置定时时间为10毫秒
u8 priority = 1; // 设置优先级为1
void timeout_callback(void *priv)
{
static u16 i = 0;
printf("回调函数跳变\n");
i = i + 10;
if (i == 1000)
{
printf("ifififiifiifififiififififi\n");
time_flag_suddenly = 1;
i = 0;
}
handleColor_arrayChange_suddenly(global_bt_receive_buffer, global_length, global_color_mode_record, global_color1);
}
// 定义全局指针变量
u8 *global_bt_receive_buffer_gradually;
u32 global_length_gradually;
volatile u8 time_flag_gradually = 0;
void handleColor_arrayChange_gradually(u8 *bt_receive_buffer, u32 length)
{
printf("通过数组控制灯颜色状态\n");
static int j = 0;
static int i = 5;
u8 STEPS = 30;
static u8 i_balance = 3;
static flag = 1;
// 获取初始亮度i-
u8 initial_red_value = bt_receive_buffer[i];
u8 initial_green_value = bt_receive_buffer[i + 1];
u8 initial_blue_value = bt_receive_buffer[i + 2];
for (; (i < (length - 5)) && (time_flag_gradually == 0);)
{
u8 target_red_value = bt_receive_buffer[i + 3];
u8 target_green_value = bt_receive_buffer[i + 4];
u8 target_blue_value = bt_receive_buffer[i + 5];
printf("i的值为-----------i的值为-----------i的值为-----------i的值为-----------i的值为-----------i的值为-----------i的值为-----------i的值为-----------%d\n", i);
printf("target_red_value------------------target_red_value---------------target_red_value%d\n", target_red_value);
printf("target_red_value------------------target_red_value---------------target_red_value%d\n", target_green_value);
printf("target_red_value------------------target_red_value---------------target_red_value%d\n", target_blue_value);
// 计算每个颜色通道的增量
int red_increment = (target_red_value - initial_red_value) / STEPS;
int green_increment = (target_green_value - initial_green_value) / STEPS;
int blue_increment = (target_blue_value - initial_blue_value) / STEPS;
// 逐步更新颜色值,使其渐变到目标值
for (; (j < STEPS) && (time_flag_gradually == 0); j++)
{
u8 current_red_value = initial_red_value + (red_increment * j);
u8 current_green_value = initial_green_value + (green_increment * j);
u8 current_blue_value = initial_blue_value + (blue_increment * j);
handleColorChange(current_red_value, current_green_value, current_blue_value);
// delay_2ms(24); // 延时一段时间,控制灯的变化速度
printf("initial_red_value----initial_red_value----initial_red_value----initial_red_value----initial_red_value----%d\n", initial_red_value);
printf("initial_green_value-----initial_green_value-------initial_green_value-------initial_green_value-------%d\n", initial_green_value);
printf("initial_blue_valueinitial_blue_valueinitial_blue_valueinitial_blue_valueinitial_blue_valueinitial_b%d\n", initial_blue_value);
printf("红色值每一次增量------红色值每一次增量--------红色值每一次增量--------红色值每一次增量-------红色值每一次增量%d\n", red_increment);
printf("绿色值每一次增量------绿色值每一次增量------绿色值每一次增量------绿色值每一次增量------绿色值每一次增量------绿色值每一次增量------%d\n", green_increment);
printf("蓝色值每一次增量------蓝色值每一次增量------蓝色值每一次增量------蓝色值每一次增量------蓝色值每一次增量------蓝色值每一次增量------蓝色值每一次增量------%d\n", blue_increment);
time_flag_gradually = 1;
printf("jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj===================%d\n", j);
}
if (j >= STEPS)
{
j = 0;
i = i + 3;
}
printf("第一组 RGB 值已经渐变到第二组一样\n");
// 更新初始亮度为目标亮度,以便下一组渐变
initial_red_value = target_red_value;
initial_green_value = target_green_value;
initial_blue_value = target_blue_value;
}
if (i >= (length - 5))
{
i=5;
}
global_bt_receive_buffer_gradually = bt_receive_buffer;
global_length_gradually = length;
}