Спойлер
Код: Выделить всё
#include "DS18B20.h"
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#define NOID 0xCC //Пропустить идентификацию
#define T_CONVERT 0x44 //Код измерения температуры
#define READ_DATA 0xBE //Передача байтов ведущему
#define PORTTEMP PORTD
#define DDRTEMP DDRD
#define PINTEMP PIND
#define BITTEMP 1
//функция определения датчика на шине
char dt_testdevice(void) //dt - digital termomether | определим, есть ли устройство на шине
{
//char stektemp=SREG;// сохраним значение стека
cli(); //запрещаем прерывание
char dt;
DDRTEMP |= 1<<BITTEMP; //притягиваем шину
_delay_us(485); //задержка как минимум на 480 микросекунд
DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
_delay_us(65); //задержка как максимум на 60 микросекунд
if ((PINTEMP & (1<<BITTEMP))==0)//проверяем, ответит ли устройство
{
dt=1;//устройство есть
}
else dt=0;//устройства нет
//SREG = stektemp;// вернем значение стека
_delay_us(420); //задержка как минимум на 480 микросекунд, но хватит и 420, тк это с учетом времени прошедших команд
return dt; //вернем результат
}
//функция записи бита на устройство
void dt_sendbit(char bt)
{
//char stektemp=SREG;// сохраним значение стека
cli(); //запрещаем прерывание
DDRTEMP |= 1<<BITTEMP; //притягиваем шину
_delay_us(2); //задержка как минимум на 2 микросекунды
if(bt)
DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
_delay_us(65); //задержка как минимум на 60 микросекунд
DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
//SREG = stektemp;// вернем значение стека
}
//функция записи байта на устройство
void dt_sendbyte(unsigned char bt)
{
char i;
for(i=0;i<8;i++)//посылаем отдельно каждый бит на устройство
{
if((bt & (1<<i)) == 1<<i)//посылаем 1
dt_sendbit(1);
else //посылаем 0
dt_sendbit(0);
}
}
//функция чтения бита с устройства
char dt_readbit(void)
{
//char stektemp=SREG;// сохраним значение стека
cli(); //запрещаем прерывание
char bt; //переменная хранения бита
DDRTEMP |= 1<<BITTEMP; //притягиваем шину
_delay_us(2); //задержка как минимум на 2 микросекунды
DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
_delay_us(13);
bt = (PINTEMP & (1<<BITTEMP))>>BITTEMP; //читаем бит
_delay_us(45);
// SREG = stektemp;// вернем значение стека
return bt; //вернем результат
}
//функция чтения байта с устройства
unsigned char dt_readbyte(void)
{
char c=0;
char i;
for(i=0;i<8;i++)
c|=dt_readbit()<<i; //читаем бит
return c;
}
//функция преобразования показаний датчика в температуру
int dt_check(void)
{
unsigned char bt;//переменная для считывания байта
unsigned int tt=0;
if(dt_testdevice()==1) //если устройство нашлось
{
dt_sendbyte(NOID); //пропустить идентификацию, тк у нас только одно устройство на шине
dt_sendbyte(T_CONVERT); //измеряем температуру
_delay_ms(750); //в 12битном режиме преобразования - 750 милисекунд
dt_testdevice(); //снова используем те же манипуляции с шиной что и при проверке ее присутствия
dt_sendbyte(NOID); //пропустить идентификацию, тк у нас только одно устройство на шине
dt_sendbyte(READ_DATA); //даем команду на чтение данных с устройства
bt = dt_readbyte(); //читаем младший бит
tt = dt_readbyte(); //читаем старший бит MS
tt = (tt<<8)|bt;//сдвигаем старший влево, младший пишем на его место, тем самым получаем общий результат
}
return tt;
}
uint8_t ds18b20_GetSign(uint16_t dt)
{
//Проверим 11-й бит
if (dt&(1<<11)) return 1;
else return 0;
}
//преобразование температуры в единицы
char converttemp (unsigned int tt)
{
char t = tt>>4;//сдвиг и отсечение части старшего байта
return t;
}Спойлер
Код: Выделить всё
/*
* 1-wire(mega32a).c
*
* Created: 13.03.2018 5:40:10
* Author : User
*/
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include "DS18B20.h"
//#include "adc.h"
#include "lcd.h"
unsigned int tt=0;
unsigned char S=0;
void inits_ports(void)
{
DDRB=0xFF;
PORTB=0x00;
DDRC|=(1<<2);
PORTC|=(0<<2);
DDRA=0x00;
PORTA=0x00;
DDRD=0xFF;
PORTD=0x00;
}
int main(void)
{
//unsigned int tt=0;
inits_ports();
//init_ADC();
lcd_init(LCD_DISP_ON);
lcd_clrscr();
while (1)
{
tt = converttemp(dt_check());
if (tt<0)
{
tt=(0-tt)/16;
//tt=-tt;
lcd_gotoxy(0,1);
lcd_data('-');
lcd_data(tt/10+0x30);
lcd_data(tt%10+0x30);
lcd_data('*');
lcd_data('C');
}
else
{
lcd_gotoxy(0,1);
lcd_data(' ');
lcd_data(tt/10+0x30);
lcd_data(tt%10+0x30);
lcd_data('*');
lcd_data('C');
}
}
}
Играюсь на AVR