📄 mainthermo float.c
字号:
/* THIS THERMOMETER USE THE MCD2 DEMO BOARD TO
DISPLAY THE temprature degree.
USING 16F877 READ MAXIM DS18b20 AND DISPLAY ON LCD1602 */
/* ver1.1 May 2006
by Freeman(自由人)
On the demo board, original DQ pin of DS18B20 is connected
to PORTA.2 through a switch, have some conflict
with LCD which also use PORTA.2
so I just keep the switch OFF, and fly a wire
from pin DQ to PORTA.0 directly.
the program of ver 1.0 only display a integer degree,
ver 1.1 can display float point. with 1 decimal fraction.
the difference as follow :
int dsread() ---> float dsread()
int temperature ---> float temperature
some change in itoa10(char, int );
*/
#include <pic.h>
/* PIN define
*/
#define LCDRS RA1
#define LCDRW RA2
#define LCDE RA3
#define LCDDATA PORTC
#define DSDQ RA0 /* ds18b20 */
#define TRISDQ TRISA0
/* function define */
void lcdinit(); /* two line mode */
void wcmd (char cmd);
void wdata (char data);
void poscursor(char line, char col);
void print(char *s);
void lcdbusy();
void delay ( int t);
void itoa10(unsigned char *buf, int i);
int strlen (const char *s);
void dsinit();
void wdscmd(char cmd);
float dsread ();
/* constant define */
char bank1 title[]= "Temperature is";
char dsfound[]="DS1820 FOUND";
char dsnotfound[]="DS1820 NOT FOUND";
char bank1 blank[]= " ";
/* LCD command define */
#define CLRLCD 0X01
#define LCDMOD 0X38 /* 8 BIT, TWO LINE, 5X7 DOT MATRIX */
#define TURNON 0X0F /* turn on LCD, CURSOR, BLINKING */
#define CURMODE 0X06 /* character don't move, cursor move right automaticall */
/* DS1820 command */
#define SKIPROM 0XCC
#define READSCRACHPAD 0XBE
#define TCONVERT 0X44
/* ORIGINAL CURSOR POSITION */
#define ORG1 0X80
#define ORG2 0XC0
/* TMR0 */
static int count;
#define PRETMR0 210 /* aproximately 50us INT interval, 256-210 PLUS some headcost,*/
float temperature;
#define DSRESET 10
#define DSRECOVER 1
char bank1 atemperature[10]; /* used for store ascii code of digital temperature */
void main(){
int len;
ADCON1=0X07; /* SET PORTA AS DIGITAL I/O */
lcdinit();
print(title);
LCDE=0; /* when LCDE=0, MCU will not affect LCD, and we can operate DS1820 */
/* INIT TIMER0 */
OPTION=0B11001111; /* bit5=0, using internal instruciton cycle clock */
TMR0IE=1; /* enable timer0 */
PEIE=0; /* disables all peripheral interrupts */
GIE=1;
poscursor(1,0);
while (1) {
dsinit();
wdscmd(SKIPROM);
wdscmd(TCONVERT);
TRISDQ=0;
DSDQ=0;
TRISDQ=1;
while(1) { //test if the conversion finished
if (DSDQ)
break;
else
continue;
}
dsinit();
wdscmd(SKIPROM);
wdscmd(READSCRACHPAD);
temperature=dsread(); /* read temperature */
itoa10(atemperature, (int) (temperature * 10)); /* because the itoa10 only works with integer */
// so use temperature * 10 to enlarge the temperature
// and then add a decimal point in the function
/* the following put a decimal dot '.' before the last digit of the atemperature */
len=strlen(atemperature);
atemperature[len]=atemperature[len-1];
atemperature[len-1]='.';
atemperature[len+1]=0;
poscursor(0,0);
print (title);
poscursor(1,0);
print (blank);
poscursor(1,2);
print (atemperature);
print (blank);
delay(10000); /* wait for 10000*50 us=0.5 s before get new temperature */
}
}
void delay (int t){
count=0; /* reset timer 0 */
TMR0=PRETMR0;
while (count<t);
}
static void interrupt isr(void) // Here be interrupt function - the name is
// unimportant.
{
if(TMR0IF) // Was this a timer overflow?
count++; // Add 1 to count - insert idle comment
TMR0IF = 0; // Clear interrupt flag, ready for next
TMR0=PRETMR0;
}
int strlen(const char * s)
{
const char *cp;
cp = s;
while(*cp++)
continue;
return cp-s-1;
}
void print(char *s){
int len;
int atmp;
len=strlen(s);
for (atmp=0; atmp<len; atmp++)
wdata(s[atmp]);
}
/* before we write to LCD , must check if the LCD IS busy */
void lcdbusy(){
// char tmpbusy;
TRISA &= 0xF1;
TRISC=0XFF;
LCDRS=0;
LCDRW=1;
LCDE=1; /* SET the LCD read/writing operation IN TO IDLE */
while(LCDDATA & 0X80);
}
/* position cursor,
line= 0 for first line, or 1 for second line,
col=0 - 15 ;
*/
void poscursor(char line, char col){
char pos;
lcdbusy();
pos = line * 0X40 + 0X80 + col;
wcmd(pos);
}
void wdata(char data) {
lcdbusy();
TRISA & =0XF1;
TRISC=0;
LCDDATA=data;
LCDRS=1;
LCDRW=0;
LCDE=0;
asm("NOP");
asm("NOP");
LCDE=1;
}
void wcmd(char cmd){
lcdbusy();
TRISA & =0XF1;
TRISC=0;
LCDDATA=cmd;
LCDRS=0;
LCDRW=0;
LCDE=0;
asm("NOP");
asm("NOP");
LCDE=1;
}
void lcdinit() {
lcdbusy();
TRISA &= 0XF1;
TRISC=0;
wcmd(CLRLCD);
wcmd(LCDMOD);
wcmd(TURNON);
wcmd(CURMODE);
poscursor(0,0); /* set cursor to first position of first line */
}
/* DS1820
This file working with 16F877 using
RA0 pin to communate */
/* INIT */
void dsinit(){
TRISDQ=0;
DSDQ=0;
delay(20); /* keep DSDQ low for 10*50 us, to reset the DS1820 */
TRISDQ=1;
delay(1); /* here we can only use delay(1), more then one may go out of the sample window */
// if (!DSDQ) /* sample window between min end:15+60, max begin,60 */
/* garrente sample window is between 60 to 75 us */
// print(dsfound);
// else
// print(dsnotfound);
delay(10); /* wait for more then 480us, as required by the DS18B20 */
}
/* write command to DS1820*/
void wdscmd(char cmd){
char tmp;
char i;
TRISDQ=0;
for(tmp=8;tmp>0;tmp--) {
TRISDQ=0;
DSDQ= 0;
asm ("NOP");
asm ("NOP");
asm ("NOP");
asm ("NOP");
asm ("NOP");
if (cmd & 0x01) {
TRISDQ=1; /* release the bus */
delay(1); /* wait for more than 60 us */
for (i=5;i>0;i--);
}
else {
DSDQ=0 ;
delay(1);
for (i=5;i>0;i--);
TRISDQ=1;
}
cmd=cmd/2;
}
}
/* READ temperature */
float dsread () {
char tmp=0x01;
float t;
union{
char c[2];
int x;
}temp;
temp.x=0;
while (tmp){ // read first 8 bits
TRISDQ=0;
DSDQ=0;
asm("NOP");
TRISDQ=1; // release the bus
if (DSDQ) // "1" presented
temp.c[0] |= tmp;
tmp=tmp<<1;
delay(2);
}
tmp=1;
while (tmp){ // read first 8 bits
TRISDQ=0;
DSDQ=0;
asm("NOP");
TRISDQ=1; // release the bus
asm("NOP");
if (DSDQ) // "1" presented
temp.c[1] |= tmp;
tmp=tmp<<1;
delay(2);
}
t=((float) temp.x)/16.0 ;
return t;
}
/* Convert integer 'i', radix 10 to a string */
void itoa10(unsigned char *buf, int i) {
unsigned int rem;
unsigned char *s,length=0;
s = buf;
if (i == 0)
*s++ = '0';
else {
if (i < 0) {
*buf++ = '-';
s = buf;
i = -i;
}
while (i) {
++length;
rem = i % 10;
*s++ = rem + '0';
i /= 10;
}
for(rem=0; ((unsigned char)rem)<length/2; rem++) {
*(buf+length) = *(buf+((unsigned char)rem));
*(buf+((unsigned char)rem)) = *(buf+(length-((unsigned char)rem)-1));
*(buf+(length-((unsigned char)rem)-1)) = *(buf+length);
}
}
*s=0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -