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

412 lines
13 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"; // Publish topic
char subTopic[512] = "/sys/hp8oQhMZJ67/Device1/thing/service/property/set"; // Subscribe topic
#define MQTT_SOCK 5
// task priority
#define START_TASK_PRIO 0
// Task stack size
#define START_STK_SIZE 128
// task handle
TaskHandle_t StartTask_Handler;
// task function
void start_task(void *pvParameters);
// task priority
#define Sensor_Communication_TASK_PRIO 1 // Communication with sensors
// Task stack size
#define Sensor_Communication_STK_SIZE 512
// task handle
TaskHandle_t Sensor_CommunicationTask_Handler;
// task function
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; // Record the time of pinging the server
char wet_temp[256]; // Cache area for subscription and publication of messages
u8 store_stage = 1; // Write the stage number of the flash, and after a power outage and restart, it can run immediately following the previous stage and status
extern PID pid;
extern float kd;
extern float ki;
u8 batch_sync_buf[11]; // Array obtained by single synchronous cutting
u8 ins_1 = 0;
int diff = 0;
u8 gpio_state = 0x00; // relay status
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; // Feeding dog timing
u8 now_stage = 1; // Current operational phase
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] = {0x02, 0x03, 0x00, 0x01, 0x00, 0x09, 0xD4, 0x3F}; // Sensor exchange data
u16 sync_cnt = 0; // 同步环境控制参数的计数器到0同步
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];
/*********************
**********************
entry function
**********************
*********************/
void os_init(void)
{
// printf("Entry function call successful\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();
}
/*********************
**********************
Create handles for tasks, queues, signal sets, etc., which can also be tested using
**********************
*********************/
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;
/*
Start function: Create other functions and timers
*/
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);
if (sync_cnt <= 0)
{
RS485_1_Send_Data_3();
sync_cnt = 600;
}
else
{
sync_cnt--;
}
delay_xms(200);
// RX_BUF_Printf(128);
bufcut_Init(RS485_RX_BUF_COPY, RS485_RX_BUF, 0, 128);
RS485_RX_CNT = 0;
// HC595_Send_Byte(0x00); // close all
while ((isAllZeros(RS485_RX_BUF_COPY, 128) == 0))
{
if (RS485_RX_BUF_COPY[0] == 0x02 && 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];
/*GPIO1->报警铃 GPIO3->加热棒 GPIO4—>新风风扇 GPIO5->加湿器 GPIO6->压缩机 */
if ((T < (tem - 20) || T > (tem + 20) || H < (hum - 100) || H > (hum + 100)) && (tick > 600)) // 温度偏差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();
// send sign to 485
// out: 0-200
// 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(); // 上传参数
delay_xms(200);
RX_BUF_Transfer(0, 23);
}
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);
Array(&now_stage, &hour, &min, &tem, &hum, &red, &blue, &white); // 更新对应阶段号的参数
Write_Init();
RX_BUF_Transfer(0, 11);
}
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];
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);
}
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);
Array(&now_stage, &hour, &min, &tem, &hum, &red, &blue, &white); // 更新对应阶段号的参数
RX_BUF_Transfer(0, 20);
}
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)
{
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)
{
RX_BUF_Transfer(0, 16);
}
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)
{
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)
{
RX_BUF_Transfer(0, 9);
}
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);
}
}
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
}
RS485_RX_CNT = 0;
}
}
// 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");
// }
//}