/*-------------------------------------------
-------------------------------------------*/
#include <cms.h>
#define DAT RA0 //定義74H164的SDA/SCL口
#define CLK RA1
#define LED1 RA3
#define LED2 RA6
#define LED3 RA4
#define LED4 RA5
#define Com0 RB1 //定義Com口
#define Com1 RB2
#define Com2 RB3
#define Com3 RB4
//顯示數據數組
unsigned char DispData[4];//存放COM0~COM4顯示的數據
//0,1,2,3,4,5,6,7,8,9數字對應碼
unsigned char num[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xff,0xf6};//0xaf,0x84,0x3d,0xb5,0x96,0xb3,0xbb,0x85,0xbf,0xb7};
//溫度對應表
const unsigned int TempTab[]=
{
255 ,//1度
254 ,//2度
253 ,//3度
252 ,//4度
251 ,//5度
250 ,//6度
249 ,//7度
248 ,//8度
247 ,//9度
246 ,//10度
245 ,//11度
244 ,//12度
243 ,//13度
242 ,//14度
241 ,//15度
240 ,//16度
239 ,//17度
238 ,//18度
237 ,//19度
236 ,//20度
235 ,//21度
234 ,//22度
233 ,//23度
232 ,//24度
231 ,//25度
230 ,//26度
229 ,//27度
228 ,//28度
227 ,//29度
226 ,//30度
225 ,//31度
224 ,//32度
223 ,//33度
222 ,//34度
221 ,//35度
220 ,//36度
219 ,//37度
218 ,//38度
216 ,//39度
215 ,//40度
213 ,//41度
212 ,//42度
210 ,//43度
209 ,//44度
207 ,//45度
206 ,//46度
204 ,//47度
203 ,//48度
201 ,//49度
199 ,//50度
198 ,//51度
196 ,//52度
194 ,//53度
192 ,//54度
191 ,//55度
189 ,//56度
187 ,//57度
185 ,//58度
183 ,//59度
181 ,//60度
180 ,//61度
178 ,//62度
176 ,//63度
174 ,//64度
172 ,//65度
170 ,//66度
168 ,//67度
166 ,//68度
164 ,//69度
162 ,//70度
160 ,//71度
157 ,//72度
155 ,//73度
153 ,//74度
151 ,//75度
149 ,//76度
147 ,//77度
145 ,//78度
143 ,//79度
141 ,//80度
139 ,//81度
137 ,//82度
135 ,//83度
133 ,//84度
131 ,//85度
129 ,//86度
127 ,//87度
125 ,//88度
123 ,//89度
121 ,//90度
119 ,//91度
117 ,//92度
115 ,//93度
113 ,//94度
111 ,//95度
109 ,//96度
107 ,//97度
105 ,//98度
103 ,//99度
102 //100度
};
volatile unsigned int adresult;//AD結果
volatile unsigned char Temp;//溫度
void Display(void);
void ADTest(void);
void ADTransTemp(void);
void TEMPEA();
//主程序
void main(void)
{
asm("clrwdt");
OSCCON = 0x71; //配置為8M內部振蕩
TRISA = 0x00; //將對應IO口配置為輸出口
TRISB = 0x20; //將RB5配置為輸入口
TRISE = 0x00;
while(1)
{
asm("clrwdt"); //清看門狗
ADTest(); //AD檢測
ADTransTemp();
//TEMPEA();
//溫度數據賦值給顯示數據
DispData[0] = num[Temp /100];//不顯示
DispData[1] = num[Temp % 100/10];
DispData[2] = num[Temp %10];
DispData[3] = 0x9c; //c
Display();
}
}
/***********************************************
函數名稱:ADTest
函數功能:AD檢測
入口參數:無
出口參數:無
備注:
************************************************/
void ADTest()
{
static unsigned int admax,admin; //存放最大、最小值
static unsigned int adsum; //存放總和
static unsigned int adls; //即時ad值
static unsigned char adtimes; //檢測ad次數
ADCON1 = 0x80; //右對齊 出10位
ADCON0 = 0xB5; //32分頻 第13通道(中間4位) 允許AD使能01
asm("nop");
asm("nop");
GODONE = 1; //開始轉換
volatile unsigned char i = 0;
while(GODONE)
{
if(0 == (--i)) //ad等待限時,防止拔插電后出現死循環
return;
}
adls =(ADRESH<<8)+ADRESL;
if(0 == admax)
{
admax = adls; //只取高8位有效處理
admin = adls;
}
else if(adls > admax)
admax = adls; //AD采樣最大值
else if(adls < admin)
admin = adls; //AD采樣最小值
adsum += adls;
if(++adtimes >= 10)
{
adsum -= admax;
adsum -= admin;
adresult = adsum >> 3; //8次平均值作為最終結果
adsum = 0;
admin = 0;//1023;
admax = 0;
adtimes = 0;
}
}
/***********************************************
函數名稱:ADTransTemp
函數功能:AD值轉換為溫度值
入口參數:無
出口參數:無
備注:二分法尋溫度點
************************************************/
void ADTransTemp()
{
volatile unsigned char Count,TempBit; //
static volatile unsigned char TempOld; //ad舊值,用于比較30次決定是否改變溫度
static volatile unsigned char TempTime; //用于記錄30次
volatile unsigned char C_TEMP_MAX = 100;
if(adresult >= 102) //>=50顯示100度
{
TempBit = 50;
}
else if(adresult <= 255) //<=0度,顯示0度
{
TempBit = 0;
}
else
{
Count=0x80; //開始判斷點,從最高位開始
TempBit=0;
do
{
if((Count>C_TEMP_MAX)||((Count|TempBit)>C_TEMP_MAX))
{
TempBit=(~Count)&TempBit; //最高位為0
}
else
{
if(adresult >= TempTab[Count|TempBit])
{
TempBit=Count|TempBit;
}
else
{
TempBit=(~Count)&TempBit;
}
}
Count=Count>>1;
}while(0!=Count);
}
if(TempBit==TempOld)
{
if(++TempTime>=30) //30次相等則刷新
{
Temp=TempBit;
TempTime=0;
}
}
else
{
TempOld=TempBit;
TempTime=0;
}
}
/***********************************************
函數名稱:Move164
函數功能:顯示程序
入口參數:movedata - 需要輸出的數據
出口參數:無
備注:
************************************************/
void Move164(unsigned char movedata)
{
for(unsigned char i = 0; i <= 7; i++)
{
DAT = 0;
CLK = 0;
if(movedata & 0x01)
DAT = 1;
CLK = 1;
movedata = movedata >> 1;
}
}
/***********************************************
函數名稱:Display
函數功能:顯示程序
入口參數:無
出口參數:無
備注:
************************************************/
void Display()//循環掃描各個COM口
{
static unsigned char Dcount;//COM口輪流顯示計數
Com0 = 1;
Com1 = 1;
Com2 = 1;
Com3 = 1;
if(++Dcount >= 4)
Dcount = 0;
switch(Dcount)
{
case 0: Move164(DispData[0]);Com0 = 0; break;
case 1: Move164(DispData[1]);Com1 = 0; break;
case 2: Move164(DispData[2]);Com2 = 0; break;
case 3: Move164(DispData[3]);Com3 = 0; break;
}
}
給出了完整的程序大神 |