/********************温度传感器CT1820程序 Start*********************************/
void CT1820_GpioInit(void)
{
ithGpioSetMode(CT1820_GPIO, ITH_GPIO_MODE0);
ithGpioSet(CT1820_GPIO);
ithDelay(10);
printf("********************CT1820GpioInit\n");
}
uint8_t CT1820Init(void)
{
uint8_t i;
ithGpioSetOut(CT1820_GPIO);
ithGpioClear(CT1820_GPIO);
ithDelay(600);
ithGpioSetIn(CT1820_GPIO);
i = 0;
ithDelay(80);
if (ithGpioGet(CT1820_GPIO))
{
printf("\nCT1820Init failed!\n");
return 0; //初始化失败
}
ithDelay(250);
if (!ithGpioGet(CT1820_GPIO))
{
printf("\nCT1820Init failed!\n");
return 0; //初始化失败
}
// printf("\nCT1820Init successful!\n");
return 1;//初始化成功
}
void CT1820WriteByte(uint8_t dat)
{
uint8_t j;
for (j = 0; j < 8; j++)
{
ithGpioSetOut(CT1820_GPIO);
ithGpioClear(CT1820_GPIO);
ithDelay(8);
if (dat & 0x01)
{
ithGpioSet(CT1820_GPIO);
}
ithDelay(60);
ithGpioSetIn(CT1820_GPIO);//释放总线
// ithDelay(25);//如果CT1820没有接VCC,则由MCU释放总线后,由DI高电平给CT1820供电
dat >>= 1;
}
}
uint8_t CT1820ReadByte(void)
{
uint8_t byte;
uint32_t bit;
uint8_t i, j;
byte = 0;
for (j = 8; j > 0; j--)
{
ithGpioSetOut(CT1820_GPIO);
ithGpioClear(CT1820_GPIO);
ithDelay(5);
ithGpioSetIn(CT1820_GPIO);//释放总线
ithDelay(6);
bit = ithGpioGet(CT1820_GPIO);
bit >>= CT1820_GPIO;
bit &= 0x01;
// printf("\n CT1820ReadByte: bit = %x\n", bit);
byte = (byte >> 1) | (bit << 7);
ithDelay(50);
}
// printf("\n CT1820ReadByte: byte = %x\n", byte);
return byte;
}
int CT1820ChangeTemp(void)
{
taskENTER_CRITICAL();//关闭本地中断,禁止任务切换
if (!CT1820Init())
{
taskEXIT_CRITICAL();//重新打开本地中断
return 0;//失败
}
CT1820WriteByte(0xcc);
ithDelay(5);
CT1820WriteByte(0x44);
taskEXIT_CRITICAL();
//sleep(2);
usleep(300000);
return 1;
}
int CT1820ReadTempCom(void)
{
taskENTER_CRITICAL();
if (!CT1820Init())
{
taskEXIT_CRITICAL();
return 0;//失败
}
CT1820WriteByte(0xcc);
ithDelay(5);
CT1820WriteByte(0xbe);
taskEXIT_CRITICAL();
ithDelay(5);
return 1;
}
volatile int err_num = 0;
float CT1820ReadTemp(void)
{
int temp = 0;
float temp_val = 0;
uint8_t tmh, tml;
if (!CT1820ChangeTemp())
{
return 255.00;
}
if (!CT1820ReadTempCom())
{
return 255.00;
}
taskENTER_CRITICAL();
tml = CT1820ReadByte();
tmh = CT1820ReadByte();
taskEXIT_CRITICAL();
temp = tmh;
temp <<= 8;
temp |= tml;
// printf("\n CT1820ReadTemp:temp = 0x%x\n", temp);
if (temp > 0xF000)
{
temp = ~temp;
temp &= 0xFFFF;
temp++;
temp_val = -0.0625 *temp;
}
else
{
temp_val = 0.0625 *temp;
}
// printf("\n CT1820ReadTemp:temp_val = %f\n", temp_val);
/*过滤无效数据*/
if (temp_val > 80.00 || temp_val < -40.00) //如果测得的温度高于零上80度或低于零下40度,则认为是无效数据
{
err_num++;
printf("\n CT1820ReadTemp2:err_num = %d, succ_num = %d\n", err_num);
temp_val = 255.00;
}
// printf("\n CT1820ReadTemp:temperature = %f\n", temp_val);
return temp_val;
}
/*多次读取温度,取温度的平均值*/
float CH1820_Mul_Read_Temperature_Degree(unsigned int times)
{
float temp;
float temp_val = 0;
int re_times = 0;
// printf("\n CH1820_Mul_Read_Temperature_Degree \n");
for (int i = 0; i < times; i++)
{
usleep(1000000);
temp = 0;
temp = CT1820ReadTemp();
// printf("\n CH1820_Mul_Read_Temperature_Degree : temp = %f\n", temp);
if (temp >= 255.00)
{
i--;
re_times++;
if (re_times > 3)
{
temp_val = 255.00;
return temp_val;
}
}
else
{
temp_val += temp;
}
}
temp_val /= times;
printf("\n CH1820_Mul_Read_Temperature_Degree : temp_val = %f\n", temp_val);
return temp_val;
}
/********************温度传感器CT1820程序 End*********************************/
volatile float Temperature_value;//记录当前测量的温度
volatile float Temperature_max;//记录当天测量的最高温,用于每日最高温度提示
volatile float Temperature_min;//记录当天测量的最低温,用于每日最低温度提示
volatile float Temperature_max_pertime;//记录过去SECOND_PER_TIME时间内的最高温度,用于温度曲线显示
volatile float Temperature_min_pertime;//记录过去SECOND_PER_TIME时间内的最低温度,用于温度曲线显示
volatile float Temperature_max_mqttpertime;//记录mqtt每次上报服务器的最高温,即过去5分钟时间内的最高温度
volatile float Temperature_min_mqttpertime;//记录mqtt每次上报服务器的最低温,即过去5分钟时间内的最低温度
extern volatile int suspend_temperature_task;//值为1时暂停温度测量。因为温度测量时会频繁关闭本地中断,致使OTA下载文件老是失败。
void* Temperature_Task(void* arg)
{
float temp_val;
float temp_prev = 0;
int temp_i = 0;
int temp_prev_i = 0;
Command cmd;
cmd.id = CMD_SHOW_TEMP;
temp_val = 255.00;
Temperature_max = -255.00;
Temperature_min = 255.00;
Temperature_max_pertime = -255.00;
Temperature_min_pertime = 255.00;
Temperature_max_mqttpertime = -255.00;
Temperature_min_mqttpertime = 255.00;
printf("\n Temperature_Task\n");
while (1)
{
if (suspend_temperature_task)
{
sleep(10);
continue;
}
#ifdef CT1820
temp_val = CH1820_Mul_Read_Temperature_Degree(3);
#else
temp_val = CH1720_Mul_Read_Temperature_Degree(3);
#endif
if (temp_val >= 255.00)//读取数据错误,重新读取
{
continue;
}
Temperature_value = temp_val;
if (temp_val > Temperature_max)
{
Temperature_max = temp_val;
}
if (temp_val < Temperature_min)
{
Temperature_min = temp_val;
}
if (temp_val > Temperature_max_pertime)
{
Temperature_max_pertime = temp_val;
}
if (temp_val < Temperature_min_pertime)
{
Temperature_min_pertime = temp_val;
}
if (temp_val > Temperature_max_mqttpertime)
{
Temperature_max_mqttpertime = temp_val;
}
if (temp_val < Temperature_min_mqttpertime)
{
Temperature_min_mqttpertime = temp_val;
}
temp_i = temp_val*10;
temp_prev_i = temp_prev*10;
//if (temp_val != temp_prev)
if (temp_i != temp_prev_i)//这次读取的数据跟上次的不一样
{
cmd.temp = temp_val;
temp_prev = temp_val;
mq_send(commandQueue, (const char *)&cmd, sizeof(Command), 0);//通知主线程,温度发生改变
}
// printf("Temperature_Task:temp_val = %f\n", temp_val);
}
}
void CreateTemperatureTask(void)
{
static pthread_t TempTask;
#ifdef CT1820
CT1820_GpioInit();
#else
CT1720Init();
#endif
pthread_create(&TempTask, NULL, Temperature_Task, NULL);
#ifndef CT1820
sleep(2);
#endif
}