/* Firmware for Thermistor sensor input, the 89S52 Project Board. The sensor is tied to analog input channel1. Channel0 is available for experimenting with another sensors. Copyright (C) 2007, Wichit Sirichote, kswichit@kmitl.ac.th */ #include #include float read_temp1(void); float read_temp1_filter(void); sbit ADCDATA = P1^4; sbit CS = P3^6; sbit CLK = P2^4; sbit LEDDATA = P3^7; sbit STROBE = P2^5; sbit LED = P1^2; char segment[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x39}; int timer3, timer4; char cputick; char buffer[4]; int x1,x2,x3,x4,x5; unsigned int temp1; // return 12-bit ADC data 0 - 4095 int read_ADC(char n) { char i,channel; int k; k=0; CS=0; if(n==0) channel=0x0d; else channel=0x0f; for(i=0;i<4;i++) { CLK = 0; if(channel&8) ADCDATA = 1; else ADCDATA = 0; CLK = 1; channel <<=1; } ADCDATA = 1; CLK = 0; for(i=0;i<12;i++) { k<<=1; CLK=1; CLK=0; if(ADCDATA) k|=1; else k&=~1; } CS = 1; return k&0xfff; } // write 32-bit data to CMOS shift register 4094 void write_led() { char m,n; for(n=0;n<4;n++) { for(m=0;m<8;m++) { if(buffer[n]&0x80) LEDDATA=1; else LEDDATA=0; CLK =1; buffer[n]<<=1; CLK =0; } } STROBE=1; // strobe all 32-bit to the output ; STROBE=0; } // display temperature in celcius void update() { temp1=read_temp1_filter()*10; //temp1=(read_temp1_filter()*9/5+32)*10; // display temperature in F degrees buffer[0]=segment[temp1/100]; temp1=temp1%100; buffer[1]=segment[temp1/10]; buffer[1]|=0x80; // put decimal point buffer[2]=segment[temp1%10]; buffer[3]=segment[10]; } /* // display ADC raw data 0-4095 for 0 to +5V input at channel 0 // select below function when calibrating the input sensor! void update() { temp1=read_ADC(1); buffer[0]=segment[temp1/1000]; temp1=temp1%1000; buffer[1]=segment[temp1/100]; temp1= temp1%100; buffer[2]=segment[temp1/10]; buffer[3]=segment[temp1%10]; } */ // print temperature to display void print_ADC() { if(++timer3>10) { timer3=0; update(); write_led(); } } // toggle LED every 50 ticks void blinkLED() { if(++timer4>50) { timer4 = 0; LED ^= 1; } } // return filtered data using 5-point moving average int low_pass_filter1(void) { x5=x4; x4=x3; x3=x2; x2=x1; x1=read_ADC(1); return(x1+x2+x3+x4+x5)/5; } // return calibrated temperature in celcius float read_temp1_filter(void) { return(0.0323*low_pass_filter1()-15.122); } void timer0int(void) interrupt 1 using 1 { TH0 = 0xd8; // reload value for 100Hz produced by 12MHz XTAL TL0 = 0xf0; // for 11.0592MHz, reload value = 0xDC00 cputick++; } void main() { EA=1; ET0=1; TMOD|=0x01; TR0=1; cputick =0; while(1) { while(!cputick) continue; cputick = 0; // below tasks will be executed every 10ms print_ADC(); blinkLED(); } }