Цифровой термометр на Attiny13A и датчике ds18b20

Для оригинальности выбрал AVR studio 5 в качестве среды, писал на C.
вот сам микроконтроллер

Ножек мало, а выводить надо минимум на 3 сегментных дисплея, еще и датчик подключить кудато, в итоге на кнопочку даже места не останется. А теперь посмотрим на выдержку из даташита...

1 килобайт — не густо… и компилятор не компилил больше 1.5килобайта без оптимизации.
немного почитав матчасти и покумекав башкой, выродил вот такую схему

PB0 — управление 3 сдвиговыми регистрами
PB1 — управление 2 светодиодами(знак температуры)
PB2 — свободен
PB3 — свободен
PB4 — подключение самого датчика DS18B20(на схеме изображены штырьки, если хочется — можно наглухо припаять его туда :) )
PB5 — reset
VCC — питание
GND — земля
точки справа с надписями — тоже штырьки(для тех кто захочет модуль с дисплеями и регистрами отдельно по проводу соединить(в этом случае не забудьте про питание и землю))
По поводу питания я не заморачивался, на картинке не нарисовал канеш, в реале у меня там на 100 микрофарад стоит кондер на землю — иначе МК ловит жесткие глюки; а вообще и от 2-х AA работает нормально.
p.s. мне понравился L7805 — очень удобный стабилизатор — используйте его всегда :)
Управление 3 регистрами по 1 проводу — изврат, но этот изврат работает и не жрет я бы сказал много памяти, зато в итоге аж 2 ноги свободные… а резет тупо можно сказать подтянул к питанию, если надо сбросить — заполняем единицами(!!!) и все будет ништяк… а почему единицами? да потому что мои сегментные дисплеи особенные, зажигаются от нулей :)

Kingbright SA04-11GWA — вполне себе приличные дисплейчики, радует что всего 1 резюк к ним подключать надо :)
Сдвиговые регистры самые обычные 74HC164
Велосипед изобретать не пришлось — просто подключил буквы на регистрах к буквам на дисплеях, только точку подключил не к среднему, а к последнему регистру в связке(на рисунке этот момент выделен достаточно жирно), остальные точки оставил висеть в воздухе — они не нужны.
Не забывайте про токоограничительные резисторы на светодиоды — 1 от питания, другой от мк, иначе попрощаетесь с диодом, или хуже того — с контроллером.
Теперь пришло время перейти к особенностям кода:
(опишу лишь некоторые функции, над которыми сам кропел)
void shiftreg(signed char num,char zpt)//разбиение по разрядам
{
if(num<0)//если значение отрицательное
{num=-num; // инвертируем его, знак у нас отдельно выносится
zpt=9-zpt;// знаки после запятой тоже инвертировать надо
}
tochka=1; //включаем точку(в функции это условие учтется)
regout(zpt); // посылаем на обработку дробную часть
regout(num%10);//посылаем единицы на обработку(остаток от деления на 10)
char tmp=num; //запоминаем нум
num/=10;//делим на 10
regout(num%10);//отсылаем десятки
tmp/=100;//делим нум на 100
if(tmp>0)regout(tmp%10);//посылаем сотни,замещают дробный остаток если их >0
}
Интересного в коде — выделение разрядов от числа, может кому-то будет полезно.
void zero(void)//вывод 0 в сегмент
{
PORTB=1<<0 ;//держим линию
_delay_us(5);//курим 5 микросекунд
PORTB=0<<0 ;//выдаем строб
PORTB=1<<0 ;//
}
void one(void)//вывод 1 в сегмент
{
PORTB=0<<0 ;//опускаем линию
_delay_us(5);//курим 5 микросекунд
PORTB=1<<0 ;//поднимаем линию
}
В этом коде показано как по 1 проводу слать биты в регистры, зажигая тем самым сегменты
СЛЕДУЕТ ПОМНИТЬ, ЧТО Я ВЫВОЖУ ИНВЕРСНЫЕ КОДЫ, А В КОМЕНТАХ НАПИСАНО ТО, ЧТО БУДЕТ НА ДИСПЛЕЕ
(т.е. чтобы на сегменте был 0 — надо выдать 1, и наоборот)
Более подробно можно прочитать в переводе немецкой статьи от DI-HALT(ссылка будет в конце)
void digitp(char digit)//Преобразование значений под сегментные дисплеи
{
if(tochka==1)digit|=0x80;
char j=8;
char tmp;
while (j)
{
tmp=digit&0x80;
if(tmp==0)zero();
else one();
digit<<=1;
j--;
}
tochka=0;
}
void regout(char numb)//таблица значений под сегментные регистры
{
asm("cli");
switch(numb)
{
case 1:
digitp(0x06);
break;
case 2:
digitp(0x5B);
break;
case 3:
digitp(0x4F);
break;
case 4:
digitp(0x66);
break;
case 5:
digitp(0x6D);
break;
case 6:
digitp(0x7D);
break;
case 7:
digitp(0x07);
break;
case 8:
digitp(0x7F);
break;
case 9:
digitp(0x6F);
break;
case 0:
digitp(0x3F);
break;
default:
digitp(0x00);
}
asm("sei");
}
Тут обойдусь без комментариев, в кратце — если точка нужна, вставляем 8 бит(он при сдвиге будет последним) и последовательно сдвигаем бит за битом в порт
Преобразование кода чисел в код дисплеев сделано в лоб… думать не хотелось, но памяти вроде не много сожрало(делал в бинарном виде, преобразовывал в шестнадцатеричный)
Саму работу с градусником, может к счастью, может к грусти мне особо осваивать не пришлось… прочитал только принципы, чтобы понимать код, а сам код взял отсюда
www.teslabs.com/openplayer/docs/docs/other/ds18b20_pre1.pdf
Тут в прицнципе на английском все прекрасно написано… но я убрал функцию задержки
и использовал стандартную _delay_us(); Еще немного подправил код
Функция чтения температуры
void therm_read_temperature(void){
//void therm_read_temperature(char *buffer){ - убрал этот буфер - много памяти
asm("cli");
uint8_t temperature[2];
signed char digit; //а тут знак надо
unsigned short decimal; // тут побольше надо памяти, делить на тыщу будем епт
//int8_t digit;//а про эти типы я ниче не знаю
//uint16_t decimal;//
//Резет, пропуск проверки CRC и запуск считывания температуры
therm_reset();
therm_write_byte(THERM_CMD_SKIPROM);
therm_write_byte(THERM_CMD_CONVERTTEMP);
//Ждем пока датчик одуплица
while(!therm_read_bit());
//резет, пропуск проверки CRC, чтение скрэчпада(там наши показания и лежат)
therm_reset();
therm_write_byte(THERM_CMD_SKIPROM);
therm_write_byte(THERM_CMD_RSCRATCHPAD);
//Читаем только 2 первых байта, остальное нам ненадо
temperature[0]=therm_read_byte();
temperature[1]=therm_read_byte();
therm_reset();//резетаем
//Сохраняем целую часть
digit=temperature[0]>>4;
digit|=(temperature[1]&0xf)<<4;
digit++;
//Сохраняем вещественную часть, преобразовываем попутно в чисто от 0 до 9(десятые доли)
decimal=temperature[0]&0xf;
decimal*=THERM_DECIMAL_STEPS_12BIT;
decimal/=1000;
//
asm("sei");
//пуляем эти числа в глобальные переменные, а они уже пойдут на дисплеи
digitemp=digit;
decimtemp=decimal;
}
Полный код со всеми функциями и дефайнами хорошо портируется на любой МК… рассказывать более подробно не вижу смысла, т.к. функция съема температуры — главная задача на данный момент.
Демонстрация работы
фотки жести :)


Исходник на avr studio 5
http://depositfiles.com/files/294abwsun
Датащиты:
tiny13a — www.atmel.com/dyn/resources/prod_documents/doc8126.pdf
ds18b20 — datasheets.maxim-ic.com/en/ds/DS18B20.pdf
mm74hc164 — www.fairchildsemi.com/ds/MM/MM74HC164.pdf
SA04-11GWA — www.us.kingbright.com/images/catalog/SPEC/SA04-11GWA.pdf
Прочее:
Управление дисплеями по 1 проводу
easyelectronics.ru/upravlenie-semisegmentnymi-indikatorami-po-odnomu-provodu.html#more-143
Описание работы с ds18b20 с примерами на Си(англ)
www.teslabs.com/openplayer/docs/docs/other/ds18b20_pre1.pdf
p.s. по поводу того, как BLS обжимать быстро напишу в другом посте :)
p.p.s. время 3 ночи щас, потому могу лажануть орфографией или пунктуацией — не до этого ))
- +2
- 16 апреля 2011, 00:03
- Defvyb
p.s. мне понравился L7805 — очень удобный стабилизатор — используйте его всегда :)В данном случае (батарейное питание) крайне неудачный вывбор т.к. он ест энергию всегда и почем зря. Батарейки прослужат ой как недолго.
Kingbright SA04-11GWA — вполне себе приличные дисплейчики, радует что всего 1 резюк к ним подключать надо :)Какое наивное заблуждение :))) С одним общим резюком яркость горения одного сегмента будет в семь раз ярче горения всех сегментов. Некрасиво :) Поэтому резюк ставят на каждый сегмент
Это заметно только когда единица горит :) 1 цифра — эт допустимо (да и что мешает добавить еще 3 резюка для единицы, всяко меньше чем 7).
Даже на видео, рядом с ярким светодиодом, свет от единички забивает всё :)
А вообще не понятно, почему производители не интегрируют в эти индикаторы обвязку. Допустим подвести туда VCC, GND, и логические уровни на каждый сегмент, а ключи и резисторы внутри. Красота! А если сдвиговый регистр туда засунуть — вообще…
А вообще не понятно, почему производители не интегрируют в эти индикаторы обвязку. Допустим подвести туда VCC, GND, и логические уровни на каждый сегмент, а ключи и резисторы внутри. Красота! А если сдвиговый регистр туда засунуть — вообще…
Да я люблю везде семисегментники лепить. Чётко, ярко, красиво, в отличии от мутных ЖК. Но вот эти резисторы, разводка и прочие прелести напрягают.
А вообще не понятно, почему производители не интегрируют в эти индикаторы обвязку… потому что не так легко получить резистор определенного номинала на кристале
… если замечали в разных даташитах написано… такойта резистор имеет номинал между 10К и 100К, чтоб получить точные номиналы например как в прецизионных ОУ, применяются всякие дорогостоющие технологии, за которые — естественно платит покупатель.
Ну, во первых, светодиоды со строенными резисторами бывают. Там как раз на кристалле AFAIK.
Во вторых, индикатор — это микросборка. Туда вполне можно нанести вполне нормальные резисторы, как в гибридных ИМС.
А вообще, прикольно было бы, если бы туда ставились драйверы вроде MBI*. Это многоканальные генераторы тока с одним задающим резистором на все каналы. Тогда можно и ток задать, и обойтись одним резистором на индикатор (а вместо разрядного ключа — вывод Е драйвера).
Во вторых, индикатор — это микросборка. Туда вполне можно нанести вполне нормальные резисторы, как в гибридных ИМС.
А вообще, прикольно было бы, если бы туда ставились драйверы вроде MBI*. Это многоканальные генераторы тока с одним задающим резистором на все каналы. Тогда можно и ток задать, и обойтись одним резистором на индикатор (а вместо разрядного ключа — вывод Е драйвера).
Эти дисплейчики сожрут намного больше, чем 7805 — на их фоне ее потребление будет незаметно.
А, вообще, проще было применить ATMega48 — выводов бы хватило, а корпусов меньше, программа проще и конструкция дешевле.
А, вообще, проще было применить ATMega48 — выводов бы хватило, а корпусов меньше, программа проще и конструкция дешевле.
У меня вопрос касательно калибровки. Вот вы в обзоре говорите что градусник показывает температуру вашего тела 36.6 градусов. А этот источник температуры стандартизирован, поверен? Вы уверены что там на выходе верные данные?
Я просто чего спрашиваю. У меня тело человеческое выдает немного другие температуры. От 34.5 до 39.8 поэтому не знаю, может у кого-то взять и на том теле проверить?
Я уверен в правильности показаний датчика, так же как и уверен в том, что я относительно здоров и измерения провожу не в жерле вулкана или морозильнике, а при обычной комнатной температуре.
p.s.
Для таких как вы, в даташитах пишут данные о точности.
• Measures temperatures from –55°C to
+125°C (–67°F to +257°F)
• ±0.5°C accuracy from –10°C to +85°C
p.s.
Для таких как вы, в даташитах пишут данные о точности.
• Measures temperatures from –55°C to
+125°C (–67°F to +257°F)
• ±0.5°C accuracy from –10°C to +85°C
В библиотеке вроде как ошибочка — если температура выше 0, то показывается температура на 1 градус больше чем в реале. Тестировал в протеусе.
Очевидно, что для строчки " digit++; " нужно ещё добавить проверку и инкрементировать только если ниже 0.
P.S. Спасибо за труд, очень классный пример по написанию собственной библиотеки и ряд интересных (для меня) приемов кодинга! Все заработало сразу. Использовал AVR Studio 4.19.
Очевидно, что для строчки " digit++; " нужно ещё добавить проверку и инкрементировать только если ниже 0.
P.S. Спасибо за труд, очень классный пример по написанию собственной библиотеки и ряд интересных (для меня) приемов кодинга! Все заработало сразу. Использовал AVR Studio 4.19.
Фейспалм. Я только что пытался собрать проект DS18b20 + tiny13A в CodeVision.
Написал 3 строки кода, опросить термометр записать целую часть температуры в регистр совпадения, подождать 5сек. Скомпилил в 660слов и конечно же пошел лесом. Правда там все функции библиотечные, встроенные. Решил поискать… и вот оно. Я использовал лицензионный кодвижн. Для чего, спрашивается? Хорошо что не я его покупал.
Написал 3 строки кода, опросить термометр записать целую часть температуры в регистр совпадения, подождать 5сек. Скомпилил в 660слов и конечно же пошел лесом. Правда там все функции библиотечные, встроенные. Решил поискать… и вот оно. Я использовал лицензионный кодвижн. Для чего, спрашивается? Хорошо что не я его покупал.
Комментарии (27)
RSS свернуть / развернуть