Привет. Вот в этом уроке я покажу вам как быстро спаять простой термометр. Для этого нам понадобиться ATMega8, LCD(16*2), DS18B20, печатная плата, панелька для микроконтроллера.
Итак, приступим, сначала откроем Code Vision AVR. Создаем новый проект, без использования мастера, потом создаем текстовый документ с расширением ".с" и добавляем туда следующий код:
#include <mega8.h> //библиотека ввода\вывода #include <delay.h> //библиотека задержки #asm //сообщаем куда подключен датчик .equ __w1_port=0x15; PORTC .equ __w1_bit=3 #endasm #asm //сообщаем куда подключён экран .equ __lcd_port=0x18 #endasm #include <lcd.h> //библиотека для LCD #include <1wire.h> //библиотека работы с 1Wire #include <ds18b20.h> //библиотека для работы с датчиком ds18b20 #include <stdio.h> //ненаю что за библиотека, но без неё неполучается char lcd_buffer[33]; //масив с данными для экрана void main(void) { unsigned char devices; //переменная в которой количество присоеденённых датчиков int temp; //переменная для хранения температуры lcd_init(16); //инициилизация LCD, и говорим что он на 16 символов devices=w1_init(); //ищим датчики while(devices>0) //бесконечный цикл, если датчик подключон { temp=ds18b20_temperature(0); //читаем температуру if (temp>1000){ //если датчик выдаёт больше 1000 temp=4096-temp; //отнимаем от данных 4096 temp=-temp; //и ставим знак "минус" } sprintf(lcd_buffer,"t=%i.%u\xdfC",temp,temp%1); //записуемв масив для экрана температуру и всё такое lcd_clear(); //чистим дисплей перед выводом lcd_puts(lcd_buffer); //выводим масив на LCD delay_ms(500); //ждём 500мс }; }
потом компилируем и выбираем частоту 8 МГц. Прошиваем, и еще прошиваем фюзы на ту же частоту
Оказывается, в используемом мной даташите на mega328p указаны адреса IO-регистров, увеличенные на 0x20! В других мануалах такие значения приводятся в скобках. Было достаточно внимательнее прочитать второе примечание к таблице "35. Register Summary" на странице 430: «I/O Registers within the address range 0x00 - 0x1F are directly bit-accessible using the SBI and CBI instructions. In these registers, the value of single bits can be checked by using the SBIS and SBIC instructions». Уменьшил значения на 0x20, скомпилировал, собрал, залил и… вуаля:
Собрал схему, запустил прогу на tiny4313, всё работает, но эта крошечная прога съела около 60% флешки. Изначально хотел запустить на mega328p, но там номера портов более 0x20: PORTB 0x24, PORTC 0x28, PORTD 0x2B. Компилятор CVAVR ругается на сроки с командами SBI и CBI: «Operand 1 out of range». Как написано в мануале: «The CBI and SBI instructions work with registers 0x00 to 0x1F only». Настройки компилятора изменять пытался -- не помогло. Эти команды в LCD.LIB заменил на соответствующие группы команд in - ori - out и in - andi - out, так решил часть проблемы. Но оставшиеся проблемные 12 строк, связанные с 1-Wire, где нет либы с ассемблерным текстом, изменить пока не смог -- среди них есть SBIC и SBIS, да и компилировать измененный листинг ведь как-то надо будет... Что подскажете?
смотрите ответ к сообщению 7, на предыдущей страницы, скорее всего, неправильно выставлены фьюзы (не отзеркальте). Настройка фьюзов на стр.30 тех.док. В протеусе они выставляются при двойном щелчке по микроконтроллеру, в CVAvr в Chip Programmer'e справа снизу, в AVR Studio они выставляются и программируются также в специальной вкладке.
Подключил 4-ре датчика DS18B20 к Atmeg16. Сами датчики определяются, считываются в первом цикле. Во втором цикле и далее первый датчик выдает -9999. Если вывожу только три датчика, то первый показывает правильную температуру. Также программа работает если вместо третьего вывожу четвертый датчик. Можно одновременно выводить на LCD (WH1604) только три датчика. В чем причина? Программа написана в CVAVR с использованием стандартных библиотек. Датчики вывожу (и считываю) как float.