📄 ds18b20.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 + -