/******************************************************************** ATmega16L学习板18B20测试程序 晶振频率: 8MHz 编译: ICCAVR 6.31 编写: hanzhaowei@2911.net ********************************************************************/ #include #include #include "../include/board.h" /*=================================================================== // 函数功能: DS18B20数据校验函数 // 形参: void // 返回: unsigned char 校验结果 // 编写: 2004/8/25 // 备注: CRC公式为:CRC = X^8 + X^5 + X^4 + 1 ===================================================================*/ unsigned char crccheck(unsigned char *p,unsigned char len) { unsigned char bit0,cbit,r,temp,i,j,byte; temp = 0; for(j = 0; j < len; j++) { byte = p[j]; for(i = 0; i < 8; i++) { cbit = temp & 0x01; bit0 = byte&0x01; temp >>= 1; r = cbit ^ bit0; if(r == 1) temp ^= 0x8c; byte >>= 1; } } return temp; } /*=================================================================== // 函数功能: us延时函数 // 形参: void // 返回: void // 编写: 2004/8/25 ===================================================================*/ void delay_us(unsigned int time) { do { time--; } while (time>1); } /*=================================================================== // 函数功能: 判断总线应答 // 形参: void // 返回: unsigned char true为应答 // 编写: 2004/8/25 ===================================================================*/ unsigned char ds1820_ack(void) { unsigned char ack; DDRC |= DQ; PORTC &= ~DQ; delay_us(500); // reset PORTC |= DQ; DDRC &= ~DQ; delay_us(45); ack = DQ & PINC; delay_us(500); // host receive if(ack) return true; else return false; } /*=================================================================== // 函数功能: 从 1-wire 总线上读取一个字节 // 形参: void // 返回: unsigned char 读到的值 // 编写: 2004/8/25 ===================================================================*/ unsigned char read_byte(void) { unsigned char i; unsigned char value = 0; for(i = 8; i > 0; i--) { value >>= 1; // low bit first DDRC |= DQ; PORTC &= ~DQ; // pull DQ low to start timeslot delay_us(3); PORTC |= DQ; DDRC &= ~DQ; // release bus delay_us(10); if(DQ & PINC) value|=0x80; delay_us(100); DDRC |= DQ; delay_us(5); // time interval } return(value); } /*=================================================================== // 函数功能: 向 1-WIRE 总线上写一个字节 // 形参: value 写到总线上的值 // 返回: void // 编写: 2004/8/25 ===================================================================*/ void write_byte(unsigned char value) { unsigned char i; DDRC |= DQ; for(i = 8; i > 0; i--) { if(value & 0x01) { PORTC &= ~DQ; // pull DQ low to start timeslot delay_us(10); PORTC |= DQ; delay_us(100); } else { PORTC &= ~DQ; // pull DQ low to start timeslot delay_us(100); PORTC |= DQ; delay_us(10); } value >>= 1; } } /*=================================================================== // 函数功能: 读取温度 // 形参: *temperature 温度存储空间 // 返回: unsigned char true为有效 // 编写: 2004/8/25 ===================================================================*/ unsigned char Read_Temperature(unsigned int *temperature) { unsigned char i; union{ unsigned char c[2]; unsigned int x; }temp; unsigned char temporary[9]; ds1820_ack(); write_byte(0xCC); // Skip ROM write_byte(0x44); // Start Conversion for(i = 0; i < 16; i++) delay_us(50000); ds1820_ack(); write_byte(0xCC); // Skip ROM write_byte(0xBE); // Read Scratch Pad for(i = 0; i < 9; i++) temporary[i] = read_byte(); temp.c[0] = temporary[0]; temp.c[1] = temporary[1]; if(crccheck(temporary,9)) return false; else { *temperature = temp.x; return true; } } /*=================================================================== // 函数功能: 读取Rom Code // 形参: *temp DS18B20的Rom Code存储空间 // 返回: unsigned char true为有效 // 编写: 2004/8/25 ===================================================================*/ unsigned char Read_RomCode(unsigned char *temp) { ds1820_ack(); write_byte(0x33); temp[0] = read_byte(); temp[1] = read_byte(); temp[2] = read_byte(); temp[3] = read_byte(); temp[4] = read_byte(); temp[5] = read_byte(); temp[6] = read_byte(); temp[7] = read_byte(); if(crccheck(temp,8)) return false; else return true; } /*=================================================================== // 函数功能: 匹配DS18B20 // 形参: *p DS18B20的Rom Code // 返回: void // 编写: 2004/8/25 ===================================================================*/ void ds1820_match(unsigned char *p) { unsigned char i; ds1820_ack(); write_byte(0x55); for(i=0;i<8;i++) write_byte(p[i]); }