` 本帖最后由 eehome 于 2013-1-5 09:43 编辑
先上个电路图先。
原理是依据rc电路因电阻不同而充电时间不同,通过单片机内部计时器测出rc电路充电时间,通过与固定电阻的rc充电时间的比值算出湿敏电阻阻值,在查表的到湿度。其原本设计目标是做个低成本低精度的湿度控制系统,但在计时环节出错,出现达到一定阻值后明明电阻增大但时间反而减小的错误,原本以为是定时器溢出了,后在程序上加上溢出中断的因素后还是不成,也就没做后面控制部分,现在拿出与大家共同探讨研究。
下面是程序
#include "includes.h"
//#define tiME0H 0x3C
//#define TIME0L 0xB0
#define TIME0H 0x00
#define TIME0L 0x00
***it over=P0^0;
***it fang=P0^1;
int code table1[]={0,46,69,74,85,93,99,113,120,150,200,250,270,300,330,360};
int code table2[]={90,85,80,75,70,65,60,55,50,45,40,35,30,25,20};
//*************************************************************************************************
//* *
//* *******************************全局变量***************************** *
//* *
//*************************************************************************************************
float uc_Clock=0; //定时器0中断计数
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<定时器0中断函数>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void Time0() interrupt 1
{
TH0=TIME0H; //恢复定时器0。
TL0=TIME0L;
uc_Clock++;
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<延时函数>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void vDelay()
{
unsigned int uiCount;
for(uiCount=0;uiCount<250;uiCount++);
}
//
void timer_ms(unsigned char tim)
{
unsigned char i;
while(tim--)
{
for(i=0;i<200;i++); //延时1ms
}
}
//
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//
unsigned int temp_ntc()
{
unsigned int rt,temp,i;
float c=0,a,b;
unsigned int shidu;
unsigned char j;
for(j=0;j<10;j++)
{
P1=0x00; over =0; //放电 0000 0000 0
timer_ms(100); //延时等待电放完
TH0=0x00; //定时器T0清零
TL0=0x00;
P1=0x08;over =1;; //使用RK冲电 00001000 1
TR0=1; //启动T0计时
while(over==0)
TR0=0;
b=(TH0<<8)|TL0;
b=b+uc_Clock*65537;
P1=0x00; over=0; //放电 0000 0000 0
timer_ms(100);
TH0=0x00;
TL0=0x00;
P1=0x04; over=1; //使用热敏电阻冲电 0000 0100 1
TR0=1;
while(over==0);
TR0=0;
a=(TH0<<8)|TL0;
a=a+uc_Clock*65537;
P1=0x00; over =0; //放电 0000 0000 0
timer_ms(100); //延时等待电放完
c=c+(a/b); //累加10测量结果
//a=+a;
}
rt=(c/10); //先除以10求平均值,再乘以10求传感器电阻值。
for(i=1;i<=40;i++) //查表求出温度值
{
temp=table1;
if(rt<=temp) break; //条件满足则退出循环
}
if(rt!=temp) i--;
shidu=table2;
//shidu=shidu*10;
return rt;
}
//
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<把湿度显示在LCD上>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void vShowshidu(unsigned int uiNumber)
{
unsigned char ucaNumber[3],ucCount;
if(uiNumber>999)
uiNumber=999;
ucaNumber[0]=uiNumber/100; //把计算数字的每个位存入数组。
ucaNumber[1]=(uiNumber-100*(int)ucaNumber[0])/10;
ucaNumber[2]=uiNumber-100*(int)ucaNumber[0]-10*ucaNumber[1];
for(ucCount=0;ucCount<3;ucCount++)
{
vShowOneChar(ucaNumber[ucCount]+48); //从首位到末位逐一输出。
if(ucCount==1)
vShowOneChar('.');
}
}
//*************************************************************************************************
//* *
//* ********************************主函数****************************** *
//* *
//*************************************************************************************************
void main()
{
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<设置定时器0>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
TMOD=0x01; //定时器0,模式1。
TH0=TIME0H;
TL0=TIME0L;
TR0=1; //启动定时器。
ET0=1; //开定时器中断。
EA=1; //开总中断
vdInitialize();
vWriteCMD(0x82); //写入显示起始地址(第二行第一个位置)
vShowChar("H:80% L:50%");
vWriteCMD(0xC9);
vShowChar("(%)");
while(1)
{
vWriteCMD(0xC4);
vShowshidu(temp_ntc());
}
}
//*************************************************************************************************
//* *
//* ***************************SMC1602驱动程序************************* *
//* *
//*************************************************************************************************
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<头文件及宏定义>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include "SMC1602.h"
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<把1个命令写入LCD>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void vWriteCMD(unsigned char ucCommand)
{
vDelay(); //先延时。
LCDE=1; //然后把LCD改为写入命令状态。
LCDRS=0;
LCDRW=0;
LCDPORT=ucCommand; //再输出命令。
LCDE=0; //最后执行命令。
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<把1个数据写入LCD>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void vWriteData(unsigned char ucData)
{
vDelay(); //先延时。
LCDE=1; //然后把LCD改为写入数据状态。
LCDRS=1;
LCDRW=0;
LCDPORT=ucData; //再输出数据。
LCDE=0; //最后显示数据。
}
void vShowOneChar(unsigned char ucChar)
{
switch(ucChar)
{
case ' ': vWriteData(0x20);break;
case '!': vWriteData(0x21);break;
case '"': vWriteData(0x22);break;
case '#': vWriteData(0x23);break;
case '$': vWriteData(0x24);break;
case '%': vWriteData(0x25);break;
case '&': vWriteData(0x26);break;
case '>': vWriteData(0x27);break;
case '(': vWriteData(0x28);break;
case ')': vWriteData(0x29);break;
case '*': vWriteData(0x20);break;
case '+': vWriteData(0x2A);break;
case '-': vWriteData(0x2D);break;
case '/': vWriteData(0x2F);break;
case '=': vWriteData(0x3D);break;
case '<': vWriteData(0x3E);break;
case '?': vWriteData(0x3F);break;
case '.': vWriteData(0x2E);break;
case ':': vWriteData(0x3A);break;
case '0': vWriteData(0x30);break;
case '1': vWriteData(0x31);break;
case '2': vWriteData(0x32);break;
case '3': vWriteData(0x33);break;
case '4': vWriteData(0x34);break;
case '5': vWriteData(0x35);break;
case '6': vWriteData(0x36);break;
case '7': vWriteData(0x37);break;
case '8': vWriteData(0x38);break;
case '9': vWriteData(0x39);break;
case 'A': vWriteData(0x41);break;
case 'B': vWriteData(0x42);break;
case 'C': vWriteData(0x43);break;
case 'D': vWriteData(0x44);break;
case 'E': vWriteData(0x45);break;
case 'F': vWriteData(0x46);break;
case 'G': vWriteData(0x47);break;
case 'H': vWriteData(0x48);break;
case 'I': vWriteData(0x49);break;
case 'J': vWriteData(0x4A);break;
case 'K': vWriteData(0x4B);break;
case 'L': vWriteData(0x4C);break;
case 'M': vWriteData(0x4D);break;
case 'N': vWriteData(0x4E);break;
case 'O': vWriteData(0x4F);break;
case 'P': vWriteData(0x50);break;
case 'Q': vWriteData(0x51);break;
case 'R': vWriteData(0x52);break;
case 'S': vWriteData(0x53);break;
case 'T': vWriteData(0x54);break;
case 'U': vWriteData(0x55);break;
case 'V': vWriteData(0x56);break;
case 'W': vWriteData(0x57);break;
case 'X': vWriteData(0x58);break;
case 'Y': vWriteData(0x59);break;
case 'Z': vWriteData(0x5A);break;
case 'a': vWriteData(0x61);break;
case 'b': vWriteData(0x62);break;
case 'c': vWriteData(0x63);break;
case 'd': vWriteData(0x64);break;
case 'e': vWriteData(0x65);break;
case 'f': vWriteData(0x66);break;
case 'g': vWriteData(0x67);break;
case 'h': vWriteData(0x68);break;
case 'i': vWriteData(0x69);break;
case 'j': vWriteData(0x6A);break;
case 'k': vWriteData(0x6B);break;
case 'l': vWriteData(0x6C);break;
case 'm': vWriteData(0x6D);break;
case 'n': vWriteData(0x6E);break;
case 'o': vWriteData(0x6F);break;
case 'p': vWriteData(0x70);break;
case 'q': vWriteData(0x71);break;
case 'r': vWriteData(0x72);break;
case 's': vWriteData(0x73);break;
case 't': vWriteData(0x74);break;
case 'u': vWriteData(0x75);break;
case 'v': vWriteData(0x76);break;
case 'w': vWriteData(0x77);break;
case 'x': vWriteData(0x78);break;
case 'y': vWriteData(0x79);break;
case 'z': vWriteData(0x7A);break;
default: break;
}
}
void vShowChar(unsigned char ucaChar[])
{
unsigned char ucCount;
for(ucCount=0;;ucCount++)
{
vShowOneChar(ucaChar[ucCount]);
if(ucaChar[ucCount+1]==' |