Чтение данных на 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/