- 芯科科技(Silicon labs)的Gecko系列芯片内部ADC集成有内部参考电压和温度传感器,温度精度很低,误差超过±3摄氏度,优点就是在精度要求不高的Z-Wave/Zigbee系统中提供了一个免费的温度传感器
ADC读取芯片内部温度传感器的方法
static void AdcSetup(void)
{
// Enable ADC clock
CMU_ClockEnable(cmuClock_ADC0, true);
ADC_Init_TypeDef init = ADC_INIT_DEFAULT;
ADC_InitSingle_TypeDef sInit = ADC_INITSINGLE_DEFAULT;
init.timebase = ADC_TimebaseCalc(0);
init.prescale = ADC_PrescaleCalc(400000, 0);
ADC_Init(ADC0, &init);
//Set input to temperature sensor. Reference must be 1.25V
sInit.reference = adcRef1V25;
sInit.acqTime = adcAcqTime8; /* Minimum time for temperature sensor */
sInit.posSel = adcPosSelTEMP;
ADC_InitSingle(ADC0, &sInit);
}
static uint32_t AdcRead(void)
{
ADC_Start(ADC0, adcStartSingle);
while ( (ADC0->STATUS & ADC_STATUS_SINGLEDV) == 0 )
{ }
return ADC_DataSingleGet(ADC0);
}
static float ConvertToCelsius(int32_t adcSample)
{
uint32_t calTemp0;
uint32_t calValue0;
int32_t readDiff;
float temp;
//Factory calibration temperature from device information page.
calTemp0 = ((DEVINFO->CAL & _DEVINFO_CAL_TEMP_MASK) >> _DEVINFO_CAL_TEMP_SHIFT);
calValue0 = ((DEVINFO->ADC0CAL3 /* _DEVINFO_ADC0CAL3_TEMPREAD1V25_MASK is not correct in current CMSIS. This is a 12-bit value, not 16-bit. */ & 0xFFF0) >> _DEVINFO_ADC0CAL3_TEMPREAD1V25_SHIFT);
if ((calTemp0 == 0xFF) || (calValue0 == 0xFFF))
{
//The temperature sensor is not calibrated
return -100.0;
}
//Vref = 1250mV TGRAD_ADCTH = 1.84 mV/degC (from datasheet)
readDiff = calValue0 - adcSample;
temp = ((float)readDiff * 1250);
temp /= (4096 * -1.84);
//Calculate offset from calibration temperature
temp = (float)calTemp0 - temp;
return temp * 100;
}
void customWriteAttributeEventHandler()
{
int32_t sample = 0;
int16_t temp = 0;
emberEventControlSetInactive(customWriteAttributeEventData);
sample = AdcRead();
temp = ConvertToCelsius(sample);
emberAfCorePrintln("sample=%d", sample);
emberAfCorePrintln("temp=%d", temp);
emberAfWriteServerAttribute(1, ZCL_TEMP_MEASUREMENT_CLUSTER_ID, ZCL_TEMP_MEASURED_VALUE_ATTRIBUTE_ID, &temp, ZCL_INT16S_ATTRIBUTE_TYPE);
emberEventControlSetDelayMS(customWriteAttributeEventData, 30000);
}
- 使用热敏电阻或电阻型温度传感器通过ADC读取温度
直接读出ADC值,根据热敏电阻的温度缺陷解析出相应的温度就可以了
void readTemperatureFromThermistor()
{
float tempValue = 0;
delayUs(100);
externalTemperatureValue = p_aux_MeasureAD(CDRAUX_MUXINPUT_DCIN1, CDRAUX_SAMP_WND_12);
temperatureValue =CaculateTrueTemp(externalTemperatureValue);
}
- 使用温度传感器,或温湿度传感器读取温度
大部分传感器都是使用I2C总线通信,也有一些采用单总线方式例如:广州奥松的DHT11
广州奥松电子国内知名的温湿度传感器厂家
敏源传感科技
SENSIRION–SHTC3,SHT3X
TI的HDC1080,TMP75C等,
RENESAS的MVH3004D
单总线应用电路
单总线读取温度数据
void dht_Rst(void)
{
dht_IO_OUT();
dht_data_OUT_0;
nrf_delay_ms(25);
dht_data_OUT_1;
dht_data_OUT_1;
nrf_delay_us(30);
}
u8 dht_Check(void)
{
u8 time=0;
dht_IO_IN();//SET INPUT
while (dht_data_IN&&time<100)
{
time++;
nrf_delay_us(1);
}
if(time>=100)
{
printf("error\r\n");
return 1;
}
else time=0;
while (!dht_data_IN&&time<100)
{
time++;
nrf_delay_us(1);
}
if(time>=100)
{
printf("error 2\r\n");
return 1;
}
return 0;
}
u8 dht_Read_Bit(void)
{
u8 time=0;
while(dht_data_IN&&time<100)
{
time++;
nrf_delay_us(1);
}
time=0;
while(!dht_data_IN&&time<100)
{
time++;
nrf_delay_us(1);
}
nrf_delay_us(40);
if(dht_data_IN)return 1;
else return 0;
}
u8 dht_Read_Byte(void)
{
u8 i,dat;
dat=0;
for (i=0;i<8;i++)
{
dat<<=1;
dat|=dht_Read_Bit();
}
return dat;
}
u8 dht_Read_Data(u8 *temp,u8 *humi)
{
u8 dat[5];
u8 i;
dht_Rst();
if(dht_Check()==0)
{
for(i=0;i<5;i++)
{
dat[i]=dht_Read_Byte();
}
if((dat[0]+dat[1]+dat[2]+dat[3])==dat[4])
{
*humi=dat[0];
*temp=dat[2];
}
}
else
{
return 1;
}
return 0;
}
u8 dht_Init(void)
{
dht_Rst();
return dht_Check();
}