內部溫度傳感器+串口(UART2)+上位機軟件實現溫度監控
視頻:http://v.eepw.com.cn/video/play/id/1920
測溫度用了平均值濾波法,下面介紹幾種常用的軟件濾波方法
1.平均值濾波法:連繼讀到幾個數值,求平均數。
缺點:需要連續多次進行AD轉換,占用CPU資源
技巧:讀8次,和右移3位就得到平均值,可省去除法運算
2.移動平均值濾波法:建立一個數組記錄數據,每進行一次AD 轉換后,把最新數據移入數組,把最舊的數據移出數組。再求平均值
優點:節省CPU資源
3.去頭去尾求平均值:就像奧運比賽一樣,把最大最小的數據去除了,再求平均數。
優點:把最大最小值去掉了,結果將更精確
![](http://uphotos.eepw.com.cn/campozeng/pics/e20999e36ac7b9f4b9539093c65736f9.JPG)
![](http://uphotos.eepw.com.cn/campozeng/pics/cd87ba976421b503da5351679cd764e8.JPG)
![](http://uphotos.eepw.com.cn/campozeng/pics/c5e726833b323625c4894f93c0611639.JPG)
下面是一些代碼,給大家參考一下,為了省時間,有很多代碼是系統生成的:
下面兩個子程序用于計算溫度:
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** This function stores the AD conversion results and calculates the temperature.
**
** Parameters:
** None
**
** Returns:
** None
**
**-----------------------------------------------------------------------------
*/
void ADC_Calculation_Temp(void)
{
unsigned char i;
unsigned short TempBuffer;
g_temp_adcvalue=0x0000;
for(i=0;i<8;i++)
{
ADS = _80_AD_INPUT_TEMPERSENSOR_0;
AD_Start();
/* Wait for the A/D conversion to complete */
while(ADIF == 0);
/* Clear ADC interrupt flag */
ADIF = 0;
AD_Read(&TempBuffer); // Store the conversion result in TempBuffer
g_temp_adcvalue = + TempBuffer;
}
g_temp_adcvalue >>=3; // Get average
temp = (float) 1.44 / g_ref_hexvalue;
g_temperature = (float) (25 - ((((g_temp_adcvalue * temp) - 1) * 1000) / 3.6)); // Calculate the temperature value in 癈
TempBuffer=(unsigned short)(g_temperature*10);
TXBuffer[0]=CMD_SETTING; //command
TXBuffer[1]=CMD_SEND_TEMPERATURE; //command
TXBuffer[2]=0x31; //channel
TXBuffer[3]=(unsigned char)(TempBuffer/100)+0x30; //Change the temperature to BCD
TXBuffer[4]=(unsigned char)(TempBuffer%100/10)+0x30;
TXBuffer[5]='.';
TXBuffer[6]=(unsigned char)(TempBuffer%10)+0x30;
TXBuffer[7]='C';
TXBuffer[8]=CMD_END_DATA;
UartTX(&TXBuffer[0]); //Send data to computer via UART2
while(TXStatus!=TX_FINISH);
}
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** This function stores the AD conversion results and calculates the reference voltage.
**
** Parameters:
** None
**
** Returns:
** None
**
**-----------------------------------------------------------------------------
*/
void ADC_Calculation_Ref(void)
{
unsigned char i;
unsigned short TempBuffer;
g_ref_hexvalue=0x0000;
for(i=0;i<8;i++)
{
ADS = _81_AD_INPUT_TEMPERSENSOR_1; //select internal temperature sensor
AD_Start();
/* Wait for the A/D conversion to complete */
while(ADIF == 0);
/* Clear ADC interrupt flag */
ADIF = 0;
AD_Read(&TempBuffer); // Store the conversion result in TempBuffer
g_ref_hexvalue = + TempBuffer;
}
g_ref_hexvalue >>=3; //get average
}
下面是串口發送數據及中斷程序:
void UartTX(unsigned char *p)
{
TXStatus=TX_START;
SRMK2 = 1U; /* Disable Reception Interrupt */
SREMK2 = 1U; /* Disable Reception error Interrupt */
TXPointer=p;
STMK2 = 1U; /* disable INTST0 interrupt */
TXD2=*TXPointer++; // Send System on msg to host computer
TXCount=1;
STIF2 = 0U; /* clear INTST2 interrupt flag */
STMK2 = 0U; /* enable INTST0 interrupt */
}
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** This function is INTST2 interrupt service routine.
**
** Parameters:
** None
**
** Returns:
** None
**
**-----------------------------------------------------------------------------
*/
#pragma vector = INTST2_vect
__interrupt void MD_INTST2(void)
{
TXD2 = * TXPointer; // TX next character
TXCount++;
if (* TXPointer == CMD_END_DATA || TXCount==MAX_PACKET_LEN) // TX over?
{
TXStatus=TX_FINISH;
SRIF2 = 0U; /* clear INTSR2 interrupt flag */
SRMK2 = 0U; /* enable INTSR2 interrupt */
SREIF2 = 0U; /* clear INTSRE2 interrupt flag */
SREMK2 = 0U; /* enable INTSRE2 interrupt */
STMK2 = 1U; /* disable INTST0 interrupt */
}
TXPointer++;
}