使用一个结构体描述执行的动作,使用一个数组组成动作组,通过一个定时器遍历这个动作组。
#include "action.h"
#include "stm32f4xx_hal.h"
#include "switch_control.h"
#include "analog_io.h"
#define MAX_ACTIONS 20 //每组动作最大动作数量
#define ACT_NUM 4 //动作组总数
static Action action_set_1[20];
static Action action_set_2[2];
static Action action_set_3[2];
static Action action_set_4[2];
Action_ctrl act_ctrl_st[ACT_NUM] = {0};
//任务优先级
#define ACTION_TASK_PRIO 10
//任务堆栈大小
#define ACTION_STK_SIZE 500
//任务控制块
OS_TCB ACTION_TaskTCB;
//任务堆栈
CPU_STK ACTION_TASK_STK[ACTION_STK_SIZE];
//以任务形式执行
void start_action_task()
{
OS_ERR err;
OSTaskCreate((OS_TCB * )&ACTION_TaskTCB, //任务控制块
(CPU_CHAR * )"HW_TEST_Task", //任务名字
(OS_TASK_PTR )ACTION_TASK, //任务函数
(void * )0, //传递给任务函数的参数
(OS_PRIO )ACTION_TASK_PRIO, //任务优先级
(CPU_STK * )&ACTION_TASK_STK[0], //任务堆栈基地址
(CPU_STK_SIZE)ACTION_STK_SIZE/10, //任务堆栈深度限位
(CPU_STK_SIZE)ACTION_STK_SIZE, //任务堆栈大小
(OS_MSG_QTY )2, //任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
(OS_TICK )0, //当使能时间片轮转时的时间片长度,为0时为默认长度,
(void * )0, //用户补充的存储区
(OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项
(OS_ERR * )&err);
}
void ACTION_TASK(void *pdata)
{
initialize_actions(); // 初始化动作
run_actions();
}
// 定义计时器相关变量
OS_TMR timer_os_act; //act定时执行定时器 100ms 0.1s
void Timer_act_Callback(void *p_tmr, void *p_arg)
{
int i,j,k;
for(j = 0;j<ACT_NUM;j++) //动作组编号j
{
if(act_ctrl_st[j].executed == 1 && act_ctrl_st[j].pause == 0)
{
for(i = 0;i < act_ctrl_st[j].action_sum;i++)
{
if(action_set_1[i].start_time == act_ctrl_st[j].time_tick)
{
execute_action(&action_set_1[i]); // 执行动作
}
}
act_ctrl_st[j].time_tick++;
}
}
}
//以定时器形式执行
void start_action_timer(OS_ERR *err)
{
// OS_ERR err;
initialize_actions(); // 初始化动作
//转阀定时器
OSTmrCreate(&timer_os_act,
"act",
1,
100/10,
OS_OPT_TMR_PERIODIC,
(OS_TMR_CALLBACK_PTR)Timer_act_Callback,
0,
err);
if(timer_os_act.State != OS_TMR_STATE_RUNNING)
OSTmrStart(&timer_os_act,err);
}
//自定义函数
//动作结束函数
static void custom_action_over(int num,float val) {
act_ctrl_st[num].executed = 0;
act_ctrl_st[num].time_tick = 0;
act_ctrl_st[num].stop = 0;
act_ctrl_st[num].pause = 0;
}
static void custom_action(int num,float val) {
// HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); // 举例:切换某个引脚状态
;
}
static void execute_action(Action *action) {
switch (action->action_type) {
case SWITCH_ON:
set_switch_output_state(action->num,1);
break;
case SWITCH_OFF:
set_switch_output_state(action->num,0);
break;
case ANALOG_OUTPUT:
// 模拟量输出逻辑
Set_DAC_Value(action->num,action->val);
break;
case CUSTOM_FUNCTION:
if (action->func) {
action->func(action->num,action->val); // 执行自定义函数
}
break;
}
}
//typedef enum {
// SWITCH_ON, 参数1 操作的开关量编号
// SWITCH_OFF, 参数1 操作的开关量编号
// ANALOG_OUTPUT, 参数1 操作的DAC编号,参数2 DAC输出的电压值
// CUSTOM_FUNCTION 执行自定义函数 参数1 整形 参数2浮点型。
//} ActionType;
// action_set_1[index++] = (Action){0, SWITCH_ON, 0, 0.0f, NULL };
// action_set_1[index++] = (Action){0, SWITCH_OFF, 0, 0.0f, NULL };
// action_set_1[index++] = (Action){0, SWITCH_OFF, 0, 0.0f, NULL };
// action_set_1[index++] = (Action){0, SWITCH_OFF, 0, 0.0f, NULL };
// action_set_1[index++] = (Action){50, SWITCH_OFF, 0, 0.0f, NULL };
// //5
// action_set_1[index++] = (Action){50, SWITCH_OFF, 0, 0.0f, NULL };
// action_set_1[index++] = (Action){50, SWITCH_OFF, 0, 0.0f, NULL };
// action_set_1[index++] = (Action){50, SWITCH_OFF, 0, 0.0f, NULL };
// action_set_1[index++] = (Action){50, SWITCH_OFF, 0, 0.0f, NULL };
// action_set_1[index++] = (Action){50, SWITCH_OFF, 0, 0.0f, NULL };
// //10
static void initialize_actions() {
int index = 0;
// 初始化动作集合 t*100ms
/*动作组1*/
action_set_1[index++] = (Action){0, SWITCH_ON, 10, 0.0f, NULL };
action_set_1[index++] = (Action){0, SWITCH_OFF, 11, 0.0f, NULL };
action_set_1[index++] = (Action){0, SWITCH_ON, 12, 0.0f, NULL };
action_set_1[index++] = (Action){0, SWITCH_OFF, 13, 0.0f, NULL };
action_set_1[index++] = (Action){51, SWITCH_ON, 10, 0.0f, NULL };
//5
action_set_1[index++] = (Action){51, SWITCH_OFF, 11, 0.0f, NULL };
action_set_1[index++] = (Action){51, SWITCH_ON, 12, 0.0f, NULL };
action_set_1[index++] = (Action){52, SWITCH_OFF, 13, 0.0f, NULL };
action_set_1[index++] = (Action){52, SWITCH_ON, 14, 0.0f, NULL };
action_set_1[index++] = (Action){52, SWITCH_OFF, 15, 0.0f, NULL };
//10
action_set_1[index++] = (Action){53, SWITCH_OFF, 10, 0.0f, NULL };
action_set_1[index++] = (Action){53, SWITCH_ON, 11, 0.0f, NULL };
action_set_1[index++] = (Action){54, SWITCH_OFF, 12, 0.0f, NULL };
action_set_1[index++] = (Action){54, SWITCH_ON, 13, 0.0f, NULL };
action_set_1[index++] = (Action){55, SWITCH_OFF, 10, 0.0f, NULL };
//15
action_set_1[index++] = (Action){55, SWITCH_OFF, 11, 0.0f, NULL };
action_set_1[index++] = (Action){56, SWITCH_ON, 12, 0.0f, NULL };
//最后一句执行结束函数
action_set_1[index++] = (Action){56, CUSTOM_FUNCTION, 0, 0.0f, custom_action_over};
act_ctrl_st[0].action_sum = 18; //要和实际数量一致,注意动作组数量定义
/*动作组2*/
action_set_2[0] = (Action){30, ANALOG_OUTPUT, 75, 150.75f, NULL };
act_ctrl_st[1].action_sum = 2;
/*动作组3*/
action_set_3[0] = (Action){10, CUSTOM_FUNCTION, 0, 0.0f, custom_action};
act_ctrl_st[2].action_sum = 2;
/*动作组4*/
action_set_4[0] = (Action){40, SWITCH_ON, 0, 0.0f, NULL };
action_set_4[1] = (Action){70, SWITCH_OFF, 0, 0.0f, NULL };
act_ctrl_st[3].action_sum = 2;
}
static void run_actions() {
OS_ERR err;
uint32_t time_tick[4] = {0};
int i,j,k;
while (1) {
for(j = 0;j<ACT_NUM;j++) //动作组编号j
if(act_ctrl_st[j].executed == 1 && act_ctrl_st[j].pause == 0)
for(i = 0;i < act_ctrl_st[j].action_sum;i++)
{
if(action_set_1[i].start_time == act_ctrl_st[j].time_tick)
{
execute_action(&action_set_1[i]); // 执行动作
act_ctrl_st[j].time_tick++;
}
}
OSTimeDlyHMSM(0, 0, 0, 100,OS_OPT_TIME_HMSM_NON_STRICT,&err); // 每100毫秒遍历一次
// // 遍历第一个动作集合
// if(executed[0] == 1 && pause[0] == 0)
// for (action_index[0] = 0; action_index[0] < action_counts[0]; action_index[0]++) {
// if (action_set_1[action_index[0]].start_time == time_tick[0]) {
// execute_action(&action_set_1[action_index[0]]); // 执行动作
// }
// }
// time_tick[0]++;
//
// // 遍历第二个动作集合
// if(executed[1] == 1 && pause[1] == 0)
// for (action_index[1] = 0; action_index[1] < action_counts[1]; action_index[1]++) {
// if (action_set_2[action_index[1]].start_time == time_tick[1]) {
// execute_action(&action_set_2[action_index[1]]); // 执行动作
// }
// }
// time_tick[1]++;
//
// // 遍历第三个动作集合
// if(executed[2] == 1 && pause[2] == 0)
// for (action_index[2] = 0; action_index[2] < action_counts[2]; action_index[2]++) {
// if (action_set_3[action_index[2]].start_time == time_tick[2]) {
// execute_action(&action_set_3[action_index[2]]); // 执行动作
// }
// }
// time_tick[2]++;
//
// // 遍历第四个动作集合
// if(executed[3] == 1 && pause[3] == 0)
// for (action_index[3] = 0; action_index[3] < action_counts[3]; action_index[3]++) {
// if (action_set_4[action_index[3]].start_time == time_tick[3]) {
// execute_action(&action_set_4[action_index[3]]); // 执行动作
// }
// }
// time_tick[3]++;
}
}
//void action_start(int action_num)
//{
// executed[action_num] = 1;
//}
void action_pause(int action_num)
{
act_ctrl_st[action_num].executed = 1;
act_ctrl_st[action_num].stop = 0;
act_ctrl_st[action_num].pause = 1;
// action_index[action_num] = 0;
}
void action_continue(int action_num)
{
if(act_ctrl_st[action_num].pause == 1)
{
act_ctrl_st[action_num].executed = 1;
act_ctrl_st[action_num].pause = 0;
act_ctrl_st[action_num].stop = 0;
}
}
void action_stop(int action_num)
{
act_ctrl_st[action_num].executed = 0;
act_ctrl_st[action_num].stop = 1;
act_ctrl_st[action_num].pause = 0;
act_ctrl_st[action_num].time_tick = 0; //从头开始
}
void action_executed(int action_num)
{
act_ctrl_st[action_num].executed = 1;
act_ctrl_st[action_num].stop = 0;
act_ctrl_st[action_num].pause = 0;
}
#ifndef ACTION_H
#define ACTION_H
#include <stdint.h>
#include <stdbool.h>
#include "os.h" // uC/OS-III 头文件
typedef enum {
SWITCH_ON,
SWITCH_OFF,
ANALOG_OUTPUT,
CUSTOM_FUNCTION
} ActionType;
typedef struct Action {
uint32_t start_time; // 动作开始执行的时间(以100毫秒为单位)
ActionType action_type; // 动作类型
int num; // 动作值1
float val; // 动作值2
void (*func)(int num,float val); // 执行函数指针,参数1为动组作编号
} Action;
typedef struct Action_c {
uint8_t stop;
uint8_t pause;
uint8_t executed;
int action_index;
int action_sum;
int time_tick;
} Action_ctrl;
//任务函数
//氢火焰信号测试任务
void ACTION_TASK(void *pdata);
// 函数声明
static void execute_action( Action *action);
static void initialize_actions();
static void run_actions();
static void custom_action(int num,float val);
void start_action_task();
//以定时器形式执行
void start_action_timer(OS_ERR *err);
void action_pause(int action_num);
void action_continue(int action_num);
void action_stop(int action_num);
void action_executed(int action_num);
#endif // ACTION_H