You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
incubator_embeded/myfreertos/myfreertos.c

430 lines
14 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "myfreertos.h"
char pubTopic[512] = "/sys/hp8oQhMZJ67/Device1/thing/event/property/post"; // 发布的主题
char subTopic[512] = "/sys/hp8oQhMZJ67/Device1/thing/service/property/set"; // 订阅的主题
#define MQTT_SOCK 5
// 任务优先级
#define START_TASK_PRIO 0
// 任务堆栈大小
#define START_STK_SIZE 128
// 任务句柄
TaskHandle_t StartTask_Handler;
// 任务函数
void start_task(void *pvParameters);
// 任务优先级
#define Sensor_Communication_TASK_PRIO 1 // 与传感器通信
// 任务堆栈大小
#define Sensor_Communication_STK_SIZE 512
// 任务句柄
TaskHandle_t Sensor_CommunicationTask_Handler;
// 任务函数
void Sensor_Communication_task(void *pvParameters);
void Host_Computer_Communication(void);
int isZeros(u8 arr[]);
u8 RS485_RX_BUF_COPY[128] = {0};
u8 cnt_flag = 0, sub_flag = 0, pub_flag = 0;
u16 time = 0; // 记录ping服务器的时间
char wet_temp[256]; // 订阅与发布消息的缓存区
u8 store_stage = 1; // 写入flash的阶段号断电重启后读取可以紧接着上次的阶段运行
extern PID pid;
extern float kd;
extern float ki;
u8 batch_sync_buf[11]; // 单个同步剪切得到的数组
u8 ins_1 = 0;
int diff = 0;
u8 gpio_state = 0x00; // 继电器状态
u8 NUM = 1; // 批量同步发送的阶段号
u8 n; // 阶段号
u16 i; // 序列号
u8 chour; // 已运行小时数
u8 cminute; // 运行分钟数
u8 hot_clod_flag = 0; // 加热制冷标志位。hot_clod_flag=0, 不加热不制冷hot_clod_flag=2,加热hot_clod_flag=1,制冷
u8 humidity_flag = 0; // 加湿除湿标志位。 humidity_flag=0不加湿不除湿 humidity_flag=2,加湿; humidity_flag=1除湿
u8 ALARM = 0; // 报警标志位。ALARM=0,不报警ALARM=1,报警
u16 tick = 0; // tick大于600触发报警条件会报警小于600则不报警。
u8 Feed_Dog_Count = 0; // 喂狗计时
u8 now_stage = 1; // 当前运行阶段
u16 tem, hum, red, blue, white;
u8 hour, min;
u8 change_stage_rev1 = 0;
u8 change_stage_rev2 = 0;
u8 change_stage_rev3 = 0;
u8 rs485buf[8] = {0x01, 0x03, 0x00, 0x01, 0x00, 0x09, 0xD4, 0x0C}; // 传感器交换数据
int T = 0, H = 0, C = 0, G = 0, current_T = 0;
extern u8 total[];
float Humidity = 0;
float temperature = 0;
// u8 RS485_RX_BUF[64];
/*********************
**********************
入口函数
**********************
*********************/
void os_init(void)
{
// printf("入口函数调用成功\r\n");
xTaskCreate((TaskFunction_t)start_task,
(char *)"start_task",
(uint16_t)START_STK_SIZE,
(void *)NULL,
(UBaseType_t)START_TASK_PRIO,
(TaskHandle_t *)&StartTask_Handler);
vTaskStartScheduler();
}
/*********************
**********************
创建 任务,队列,信号集等句柄,也可以测试用
**********************
*********************/
BaseType_t handler = 0;
BaseType_t handler1 = 0;
BaseType_t handler2 = 0;
BaseType_t handler3 = 0;
BaseType_t handler4 = 0;
BaseType_t handler5 = 0;
BaseType_t handler6 = 0;
BaseType_t handler7 = 0;
BaseType_t handler8 = 0;
BaseType_t handler9 = 0;
BaseType_t handler10 = 0;
BaseType_t handler11 = 0;
/*
开始函数:创建其他函数与定时器
*/
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); // 进入临界区
// 创建与传感器通信任务
handler = xTaskCreate((TaskFunction_t)Sensor_Communication_task,
(const char *)"Sensor_Communication_task",
(uint16_t)Sensor_Communication_STK_SIZE,
(void *)NULL,
(UBaseType_t)Sensor_Communication_TASK_PRIO,
(TaskHandle_t *)&Sensor_CommunicationTask_Handler);
// if(handler==pdPASS){printf("与传感器通信任务创建成功\r\n");}
// else{printf("与传感器通信任务创建失败\r\n");}
// //创建控灯任务
// handler4=xTaskCreate((TaskFunction_t )led_task,
// (const char* )"led_task",
// (uint16_t )LED_STK_SIZE,
// (void* )NULL,
// (UBaseType_t )LED_TASK_PRIO,
// (TaskHandle_t* )&LEDTask_Handler);
// if(handler4==pdPASS){printf("控灯任务创建成功\r\n");}
// else{printf("控灯任务创建失败\r\n");}
vTaskDelete(StartTask_Handler); // 删除开始任务
taskEXIT_CRITICAL(); // 退出临界区
}
void Sensor_Communication_task(void *pvParameters)
{
while (1)
{
// cnt_flag=do_mqtt(MQTT_SOCK,NET_CONFIG.rip,1883,5500);
// Humidity=H*0.1;
// temperature=T*0.1;
// delay_ms(50);
// sprintf(wet_temp,"{\"method\":\"thing.event.property.post\",\"params\":{\"Humidity\":%.2f,\"temperature\":%.2f,\"CO2\":%d,\"red_light\":%d,\"white_light\":%d,\"blue_light\":%d},\"version\":\"1.0.0\"}",Humidity,temperature,C,red/10,white/10,blue/10); //构建数据
// //sprintf(wet_temp,"{\"method\":\"thing.event.property.post\",\"params\":{\"Humidity\":%.2f,\"temperature\":%.2f,\"CO2\":%d},\"version\":\"1.0.0\"}",Humidity,temperature,C); //构建数据
// if(cnt_flag==0){sub_flag=0;pub_flag=0;time=0;}
// if(cnt_flag&&sub_flag==0)sub_flag=!subscribMqtt(MQTT_SOCK,subTopic);
// if(cnt_flag&&sub_flag&&pub_flag==0)pub_flag=!publishMqtt(MQTT_SOCK,pubTopic,wet_temp);
// if(cnt_flag)time++;
// if(time==50){
// time=0;
// pingMqtt(MQTT_SOCK);
// }
now_stage = timelong_Compare(); //
// printf("%d %d\r\n",chour,cminute);
Array(&now_stage, &hour, &min, &tem, &hum, &red, &blue, &white); // 更新对应阶段号的参数
// printf("current stage: %d\r\n",now_stage);
RS485_1_Send_Data_1(rs485buf, 8); //(RS485_RX_CNT=0已被注释)
// printf("send finish\r\n");
delay_xms(200);
// RX_BUF_Printf(128);
RS485_1_Send_Data_3();
delay_xms(200);
// RX_BUF_Printf(128);
bufcut_Init(RS485_RX_BUF_COPY, RS485_RX_BUF, 0, 128);
RS485_RX_CNT = 0;
while ((isAllZeros(RS485_RX_BUF_COPY, 128) == 0))
// while(!(RS485_RX_BUF[0]==0x00 && RS485_RX_BUF[1]==0x00&&RS485_RX_BUF[2]==0x00 && RS485_RX_BUF[3]==0x00))
{
// printf("enter while\r\n");
if (RS485_RX_BUF_COPY[0] == 0x01 && RS485_RX_BUF_COPY[1] == 0x03) // 判断是否校验成功
{
// -21
// RS485_RX_BUF_COPY[3] = 0xFF;
// RS485_RX_BUF_COPY[4] = 0xB1;
T = RS485_RX_BUF_COPY[3];
T = T << 8 | RS485_RX_BUF_COPY[4];
// 支持负数温度
if (T & 0x8000) {
T = ((~T + 1) & 0xFFFF);
}
H = RS485_RX_BUF_COPY[5];
H = H << 8 | RS485_RX_BUF_COPY[6];
C = RS485_RX_BUF_COPY[19];
C = C << 8 | RS485_RX_BUF_COPY[20];
// printf("now_tem=%d.%d℃,now_hum=%d.%d%% ,co2=%d\r\n",T/10,T%10,H/10,H%10,C);
/*GPIO1->报警铃 GPIO6->压缩机 GPIO3->加热棒 GPIO4—>新风风扇 GPIO5->加湿器 */
if ((T < (tem - 20) || T > (tem + 20) || H < (hum - 100) || H > (hum + 100)) && (tick > 610)) // 温度偏差2℃报警湿度偏差10报警
{
HC595_Send_Byte(gpio_state |= 0x01); // 打开报警铃 GPIO1->PB1 |=0000 0001 0x01
ALARM = 1;
}
else
{
HC595_Send_Byte(gpio_state &= 0xFE); // 关闭报警铃 &=1111 1110 0xFE
ALARM = 0;
}
if (T < 600 && T > -400)
{
diff = current_T - T;
if (diff < 0)
diff = -diff;
if (diff < 3 || current_T == 0) // 最近两次温差相差0.3℃,消除传感器感应出错的影响
{
pid.set_tem = tem / 10.0;
pid.now_tem = T / 10.0;
PID_Calc();
// num=(((pid.OUT*400)/pid.pwmcycle)-1);//请问这个pid.OUT与pwm占空比的值是如何换算过来的
// TIM_SetCompare3(TIM3,num);
// TIM_SetCompare3(TIM3,0.845*num);
// printf("%d\r\n",num);
// 0-200对应0-100%如果pid.out=50,占空比就是25%//num=50*400/200=100100/400=25%
// printf("%d ,%d ,%d ,%d ,%f ,%f ,%f ,%f ,%f ,%f ,%f ,%.3f\r\n",T,H,C,num,(pid.set_tem*10),pid.Kp,ki,kd,pid.Pout,pid.Iout,pid.Dout,num/399.0);
current_T = T;
}
}
if (H > (hum + 50)) // 湿度高于设定值5打开新风风扇 GPIO4->PD1
{
HC595_Send_Byte(gpio_state |= 0x08); // 打开新风风扇 |=0000 1000 0x08
HC595_Send_Byte(gpio_state &= 0xEF); // 关闭加湿器 &=1110 1111 0xEF
humidity_flag = 1; // 除湿
}
if (H < (hum - 50)) // 湿度低于设定值5打开加湿器 GPIO5->PD0
{
HC595_Send_Byte(gpio_state |= 0x10); // 启动加湿器 |=0001 0000 0x10
HC595_Send_Byte(gpio_state &= 0xF7); // 关闭风扇 &=1111 0111 0xF7
humidity_flag = 2;
}
if (humidity_flag == 1 && H <= hum)
{
HC595_Send_Byte(gpio_state &= 0xE7); // 关闭风扇 关闭加湿器 &=1110 0111 0xE7
humidity_flag = 0;
}
if (humidity_flag == 2 && H >= hum)
{
HC595_Send_Byte(gpio_state &= 0xE7); // 关闭加湿器 关闭风扇 &=1110 0111 0xE7
humidity_flag = 0;
}
RS485_1_Send_Data_2(); // 上传参数
RX_BUF_Transfer(0, 23);
// RX_BUF_Printf(128);
}
else if (RS485_RX_BUF_COPY[0] == 0xEE && RS485_RX_BUF_COPY[1] == 0xB6 && RS485_RX_BUF_COPY[2] == 0x03)
{
Analysis(&n, &i, RS485_RX_BUF_COPY);
// printf("B6 03 cmd: batch sync\r\n");
Array(&now_stage, &hour, &min, &tem, &hum, &red, &blue, &white); // 更新对应阶段号的参数
Write_Init();
RX_BUF_Transfer(0, 11);
// printf("batch sync over\r\n");
// RX_BUF_Printf(128);
}
else if (RS485_RX_BUF_COPY[0] == 0xEE && RS485_RX_BUF_COPY[1] == 0xB6 && RS485_RX_BUF_COPY[2] == 0x04)
{
change_stage_rev1 = RS485_RX_BUF_COPY[3];
// printf("B6 04 cmd: change stage\r\n");
RTC_synchronization_ins(2023, 9, 1, 0, 00, 00);
now_stage = change_stage_rev1;
store_stage = change_stage_rev1;
Write_Init();
RX_BUF_Transfer(0, 8);
// printf("change stage over\r\n");
// RX_BUF_Printf(128);
}
else if (RS485_RX_BUF_COPY[0] == 0xEE && RS485_RX_BUF_COPY[1] == 0xB6 && RS485_RX_BUF_COPY[2] == 0x01)
{
Batch_synchronization(&n, RS485_RX_BUF_COPY);
// printf("B6 01 cmd: get one %d\r\n", n);
Array(&now_stage, &hour, &min, &tem, &hum, &red, &blue, &white); // 更新对应阶段号的参数
// Write_Init();减少擦写的次数
// printf("get one over\r\n");
RX_BUF_Transfer(0, 20);
// RX_BUF_Printf(128);
}
else if (RS485_RX_BUF_COPY[0] == 0xEE && RS485_RX_BUF_COPY[1] == 0xB1 && RS485_RX_BUF_COPY[2] == 0x11 && RS485_RX_BUF_COPY[15] == 0xFF && RS485_RX_BUF[16] == 0xFF)
{
// printf("cut overdata of B6 03 \r\n");
RX_BUF_Transfer(0, 17);
}
else if (RS485_RX_BUF_COPY[0] == 0xEE && RS485_RX_BUF_COPY[1] == 0xB1 && RS485_RX_BUF_COPY[2] == 0x11 && RS485_RX_BUF_COPY[14] == 0xFF && RS485_RX_BUF[15] == 0xFF)
{
// printf("cut overdata of B6 03 \r\n");
// RX_BUF_Printf(128);
RX_BUF_Transfer(0, 16);
// RX_BUF_Printf(128);
}
else if (RS485_RX_BUF_COPY[0] == 0xEE && RS485_RX_BUF_COPY[1] == 0xB1 && RS485_RX_BUF_COPY[2] == 0x11 && RS485_RX_BUF_COPY[12] == 0xFF && RS485_RX_BUF[13] == 0xFF)
{
// printf("cut overdata of B6 04 \r\n");
// RX_BUF_Printf(128);
RX_BUF_Transfer(0, 14);
}
else if (RS485_RX_BUF_COPY[0] == 0xEE && RS485_RX_BUF_COPY[1] == 0xB1 && RS485_RX_BUF_COPY[2] == 0x01 && RS485_RX_BUF_COPY[7] == 0xFF && RS485_RX_BUF_COPY[8] == 0xFF)
{
// printf("cut overdata of Upper computer \r\n");
// RX_BUF_Printf(128);
RX_BUF_Transfer(0, 9);
// RX_BUF_Printf(128);
}
else
{
int ZERO_Count = 0;
// if()与while()的顺序不能变
if ((RS485_RX_BUF_COPY[0] != 0x00)) // 不为0处理掉
{
RX_BUF_Transfer(0, 1);
}
while (RS485_RX_BUF_COPY[ZERO_Count] == 0x00)
{
ZERO_Count++;
}
RX_BUF_Transfer(0, ZERO_Count);
// printf("previous array cut\r\n");
// RX_BUF_Printf(128);
}
// HC595_Send_Byte(0x00);
}
// printf("%d,%d,%d\r\n",T,H,C);
// printf("current params: %d:%d,hot or cold flag:%d, humidity flag:%d, alarm: %d\r\n",chour, cminute, hot_clod_flag, humidity_flag, ALARM);
// printf("led!!!\r\n");
if (red <= 1000 && blue <= 1000)
{
PWM_SetCompare1((red / 100.0 * 3.5 + 28)); // J9
PWM_SetCompare2((blue / 100.0 * 3.5 + 28)); // J11
PWM_SetCompare4((white / 100.0 * 3.5 + 28)); // J10
// printf("red=%d\r\n",red);
// printf("bule=%d\r\n",blue);
}
RS485_RX_CNT = 0;
// printf("end data to serial monitor end");
}
}
// void Host_Computer_Communication(void)
//{
// if(RS485_RX_BUF_COPY[0]==0xEE&&RS485_RX_BUF_COPY[1]==0xB6)
// {
// if(RS485_RX_BUF_COPY[2]==0x03)//单个同步
// {
// Analysis(&n,&i,RS485_RX_BUF_COPY);
// //printf("B6 03 cmd: batch sync\r\n");
// Array(&now_stage,&hour,&min,&tem,&hum,&red,&blue,&white);//更新对应阶段号的参数
// Write_Init();
// RX_BUF_Transfer(0,11);
//
// }
// if(RS485_RX_BUF_COPY[2]==0x04)//阶段切换
// {
// change_stage_rev1=RS485_RX_BUF_COPY[3];
// //printf("B6 04 cmd: change stage\r\n");
// RTC_synchronization_ins(2023,9,1,0,00,00);
// now_stage=change_stage_rev1;
// store_stage=change_stage_rev1;
// Write_Init();
// RX_BUF_Transfer(0,8);
// }
// if(RS485_RX_BUF_COPY[2]==0x01)//批量同步
// {
// Batch_synchronization(&n,RS485_RX_BUF_COPY);
// //printf("B6 01 cmd: get one %d\r\n", n);
// Array(&now_stage,&hour,&min,&tem,&hum,&red,&blue,&white);//更新对应阶段号的参数
// //Write_Init();减少擦写的次数
// RX_BUF_Transfer(0,20);
// }
// }
// else if(RS485_RX_BUF_COPY[0]==0xEE&&RS485_RX_BUF_COPY[1]==0xB1)
// {
// if(RS485_RX_BUF_COPY[2]==0x11&&RS485_RX_BUF_COPY[15]==0xFF&&RS485_RX_BUF[16]==0xFF)//单个同步默认带的数据
// {
// //printf("cut overdata of B6 03 \r\n");
// RX_BUF_Transfer(0,17);
// }
// if(RS485_RX_BUF_COPY[2]==0x11&&RS485_RX_BUF_COPY[14]==0xFF&&RS485_RX_BUF[15]==0xFF)//单个同步默认带的数据
// {
// //printf("cut overdata of B6 03 \r\n");
// //RX_BUF_Printf(128);
// RX_BUF_Transfer(0,16);
// //RX_BUF_Printf(128);
// }
// if(RS485_RX_BUF_COPY[2]==0x11&&RS485_RX_BUF_COPY[12]==0xFF&&RS485_RX_BUF_COPY[13]==0xFF)//阶段切换默认带的数据
// {
// //printf("cut overdata of B6 04 \r\n");
// //RX_BUF_Printf(128);
// RX_BUF_Transfer(0,14);
// }
// if(RS485_RX_BUF_COPY[2]==0x01&&RS485_RX_BUF_COPY[7]==0xFF&&RS485_RX_BUF_COPY[8]==0xFF)//上位机默认带的数据
// {
// //printf("cut overdata of Upper computer \r\n");
// //RX_BUF_Printf(128);
// RX_BUF_Transfer(0,9);
// //RX_BUF_Printf(128);
//
// }
// }
// else
// {
// //int ZERO_Count=0;
// //if()与while()的顺序不能变
//// if((RS485_RX_BUF_COPY[0]!=0x00))//不为0处理掉
//// {
//// RX_BUF_Transfer(0,1);
//// //printf("the number is no zero\r\n");
//// }
////
//// while(RS485_RX_BUF_COPY[ZERO_Count]==0x00)
//// {
//// ZERO_Count++;
//// }
//// RX_BUF_Transfer(0,ZERO_Count);
//
// RX_BUF_Transfer(0,1);
// //printf("previous array cut\r\n");
// }
//}