⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds18b20.c

📁 AVR红外遥控
💻 C
字号:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/eeprom.h>
#include <avr/delay.h>
#include <avr/wdt.h>

#include "ds18b20.h"
#include "display.h"
//延时N毫秒
void DelayMs(uint ms){
	uint i;
	wdt_reset();
	for (i=0;i<ms;i++)
	_delay_loop_2(8*250);
}
void delay_us(int time){
	do 
		time--;
	while (time>1);
}
/*  		字符输出函数 		 */
/*void putchar(uchar c){	 
 while (!(UCSRA&(1<<UDRE)));
 UDR=c;    
}*/
/*void uart0_init(void){
	UCSRA = 0x00;
	UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
  UBRRL = (FOSC/16/(BAUD+1))%256;
	UBRRH = (FOSC/16/(BAUD+1))/256;
	UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);//8位数据+1位STOP位
}*/

//DS1820应答
unsigned char ds1820_ack(void){
	unsigned char ack;
	DDRD |= _BV(DS_PLACE);					//方向:输出
	PORTD &= ~_BV(DS_PLACE);				//输出:0
//	delay_us(200);
	delay_us(400);
	PORTD |= _BV(DS_PLACE);					//输出1
	DDRD &= ~_BV(DS_PLACE);					//方向:输入
//	delay_us(30);
	delay_us(60);
	ack = PIND;
	ack &=_BV(DS_PLACE);
//	delay_us(200);
	delay_us(400);
	return ack;
}
//================================================
//   从DS18b20 读一个字节
//================================================
unsigned char ds1820_read(void){
	unsigned char i,byte,temp;
//	cli();
  TIMSK &= ~_BV(TOIE0);      // stop T0 interrupt
	byte = 0x00;
	for (i = 0;i < 8; i ++){
		DDRD |= _BV(DS_PLACE);				//方向:输出
		PORTD &= ~_BV(DS_PLACE);			//输出:0
//		delay_us(1);
	  delay_us(2);
//		delay_us(3);
		PORTD |= _BV(DS_PLACE);				//输出1
		DDRD &= ~_BV(DS_PLACE);				//方向:输入
//		delay_us(5);
//  	delay_us(10);
  	delay_us(10);
		temp = (PIND & _BV(DS_PLACE));
		if (temp != 0x0)
			byte |= 0x80;
		if (i<7)
			byte = byte>>1;
//		delay_us(50);
  	delay_us(100);
		DDRD |= _BV(DS_PLACE);
//		delay_us(1);
		delay_us(2);
	}
//	sei();
//	putchar(byte);
  TIMSK |= _BV(TOIE0);      // enable T0 interrupt
	return byte;
}
//================================================
//写ROM或存储器命令到DS1820
//================================================
void ds1820_write(unsigned char cmd){
	unsigned char i,j;
//	cli();
  TIMSK &= ~_BV(TOIE0);      // stop T0 interrupt
	DDRD |= _BV(DS_PLACE);
	for (j = 0; j <= 7; j ++){
		i = cmd & 0x01;
		if (i == 0x01){
			PORTD &= ~_BV(DS_PLACE);
//			delay_us(5);
		  delay_us(10);
			PORTD |= _BV(DS_PLACE);
//			delay_us(100);
	  	delay_us(200);
		}
		else{
			PORTD &= ~_BV(DS_PLACE);
//			delay_us(50);
	  	delay_us(100);
			PORTD|= _BV(DS_PLACE);
//			delay_us(5);
	  	delay_us(10);
		}
		cmd >>= 1;
	}
//	sei();
  TIMSK |= _BV(TOIE0);      // enable T0 interrupt
}
//================================================
//  匹配DS1820
//================================================
void ds1820_match (unsigned char *p){
	unsigned char i;
	do {
	//	putchar('4');
		i = ds1820_ack();
	//	putchar(i);
	}
	while(i==0x10);
	ds1820_write(0x55);
	for (i = 0; i < 8; i ++)
	ds1820_write(p[i]);

}
//crc校验
uint8_t crccheck(uint8_t *p,uint8_t 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 = temp >> 1;
			r = cbit ^bit0;
			if (r == 1)
				temp = temp ^ 0x8c;
			byte = byte>>1;
		}
	}
	return temp;
}
//读DS18B20,返回温度值
uint8_t Rom_code[8]={0,0,0,0,0,0,0,0};
uint8_t *Asc2p;
uint16_t Temperature;//=20;
uint16_t read_ds1820(void){
	uint8_t ds1820[9];					
	uint16_t ds1820_temp = 0;
	uint8_t i,crc;
	Asc2p =& Rom_code[0];
	wdt_reset();
//	putchar(1);

	ds1820_match(Asc2p);
//	putchar(2);

	ds1820_write(0x44);

//	putchar(3);
	wdt_reset();
	DelayMs(750);
//	putchar(4);

	Asc2p =& Rom_code[0];
//	putchar(5);
	ds1820_match(Asc2p);
//	putchar(6);
	ds1820_write(0xbe);
//	putchar(7);
	for (i = 0; i < 9; i ++){
		ds1820[i] = ds1820_read();
	}
	Asc2p =& ds1820[0];

	crc = crccheck(Asc2p,9);
//	putchar(crc);
	if (crc == 0){
//		putchar(8);
		ds1820_temp = ds1820[1];
		ds1820_temp = ds1820_temp << 8;
		ds1820_temp += ds1820[0];			

		if ((ds1820_temp & 0xf800) != 0){
			ds1820_temp = 0xffff - ds1820_temp;				//为零度以下,加-号
    		ds1820_temp+=1;
    		ds1820_temp *= 10;							//为提高精度,放大10倍,精度达到0。1超出了要求0。5的精度。
    		ds1820_temp /= 16;							//放大10倍,注意后部计算时除10
    		ds1820_temp |=0x8000;
  //  		putchar(10);
    		return ds1820_temp;
		}
		else{
	//		putchar(9);
	//		ds1820_temp *= 10;							//为提高精度,放大10倍,精度达到0。1超出了要求0。5的精度。
   			ds1820_temp /= 16;							//放大10倍,注意后部计算时除10
    		return ds1820_temp;	
 		}
	}
	else
		return 0xffff;

}

//************************************************



void ds1820_init(void){
	uint8_t i,crc;
	do {
		i = ds1820_ack();
	//putchar(i);
	}
	while(i==0x10 );
	ds1820_write(0x33);
	for (i = 0; i < 8; i++){
		Rom_code[i] = ds1820_read();
	}
	Asc2p =& Rom_code[0];
	crc = (crccheck(Asc2p,8));
	if (crc == 0x00){
		Asc2p =& Rom_code[0];
	}
	Temperature = read_ds1820();					//read ds18b20 
	
//	putchar(Temperature);
//	putchar((Temperature>>8) & 0x00ff);
	//putchar(0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -