Re: digital thermometer
#include "8051io.h"
#include "8051reg.h"
#include <AT89X51.H>
extern register char cputick; /* cputick increments by 1 every 10 ms */
unsigned register int count,i,adc,min,max;
unsigned register char sec100,sec10,ACC,initcount,flag;
unsigned register int msd,nsd,lsd;
unsigned register int xin[10];
void main (void)
{
TMOD = 0x21; /* set timer0 to 16-bit counter */
serinit(9600);
cputick = 0;
i = 0;
count=0;
sec100=0;
sec10=0;
flag = 0;
initcount=0;
asm "E EQU $B5"; /* bit define for P3.5 and P3.4 */
asm "RS EQU $B4";
asm " CLR E";
asm " CLR RS";
P1 = 0;
delay(5);
i_LCD();
puttitle();
delay(5000); /* show quantities to be measured */
flag |= 0x04;
puttime();
xin[0]=10000; /* show invalid display by putting out-of-range xin value */
flag |= 0x02;
puttemp();
TCON = 0x59;
while(1) /* run continuously */
{
do
{
; /* put tasks require 51's speed here */
}
while ( cputick < 10); /* 10 * 10 ms = 100 ms */
cputick = 0;
/* ____---____________________---___________________---________
|<------- 100 ms ----->|
_______----___________________----__________________----____
time ~20 ms
*/
/* put tasks requires 100 ms tick here */
asm " setb $b0";
time(); /* update time base */
putxin(); /* put converted digital data to 10-word buffer */
puttemp(); /* put temperature reading to LCD */
puttime(); /* put second counter to LCD */
asm " clr $b0";
}
}
time()
/* flag
%00000001 set bit0 every 100 ms
%00000010 set bit1 after first 10-samples
%00000100 set bit2 every 1 s
*/
{
sec100++;
if (sec100 >= 1) /* 1 * 100 ms = 100 ms */
{sec100 = 0;
sec10++;
initcount++;
flag |= 0x01; /* set bit 0 in flag */
if (initcount >= 10)
{initcount = 10;
flag |= 0x02;
}
if (sec10 >= 10)
{ sec10 = 0;
count++; /* increment count every 1 sec */
flag |= 0x04;
/* sendreading(); */
}
}
}
pause(j)
int j;
{
int i;
for (i = 0; i < j; i++)
;
}
LCDWI(A) /* write instruction to LCD */
char A;
{
ACC = A; /* use ACC for interfacing to Assembly */
asm {
MOV A,ACC
CLR RS
CLR E
MOV P1,A
SETB E
NOP
CLR E
SWAP A
MOV P1,A
SETB E
NOP
CLR E
}
pause(1);
}
LCDWD(A)
char A;
{
ACC = A; /* use ACC for interfacing to Assembly */
asm {
MOV A,ACC
SETB RS /* write data */
CLR E
MOV P1,A /* check for p1.0-p1.4 */
SETB E
NOP
CLR E
SWAP A
MOV P1,A
SETB E
NOP
CLR E
}
pause(1);
}
i_LCD() /* initialize LCD in accordance with Hitachi 44780 4-bit */
{
P1 = 0x30;
pulseE();
delay(10);
pulseE();
delay(1);
pulseE();
delay(1);
P1 = 0x20;
pulseE();
pulseE();
pulseE();
LCDWI(0x28); /* function set 4-bit bus, 1/16 line, 5*7 dots */
LCDWI(0x0c); /* display on/off on display,off cursor, no blink */
LCDWI(0x06); /* entry mode DDRAM address + */
LCDWI(1); /* clear display */
delay(5);
}
pulseE()
{
asm{
SETB E
NOP
CLR E
}
}
puttime()
{
int temp;
char zero;
if ((flag & 0x04) == 4)
{ flag &= ~0x04;
zero = 0;
LCDWI(0x80); /* leftmost digit */
if (count/10000 != 0)
{
LCDWD(count/10000+48);
zero = 1;
}
else LCDWD(' ');
temp = count%10000;
if ((zero == 0) && (temp/1000 == 0))
LCDWD(' ');
else {
LCDWD(temp/1000+48);
zero = 1;
}
temp = temp%1000;
if ((zero == 0) && (temp/100 == 0))
LCDWD(' ');
else {
LCDWD(temp/100+48);
zero = 1;
}
temp = temp%100;
if ((zero == 0) && (temp/10 == 0))
LCDWD(' ');
else LCDWD(temp/10+48);
temp = temp%10;
LCDWD(temp+48);
LCDWD(' ');
LCDWD('s');
LCDWD(' ');
}
}
/*
puttime()
{
int temp;
char zero;
zero = 0;
LCDWI(0x80); /* leftmost digit */
LCDWD(' ');
LCDWD(count/10000+48);
temp = count%10000;
LCDWD(temp/1000+48);
temp = temp%1000;
LCDWD(temp/100+48);
temp = temp%100;
LCDWD(temp/10+48);
temp = temp%10;
LCDWD(temp+48);
LCDWD(' ');
LCDWD('s');
}
*/
time1ms() /* 1 ms delay with XTAL 11.0592MHz */
{
int i;
for (i = 0; i < 8 ; i++)
;
}
delay
/* do nothing n*1ms */
int n;
{
int i;
for (i=0; i< n ; i++)
time1ms();
}
int readtemp()
{
P1 = 0xff; /* make P1.0 to P1.3 to be input port */
asm " SETB $B7";
asm " JNB $B7,*";
asm " JB $B7,*";
delay(1);
msd = (P1 & 0x0f);
delay(2);
P1 = 0xff;
lsd = P1 & 0x0f;
delay(2);
P1 = 0xff;
nsd = (P1 & 0x0f);
return(msd*100+nsd*10+lsd);
}
putxin() /* put raw data to FIFO buffer */
{ if ((flag & 0x01) ==1)
{flag &= 0xfe;
xin[9]=xin[8];
xin[8]=xin[7];
xin[7]=xin[6];
xin[6]=xin[5];
xin[5]=xin[4];
xin[4]=xin[3];
xin[3]=xin[2];
xin[2]=xin[1];
xin[1]=xin[0];
xin[0]=readtemp();
}
}
int average()
{
return((xin[0]+xin[1]+xin[2]+xin[3]+xin[4]+xin[5]+xin[6]+xin[7]+xin[8]+xin[9])/10);
}
puttemp()
{
int temp,t;
if((flag & 0x02)== 2)
{ flag &= ~0x02;
LCDWI(0xc0);
LCDWD(' ');
temp=average();
adc=temp;
if (temp < min)
min = temp;
if (temp > max)
max = temp;
if ( (temp < 999) && (temp > 0)) /* limit measuring range to 0-100 c */
{
t = temp/100;
if(t != 0)
LCDWD(t+48);
else LCDWD(' ');
temp = temp%100;
LCDWD(temp/10+48);
LCDWD('.');
LCDWD(temp%10+48);
}
else
{
LCDWD('-');
LCDWD('-');
LCDWD('-');
LCDWD('-');
}
LCDWD(0xdf); /* i.e., 'C */
LCDWD('C');
LCDWD(' ');
}
}
puttitle()
{
LCDWI(0x80);
LCDWD('D');
LCDWD('i');
LCDWD('g');
LCDWD('i');
LCDWD('T');
LCDWD('h');
LCDWD('e');
LCDWD('r');
LCDWI(0xc0);
LCDWD('m');
LCDWD('0');
LCDWD('-');
LCDWD('1');
LCDWD('0');
LCDWD('0');
LCDWD(0xdf);
LCDWD('C');
}