#define CT1720_GOIO 18
void CT1720Init(void)
{
ithGpioSetMode(CT1720_GOIO, ITH_GPIO_MODE0); //设置GPIO模式
ithGpioSet(CT1720_GOIO); //GPIO置高
ithDelay(10); //延时10us
printf("********************CT1720Init\n");
}
void CT1720_Start(void)
{
ithGpioSetOut(CT1720_GOIO); //设置GPIO为输出模式
ithGpioClear(CT1720_GOIO); //电平置低
ithDelay(500);
ithGpioSet(CT1720_GOIO); //电平置高,产生一个上升沿
usleep(50000); //睡眠延时50ms
}
unsigned char CT1720_Read_Bit(void) //从CT1720读一个bit的数据
{
unsigned int bit_val = 0;
ithGpioSetOut(CT1720_GOIO);
ithGpioClear(CT1720_GOIO);
ithDelay(1);
ithGpioSetIn(CT1720_GOIO);//IT976E 的GPIO设置为输入模式时,默认设置为高电平
ithDelay(20);
bit_val = ithGpioGet(CT1720_GOIO); //获取GPIO电平状态
// printf("**********CT1720_Read_Bit:1 bit_val = %x\n",bit_val);
if (bit_val & (1 << 18)) //1<<18是因为GPIO的引脚号为18,与ithGpioGet的返回值相关。
{
bit_val = 1;
}
else
{
bit_val = 0;
}
ithGpioSetIn(CT1720_GOIO);//GPIO设置为输入时,默认拉高电平
ithDelay(30);
//printf("**********CT1720_Read_Bit:2 bit_val = %x\n", bit_val);
return (bit_val&0x01);
}
unsigned char CH1720_Read_Byte(void)//从CT1720读取一个字节的数据
{
unsigned char Byte_val = 0;
for (int i = 0; i < 8; i++)
{
Byte_val <<= 1;
Byte_val |= CT1720_Read_Bit();
}
// printf("**********CH1720_Read_Byte: Byte_val = %x\n", Byte_val);
return Byte_val;
}
/*单次读取一次温度*/
float CH1720_Read_Temperature_Degree(void)
{
float Temp_Val;
int Temp = 0;
char Temp_Byte0 = 0;
char Temp_Byte1 = 0;
unsigned char Bit_CC0 = 0;
unsigned char Bit_CC1 = 0;
unsigned char Bit_Sign = 0;
CT1720_Start();
Bit_CC0 = CT1720_Read_Bit();
ithDelay(10);
Bit_CC1 = CT1720_Read_Bit();
ithDelay(10);
// printf("**********CH1720_Read_Temperature_Degree:Bit_CC0= %d,Bit_CC1= %d\n", Bit_CC0, Bit_CC1);
if (Bit_CC0 == 0 && Bit_CC1 == 0) //判断数据是否有效
{
Bit_Sign = CT1720_Read_Bit();
Temp_Byte0 = CH1720_Read_Byte();
ithDelay(10);
Temp_Byte1 = CH1720_Read_Byte();
ithDelay(10);
Temp = (Temp_Byte0 << 5) + (Temp_Byte1 >> 3);
// printf("************* 1: Temp = %x\n",Temp);
if (Bit_Sign == 0x01)
{
Temp = ~Temp;
Temp &= 0xFFFF;
Temp++;
Temp_Val = -3.125 *Temp / 100.00;
}
else
{
Temp_Val = 3.125 *Temp / 100.00;
}
/*过滤无效数据*/
if (Temp_Val > 40.00 || Temp_Val < -35.00) //如果测得的温度高于零上40度或低于零下35度,则认为是无效数据
{
Temp_Val = 255.00; //无效数据此处默认为255.00
}
}
else
{
Temp_Val = 255.00; //无效数据此处默认为255.00
}
// printf("************CH1720_Read_Temperature_Degree:Temp_Val = %f\n", Temp_Val);
return Temp_Val;
}
/*多次读取温度,取温度的平均值*/
float CH1720_Mul_Read_Temperature_Degree(unsigned int times)
{
float temp;
float temp_val = 0;
int re_times = 0;
for (int i = 0; i < times; i++)
{
usleep(1000000);
temp = 0;
temp = CH1720_Read_Temperature_Degree();
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;
return temp_val;
}
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分钟时间内的最低温度
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)
{
temp_val = CH1720_Mul_Read_Temperature_Degree(3);
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;
CT1720Init();
pthread_create(&TempTask, NULL, Temperature_Task, NULL);
sleep(2);//开机2秒后,开始温度测量
}