Наводя порядок нашел tiny45 7сегм. индикатор и НС595й сд.регистр Возникла идея создать на данных элементах термометр в баньку. Весь вкус состоял в том что бы испоьзуя attiny45 с его недостатком ног считать с 18b20 температуру и вывести на 7сегментный индикатор используя только одну ИМС сдвигового регистра. Т.к. елементы были в SOP и SOIC корпусах то конечное устройство должно было получиться миниатюрным и влезть в корпус сгоревшей гал.лампочки под 12В , микросхема датчика температуры размещается на плате или выносным монтажем. Плата изготавливалась с помощью фоторезиста, ЛУТ не проходит т.к. очень мелкая детализация - сд.регистр паялся под лупой. Программу как-то "написал" на AVR C, используя чужие библиотеки 1wire и примеры находящиеся в свободном доступе(не помню чьи) , просьба не ругать а поправить, ну не получается у меня пока разложить 8битовое значение в Atmel Studio - поэтому побитно делал, знаю что некрасиво... Проект "запустил" в Протеусе. Перенес в жизнь и вот не работает. Подозреваю что 18в20 не отслеживает температуру (если без датчика индикатор выводит 00 что и нужно, при подключение датчика - 88??) Видно временные интервалы расчитал неправильно. Ну что коты поможете? http://www.pif-paf.com.ua/img/term.jpg
Код:
#include <avr/io.h> #include <avr/iotn45.h> // библиотека для используемого МК #include <util/delay.h> #include <avr/interrupt.h> #include <avr/wdt.h>
#define F_CPU 8000000UL #define DATA 2 // Подключаем к порту PB2 ножку данных сдвигового регистра #define CLK 0 // Подключаем к порту PB0 ножку тактовых импульсов сдвигового регистра #define RES 1 // Подключаем к порту PB1 ножку защёлки сдвигового регистра #define TRIG 3 // Подключаем к порту PB3 >100/минус
unsigned char i, z; for (z=0; z<40; z++) {//поставим задержку на 10сек, а после идет обработка сл.прерывания на измерение - измерение темп.каждые 10сек for (i=0;i<3;i++) { vpihreg (reg_buff[i]); vpih (led_buff[buf_temp[i]]); _delay_ms(10); } } }
Как вариант можно попробовать подогнать OSCCAL – Oscillator Calibration Register ,хотя с изменением температуры частота все равно будет меняться.. Поэтому нужно сделать авто калибровку обнуляем OSCCAL и пока датчик не отвечает увеличиваем значение OSCCAL.
Поэтому нужно сделать авто калибровку обнуляем OSCCAL и пока датчик не отвечает увеличиваем значение OSCCAL.
изменение регистра OSCCALя думаю актуально только в случае явного влияния температуры на внутрен RС цепочку применить это можно как термозависимость . Ну а вообще это интересная идея(там только изменять кратному 2), но а вдруг частоты запроса по шине отличаются в разы и есть ошибка, тогда это не поможет. Пока не могу представить как это сделать т.к. не решал еще такую задачу кроме как в AVR DUDE. Определить временные показатели посылки запроса на датчик представляется только по осцилограмме с1-55- все вроде сходится - вопрос - насколько датчик критичен к частоте. Хотя наглядно все нормально, датчик работает неккоректно, по осцилограмме вижу - МК передает зараза 8ки, а не комнатную температуру. В программе работа только двух прерываний по таймеру первое обслуживает индикатор, а только потом начинает работать программа по второму прерыванию для датчика. Датчик впринципе не может влезть в передачу данных на сд.регистр. У меня еще подозрения что датчик не успевает выйти на рабочий режим, хотя все задержки на имитаторе сг. рекомендаций по 1wire.
Нужно определится при какой тактовой будет работать сие устройство. F_CPU объявлено 8000000UL а в протеусе все работает на 1 МГц тк фьюз делитель на 8 включен и таймеры тож настроены на тактовую в 1МГц. Формировать точные задержки в несколько микросекунд, при низкой тактовой весьма проблематично.
Нужно определится при какой тактовой будет работать сие устройство. Формировать точные задержки в несколько микросекунд, при низкой тактовой весьма проблематично.
Кабы изначально было решено 1МГц, т.к. подавляюшее большинство однотипных схем по 18в20 привязано к 1МГц. А в тиньке конструктивно вн. делитель не опустить на ту временную задержку с 8МГЦ (???). Т.к. используются 2 таймера то им более подходит 1МГц
Датчик правильно подключен? В ARES печатной плате 3 пин датчика весит в ввоздухе
Прошу прощения забыл указать - Пин VСС датчика специально в воздухе, что бы его по выбору можно было подключить к питанию или земле. По схемам подключения я в курсе:)
phanis писал(а):
По поводу OSCCAL он может плавно изменять частоту.
Попробую реализовать это в ближайшее время, может у кого с временем получше, раньше выложит!?
Схему немного переработал, после многочисленных попыток так и не получилось адекватно выводить данные с вывода Q7' сдвигового регистра , поэтому применил инвертор добавив еще один транзистор Q2 используя один выход Q7, для выравнивания свечения индикации единицы добавлен R7. Программу максимально переписал, значительно сократив код, теперь она занимает меньше половины флеш. Кроме того включена фунция подстройки калибровочной константы для точной подстройки частоты для работы по протоколу 1wire. Схемка получилась вот такая. Пин VCC датчика подключен на +5в. Код вот
Код:
#include <avr/io.h> #include <avr/iotn45.h> // библиотека для используемого МК #define F_CPU 8000000UL #include <util/delay.h> #include <avr/interrupt.h> #include <avr/wdt.h>
#define DATA 2 // Подключаем к порту PB2 ножку данных сдвигового регистра #define CLK 0 // Подключаем к порту PB0 ножку тактовых импульсов сдвигового регистра #define RES 1 // Подключаем к порту PB1 ножку защёлки сдвигового регистра #define TRIG 3 // Подключаем к порту PB3 ножку сигнал - вывести данные
//общий анод - ОСНОВНАЯ таблица символов - данные в 7ми битном значении- нет знака точки const char led_table[15]={0x2,0x9E,0x24,0xC,0x98,0x48,0x40,0x1E,0x0,0x8,0xFC,0xFE,0xC4,0xD4,0x38}; // 0, 1, 2 3 4 5 6 7 8 9,минус,пусто, O N симв.градуса int temp; //глобальная переменная значения температуры unsigned char reg_buff[4]; //временный массив значений знакомест unsigned char buf_temp[4] = {0,0,0,10}; //массив цифр температуры 10-это минус unsigned char int_data_end = 1; //переменная признака конца обработки
//стробирующий импульс на сд.регистр void takt() { PORTB |= _BV(CLK); //установить 1 на PB0 _delay_us(20); PORTB &= ~_BV(CLK); //установить 0 на РВ0 _delay_us(20); }
//функция разложения значения температуры на сотни.десятки.еденицы градусов unsigned char reg_temp(signed char temp) { buf_temp[0]=11; //пустое место if (temp<0) { temp=-temp; buf_temp[0]=10; //знак минуса } if (temp>100) { buf_temp[0]=temp/100; //деление на целое если >100 то 1 temp=temp-100; buf_temp[1]=temp/10; //выделение десятков buf_temp[2]=temp%10; //остаток от деления еденицы градусов } else { buf_temp[1]=temp/10; //выделение десятков buf_temp[2]=temp%10; //остаток от деления еденицы градусов } _delay_ms(10); return buf_temp; //возвращает разложенные значения температуры 123 = {1,2,3} //_delay_ms(10); }
//вывод символов включения ON void device_ON(){ for (char i=12;i<14;i++) { send_reg2(i-11); //вывод знакоместа send_data (led_table[i]);//выводим значение _delay_ms(2); //задержка между посылками } }
//прерывание по 1му таймеру ISR (TIMER1_OVF_vect) { int_data_end = 1; unsigned char i, z; for (z=0; z<20; z++) {//2 на 0.2сек//40 поставим задержку на 10сек, а после идет обработка сл.прерывания на измерение - измерение темп.каждые 10сек for (i=1;i<3;i++) { //обнуление индикаторов /*if (i==1){ send_reg2(0); send_data(led_table[8]); _delay_ms(1); }*/ send_reg2(i); //вывод знакоместа send_data(led_table[buf_temp[i]]);//выводим значения _delay_ms(2); //задержка между посылками } } int_data_end = 0; }
//прерывание по 0таймеру /*ISR (TIMER0_OVF_vect) { //calibrating_osccal(); //калибровка константы osccal - если невозможно связаться с уст.1wire temp = temp_18b20();
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 28
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения