/*-------------------------------------------
-------------------------------------------*/
#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;
}
}
给出了完整的程序大神 |