本例程采用宏晶的STC8G1K08單片機來檢測輸出類型為4~20mA PT100傳感器的程序,在檢測中使用XPT2046作為AD的檢測芯片,XPT2046具有4路12位的AD檢測輸入端,因此最大可檢測4路傳感器,本例程中我們只使用了其中1路。檢測時使用了中值濾波算法。先看一下XPT2046的驅(qū)動程序:
/****************************************************************************
*函數(shù)名:SPI_Write
*輸 入:dat:寫入數(shù)據(jù)
*輸 出:無
*功 能:使用SPI寫入數(shù)據(jù)
****************************************************************************/
void SPI_Write(uchar dat)
{
uchar i;
CLK = 0;
delay_us(2);
for(i=0; i<8; i++)
{
DIN = dat >> 7; //放置最高位
dat <<= 1;
CLK = 0; //上升沿放置數(shù)據(jù)
delay_us(2);
CLK = 1;
delay_us(2);
}
}
/****************************************************************************
*函數(shù)名:SPI_Read
*輸 入:無
*輸 出:dat:讀取 到的數(shù)據(jù)
*功 能:使用SPI讀取數(shù)據(jù)
****************************************************************************/
uint SPI_Read(void)
{
uint i, dat=0;
CLK = 0;
delay_us(2);
for(i=0; i<12; i++) //接收12位數(shù)據(jù)
{
dat <<= 1;
CLK = 1;
delay_us(2);
CLK = 0;
delay_us(2);
dat|= DOUT;
}
return dat;
}
/****************************************************************************
*函數(shù)名:Read_AD_Data
*輸 入:cmd:讀取的X或者Y
*輸 出:endValue:最終信號處理后返回的值
*功 能:讀取觸摸數(shù)據(jù)
****************************************************************************/
uint Read_AD_Data(uchar cmd)
{
uint AD_Value;
CS = 0;
delay_us(2);
CLK = 0;
delay_us(2);
SPI_Write(cmd);
delay_us(6);//延時等待轉(zhuǎn)換結(jié)果
CLK = 1; //發(fā)送一個時鐘周期,清除BUSY
delay_us(2);
CLK = 0;
delay_us(2);
AD_Value=SPI_Read();
CS = 1;
return AD_Value;
}
下面是它的頭文件:
#ifndef __XPT2046_H_
#define __XPT2046_H_
#include "STC8G.H"
#include "delay.h"
#include<intrins.h>
//---定義使用的IO口---//
sbit DOUT = P1^0; //輸出
sbit CLK = P3^4; //時鐘
sbit DIN = P3^6; //輸入
sbit CS = P3^5; //片選
uint Read_AD_Data(uchar cmd);
uint SPI_Read(void);
void SPI_Write(uchar dat);
#endif
以下是主程序:
#include "STC8G.H"
#include "delay.h"
#include "uart1.h"
#include "XPT2046.h"
#define voltage 5.00
#define ncnt 127 //采集次數(shù)必須為奇數(shù)
float sum=0; //浮點型溫度值
float val=0; //AD采集到的電壓值
unsigned int temd; //排序中間轉(zhuǎn)換變量
unsigned int temp; //用取取緩存中的中間值
xdata unsigned int value_buf[ncnt]; //AD采集存儲緩存
int wendu; //整數(shù)型溫度變量
char count, i,j; //排序計數(shù)變量
unsigned char puf[6];
void main()
{
P_SW1 = 0x10;//RXD/P3.0, TXD/P3.1
Uart1_Init();
P1M0 = 0x00; //設(shè)置為準雙向口
P1M1 = 0X00;
P3M0 = 0x70; //設(shè)置為推挽輸出
P3M1 = 0X00;
while(1)
{
//temp = Read_AD_Data(0x94);//AIN0
//temp = Read_AD_Data(0xD4);//AIN1
//temp = Read_AD_Data(0xA4);//AIN2
//temp = Read_AD_Data(0xE4);//AIN3
for (count=0; count<ncnt; count++) //連續(xù)采集ncnt次
{
value_buf[count]= Read_AD_Data(0x94); //將采集到的數(shù)據(jù)存到value_buf中
}
for (j=0;j<ncnt-1;j++) //將采集到的數(shù)據(jù)從小到大排列
{
for (i=0;i<ncnt-j;i++) //通過for循環(huán)排列數(shù)據(jù)
{
if (value_buf[ i] > value_buf[i+1]) //如果前一個元素大于后一個元素
{
temd = value_buf[ i]; //則將大的元素賦值給temd
value_buf[ i] = value_buf[i+1]; //將小值賦給前一個元素
value_buf[i+1] = temd; //將大值賦給后一個元素
}
}
}
temp=value_buf[(ncnt-1)/2]; //取緩存中的中間值
val=temp*voltage/4096.0; //算出當前電壓,5.01是AD基準值,跟據(jù)實際電壓自行修改
sum=((250.00*val)/2.40)-112.50; //根據(jù)公式計算出當前溫度,公式: T=(250/2.4)*V-112.5
wendu=(int)(sum*10); //將浮點數(shù)*10轉(zhuǎn)換為整數(shù)型數(shù)據(jù)
if(wendu&0x8000) //如果溫度為負值
{
wendu=((~wendu)&0x7fff)+1; //則取反加1
puf[0]='-'; //加上負數(shù)標志位'-'
}
else if((wendu/1000)==0){
puf[0]=' ';
}else puf[0]=wendu/1000+0x30;
if(((wendu/1000)==0)&&((wendu%1000/100)==0)) //如果最高兩位都為0
puf[1]=' '; //則不顯示
else puf[1]=wendu%1000/100+0x30; //否則正常顯示數(shù)
puf[2]=wendu%1000%100/10+0x30;
puf[3]='.';
puf[4]=wendu%1000%100%10+0x30;
// Uart1_SendString(puf);
//Uart1_SendChar(temp/256);
//Uart1_SendChar(temp%256);
delay_ms(300);
}
}
原理圖: 無
仿真: 無
Keil代碼:
PT00串口.7z
(29.44 KB, 下載次數(shù): 25)
2024-1-2 01:03 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|