Чтение данных на 1-Wire шине

Инициализация: сигнал сброса и присутствия на 1-Wire шине

Все сеансы связи микроконтроллера с датчиком DS18B20 начинаются с сигнала сброса. Микроконтроллер на 480 мкс «проваливает» 1-Wire шину в ноль, а затем «отпускает» ее. Если к шине подключен термометр DS18B20, то он обнаруживает положительный перепад и после паузы в 15-60 мкс отвечает микроконтроллеру импульсом присутствия — «проваливает» шину в ноль на время от 60 до 240 мкс.

Запись данных на 1-Wire шине

Обмен данными по 1-Wire шине происходит последовательно, младшим битом вперед. Передача или прием одного бита данных выполняются в течении фиксированного промежутка времени, так называемого тайм слота (time slot). Различают тайм слоты записи и тайм слоты чтения. Длительность всех тайм слотов должна быть > 60 мкс, а пауза между тайм слотами > 1 мкс.

Для передачи нуля микроконтроллер «проваливает» 1-Wire шину на время от 60 до 120 мкс. Затем «отпускает» ее и перед записью следующего бита выдерживает паузу >1 мкс.

Для передачи единицы микроконтроллер «проваливает» 1-Wire шину на время от 1 до 15 мкс, «отпускает» ее и выдерживает паузу. Пауза должна быть такой, чтобы длительность тайм слота была > 60+1 мкс.

Чтение данных на 1-Wire шине

DS18B20 является подчиненным устройством и может передавать данные, только когда микроконтроллер формирует на 1-Wire шине тайм слоты чтения. Для формирования тайм слота чтения микроконтроллер «проваливает» 1-Wire шину на время от 1 до 15 мкс, а затем «отпускает» ее, передавая управление состоянием 1-Wire шины датчику DS18B20. Если DS18B20 передает ноль, он удерживает шину в «проваленном» состоянии (в состоянии логического нуля) до конца тайм слота. Если он передает 1, он оставляет шину в «подтянутом» состоянии.

Микроконтроллер может считывать данные датчика DS18B20 через 15 мкс после начала тайм слота чтения

3 Описание программного обеспечения

3.1 Программа

#define F_CPU 1000000UL

#include <avr/io.h>

#include <util/delay.h>

#include <avr/interrupt.h>

#define SKIP_ROM 0xCC

#define CONVERT_T 0x44

#define READ_SCRATCHPAD 0xBE

#define lov DDRA |= 1<<0

#define high DDRA &= ~(1<<0)

#define e 0x03

#define rs 0x02

char init(void)

{

char device;

lov;

PORTA=0x00;

_delay_us(480);

high;

_delay_us(60);

if((PINA & (1<<0))==0x00)

device=1;

else

device=0;

_delay_us(420);

return device;

}

void send_bit(char bit)

{

lov;

PORTA=0x00;

_delay_us(1);

if(bit==0)

{

_delay_us(60);

high;

}

else

{

high;

_delay_us(60);

}

}

void send_byte(unsigned char byte)

{

char i;

for(i=0; i<8; i++)

{

if((byte & (1<<i))==(1<<i))

send_bit(1);

else

send_bit(0);

}

}

char read_bit(void)

{

char rbit=0;

lov;

PORTA=0x00;

_delay_us(1);

high;

_delay_us(14);

if(PINA&(1<<0))

rbit=1;

_delay_us(45);

return rbit;

}

unsigned char read_byte(void)

{

char data=0, i;

for(i=0; i<8; i++)

data|=(read_bit()<<i);

return data;

}

unsigned int temp()

{

unsigned char temp_ls=0;

unsigned char temp_ms=0;

unsigned int temp=0;

init();

send_byte(SKIP_ROM);

send_byte(CONVERT_T);

_delay_ms(750);

init();

send_byte(SKIP_ROM);

send_byte(READ_SCRATCHPAD);

temp_ls = read_byte();

temp_ms = read_byte();

temp =(temp_ms<<8)|temp_ls;

return temp;

}

unsigned char convert_temp()

{

unsigned char convert;

convert=temp()/16;

return(convert);

}

void send_com(unsigned char com)

{

unsigned char a;

a=(com&~(1<<rs))|(1<<e);

PORTD=a;

_delay_us(1);

PORTD=a&~(1<<e);

a=((com*16)&~(1<<rs))|(1<<e);

PORTD=a;

_delay_us(1);

PORTD=a&~(1<<e);

_delay_ms(2);

}

void send_data(unsigned char data)

{

_delay_us(50);

unsigned char b;

b=(data|(1<<rs))|(1<<e);

PORTD=b;

_delay_us(50);

PORTD=b&~(1<<e);

_delay_us(50);

b=((data*16)|(1<<rs))|(1<<e);

PORTD=b;

_delay_us(50);

PORTD=b&~(1<<e);

_delay_us(50);

}

void lcd_init (void)

{

_delay_ms(2);

send_com(0b00000001);

_delay_ms(2);

send_com(0b00001100);

_delay_ms(2);

send_com(0b00100000);

_delay_ms(2);

send_com(0b00000110);

_delay_ms(2);

}

void send_temp(void)

{

unsigned char t;

unsigned char g;

g=convert_temp();

t=(g/100);

if(t!=0)

{

t=t+0x30;

send_data(t);

t=((g%100)/10)+0x30;

send_data(t);

t=((g%100)%10)+0x30;

send_data(t);

}

else

{

t=((g%100)/10);

if(t!=0)

{

t=t+0x30;

send_data(t);

t=((g%100)%10)+0x30;

send_data(t);

}

else

{

t=((g%100)%10)+0x30;

send_com(0b00000001);

_delay_ms(2);

send_data(t);

}

}

}

int main(void)

{

DDRA=0x00;

PORTA=0x00;

DDRD=0xFF;

PORTD=0x3F;

_delay_ms(1000);

lcd_init();

while(1)

{

send_temp();

send_com(0b00000010);

}

}

3.2 Описание используемых данных

3.2.1 Присвоенные имена числовым значениям

SKIP_ROM – 0xCC;

CONVERT_T – 0x44;

READ_SCRATCHPAD – 0xBE;

lov – DDRA |= 1<<0;

high – DDRA &= ~(1<<0);

e – 0x03;

rs – 0x02.

3.2.2 Переменные

device – переменная состояния датчика;

i –переменная цикла;

rbit – переменная для записи бита с датчика;

data – переменная для записи байта с датчика;

temp_ls – переменная для записи младшего байта с датчика;

temp_ms – переменная для записи старшего байта с датчика;

temp – переменная, содержащая оба байта температуры;

convert – переменная для преобразования температуры в один байт;

a – переменная для отправки команд в порт микроконтроллера;

b – переменная для отправки команд в порт микроконтроллера;

g – промежуточная переменная для отправки температуры на экран;

t –переменная для отправки температуры на экран.

3.3 Описание используемых функций.

char init(void) – функция инициализации датчика;

void send_bit(char bit) – функция отправки бита в датчик;

void send_byte(unsigned char byte) – функция отправки байта в датчик;

char read_bit(void) – функция чтения бита из датчика;

unsigned char read_byte(void) – функция чтения байта из датчика;

unsigned int temp()– функция чтения температуры;

unsigned char convert_temp()– функция конвертирования температуры;

void send_com(unsigned char com) – функция отправки команд на дисплей;

void send_data(unsigned char data) – функция отправки данных на дисплей;

void lcd_init (void) – функция инициализации дисплея;

void send_temp(void) – функция отправки температуры на дисплей

.

3.4 Блок-схема программы

Заключение

В ходе написания данной курсовой работы я познакомился с несколькими средами программирования микроконтроллеров. Остановил выбор на программе AVR Studio 4 и подробнее рассмотрел ее работу. Написал и проверил на работоспособность программу на языке «Си» для термометра. Работа над программой позволила понять работу пользовательских функций и их взаимодействия. Проделанная работа в будущем поможет мне в освоении написания новых, более сложных программ для микроконтроллеров.

Список литературы

1. Бродин В.Б., Калинин А.В. Системы на микроконтроллерах и БИС программируемой логики. - М.: Издательство ЭКОМ, 2002 – 400 с.

2. Гребнев В.В. Микроконтроллеры семейства AVR фирмы ATMEL. М.: ИП РадиоСофт, 2002. – 176 с.

3. http://easyelectronics.ru/

4. http://www.kit-e.ru/

5. https://ru.wikipedia.org/

Наши рекомендации