| Форум РадиоКот https://radiokot.ru/forum/ |
|
| Еще один термометр на Attiny45 и сдвиговом регистре https://radiokot.ru/forum/viewtopic.php?f=57&t=83954 |
Страница 1 из 1 |
| Автор: | drBOR [ Чт янв 24, 2013 14:52:03 ] | ||||
| Заголовок сообщения: | Еще один термометр на Attiny45 и сдвиговом регистре | ||||
Наводя порядок нашел 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 led_buff[13]; unsigned char reg_buff[3]; unsigned char buf_temp[4] = {0,0,0,11}; //общий анод const char pinot[7] = {1,1,1,1,1,1,1}; // Точкa 0x7F const char one[7] = {1,1,1,1,0,0,1}; // Один 0x4F const char two[7] = {0,1,0,0,1,0,0}; // Два 0x12 const char three[7] = {0,1,1,0,0,0,0}; // Три 0x30 const char four[7] = {0,0,1,1,0,0,1}; // Четыре 0x19 const char five[7] = {0,0,1,0,0,1,0}; // Пять 0x12 const char six[7] = {0,0,0,0,0,1,0}; // Шесть 0x2 const char seven[7] = {1,1,1,1,0,0,0}; // Семь 0x78 const char eight[7] = {0,0,0,0,0,0,0}; // Восемь 0x0 const char nine[7] = {0,0,1,0,0,0,0}; // Девять 0x04 const char zero[7] = {1,0,0,0,0,0,0}; // Ноль 0x01 const char minus[7] = {0,1,1,1,1,1,1}; // Минус 0x3F const char blanc[7] = {1,1,1,1,1,1,1}; // Пусто 0x7F const char reg0[3] = {0,0,0}; const char reg1[3] = {0,1,1}; //Вывод знакомест const char reg2[3] = {1,0,1}; const char reg3[3] = {1,1,0}; int temp; void takt() { PORTB |= _BV(CLK); //установить 1 на PB0 _delay_us(150); PORTB &= ~_BV(CLK); //установить 0 на РВ0 _delay_us(150); } void vpihreg(char digit[3]) { unsigned char i; for (i=0;i<2;i++) { PORTB = (digit[i]<<DATA); // вывод на нужный регистр takt(); } } void vpih(char digit[7]) { unsigned char i=0; for (i=0;i<7;i++) { PORTB = (digit[i]<<DATA); // побитный вывод значения на вывод PB2 takt(); //запуск стробирующего импульса } if (temp>99) { //if (buf_temp[0]<12) { //PORTB |= _BV(TRIG); //установить 1 PB3 PORTB = (1<<TRIG); } else { //PORTB &= ~_BV(TRIG);//установить 0 PB3 PORTB = (0<<TRIG); } PORTB |= _BV(RES); //сигнал защелки на PB1 _delay_us(200); PORTB &= ~_BV(RES);//снять сигнал защелки на PB1 } void reg_temp(signed char temp) { buf_temp[0]=12; //пустое место if (temp<0) { temp=-temp; buf_temp[0]=11; //знак минуса } if (temp>100) { buf_temp[0]=temp/100; 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(100); return buf_temp; _delay_ms(10); } ISR (TIMER1_OVF_vect) { 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); } } } ISR (TIMER0_OVF_vect) { temp = temp_18b20(); if(temp > 1000)//если температура <0 { temp = 4096 - temp; temp = -temp; } reg_temp(temp); } int main(void) { led_buff[0]=zero; led_buff[1]=one; led_buff[2]=two; led_buff[3]=three; led_buff[4]=four; led_buff[5]=five; led_buff[6]=six; led_buff[7]=seven; led_buff[8]=eight; led_buff[9]=nine; led_buff[10]=pinot; led_buff[11]=minus; led_buff[12]=blanc; //0x00; reg_buff[0]=reg0; reg_buff[1]=reg1; reg_buff[2]=reg2; reg_buff[3]=reg0; char buffer[16] = ""; DDRB = 0b00001111; //настроить РВ0-4 на вывод PB5- вход PORTB = 0b00000000; temp = temp_18b20(); if(temp > 1000)//если температура <0 { temp = 4096 - temp; temp = -temp; } reg_temp(temp);//разложение температуры по знакоместам 123 = 1,2,3 - выводит в buf_temp[3] TCCR1 = (1<<CS10);//коэф деления 8 смотри даташит стр.89 TCCR0B = (1<<CS01)|(1<<CS00);// коэф деления Таймера 0В 64 см.стр.79 TCNT1=0xf3; // 243 коррекция счетчика на 1 сек (243+1)/1000000Гц*4096(коэф деления)= 1сек TCNT0 = 0xf3; TIMSK=(1<<TOIE1)|(1<<TOIE0);// включить таймер на внутренние прерывание sei(); //разрешение прерываний while(1){ } }
|
|||||
| Автор: | phanis [ Чт янв 24, 2013 17:06:22 ] |
| Заголовок сообщения: | Re: Еще один термометр на Attiny45 и сдвиговом регистре |
Как вариант можно попробовать подогнать OSCCAL – Oscillator Calibration Register ,хотя с изменением температуры частота все равно будет меняться.. Поэтому нужно сделать авто калибровку обнуляем OSCCAL и пока датчик не отвечает увеличиваем значение OSCCAL. |
|
| Автор: | drBOR [ Чт янв 24, 2013 18:08:53 ] |
| Заголовок сообщения: | Re: Еще один термометр на Attiny45 и сдвиговом регистре |
phanis писал(а): Поэтому нужно сделать авто калибровку обнуляем OSCCAL и пока датчик не отвечает увеличиваем значение OSCCAL. изменение регистра OSCCALя думаю актуально только в случае явного влияния температуры на внутрен RС цепочку применить это можно как термозависимость . Ну а вообще это интересная идея(там только изменять кратному 2), но а вдруг частоты запроса по шине отличаются в разы и есть ошибка, тогда это не поможет. Пока не могу представить как это сделать т.к. не решал еще такую задачу кроме как в AVR DUDE. Определить временные показатели посылки запроса на датчик представляется только по осцилограмме с1-55- все вроде сходится - вопрос - насколько датчик критичен к частоте. Хотя наглядно все нормально, датчик работает неккоректно, по осцилограмме вижу - МК передает зараза 8ки, а не комнатную температуру. В программе работа только двух прерываний по таймеру первое обслуживает индикатор, а только потом начинает работать программа по второму прерыванию для датчика. Датчик впринципе не может влезть в передачу данных на сд.регистр. У меня еще подозрения что датчик не успевает выйти на рабочий режим, хотя все задержки на имитаторе сг. рекомендаций по 1wire. |
|
| Автор: | phanis [ Чт янв 24, 2013 18:59:53 ] |
| Заголовок сообщения: | Re: Еще один термометр на Attiny45 и сдвиговом регистре |
Нужно определится при какой тактовой будет работать сие устройство. F_CPU объявлено 8000000UL а в протеусе все работает на 1 МГц тк фьюз делитель на 8 включен и таймеры тож настроены на тактовую в 1МГц. Формировать точные задержки в несколько микросекунд, при низкой тактовой весьма проблематично. |
|
| Автор: | drBOR [ Чт янв 24, 2013 19:14:40 ] |
| Заголовок сообщения: | Re: Еще один термометр на Attiny45 и сдвиговом регистре |
phanis писал(а): Нужно определится при какой тактовой будет работать сие устройство. Формировать точные задержки в несколько микросекунд, при низкой тактовой весьма проблематично. Кабы изначально было решено 1МГц, т.к. подавляюшее большинство однотипных схем по 18в20 привязано к 1МГц. А в тиньке конструктивно вн. делитель не опустить на ту временную задержку с 8МГЦ (???). Т.к. используются 2 таймера то им более подходит 1МГц |
|
| Автор: | phanis [ Чт янв 24, 2013 19:26:55 ] |
| Заголовок сообщения: | Re: Еще один термометр на Attiny45 и сдвиговом регистре |
Датчик правильно подключен? http://www.google.ru/imgres?um=1&hl=ru& ... 90&bih=660 http://jt5.ru/image/data/examples/DS18B20-schematic.gif http://chipenable.ru/index.php/programm ... ast-1.html В ARES печатной плате 3 пин датчика весит в ввоздухе По поводу OSCCAL он может плавно изменять частоту. The CAL[6:0] bits are used to tune the frequency within the selected range. A setting of 0x00 gives the lowest frequency in that range, and a setting of 0x7F gives the highest frequency in the range. (OSCCAL 0x00 .. 0xFF) меняет от 50 до 200% от номинальной |
|
| Автор: | drBOR [ Пн янв 28, 2013 11:12:00 ] |
| Заголовок сообщения: | Re: Еще один термометр на Attiny45 и сдвиговом регистре |
phanis писал(а): Датчик правильно подключен? В ARES печатной плате 3 пин датчика весит в ввоздухе Прошу прощения забыл указать - Пин VСС датчика специально в воздухе, что бы его по выбору можно было подключить к питанию или земле. По схемам подключения я в курсе:) phanis писал(а): По поводу OSCCAL он может плавно изменять частоту. Попробую реализовать это в ближайшее время, может у кого с временем получше, раньше выложит!? |
|
| Автор: | drBOR [ Пн фев 11, 2013 17:16:37 ] | ||
| Заголовок сообщения: | Re: Еще один термометр на Attiny45 и сдвиговом регистре | ||
Схему немного переработал, после многочисленных попыток так и не получилось адекватно выводить данные с вывода Q7' сдвигового регистра ![]() Код вот Код: #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); } // вывод данных о знакоместе на сд.регистр - два знакоместа void send_reg2(unsigned char reg) { for(unsigned char i = 0; i<2; i++)//в цикле посылаем побитно { if((reg & (2>>i)) == 2>>i)//если бит=1 посылаем 1 { PORTB = (1<<DATA); takt(); //запуск стробирующего импульса } else//иначе посылаем 0 { PORTB = 0<<DATA; takt(); //запуск стробирующего импульса } } } // функция вывода символа(цифры) на сдвиговый регистр void send_data (unsigned char digit) { for(unsigned char i = 1; i <8; i++)//в цикле посылаем побитно { if((digit & (1<<i)) == 1<<i)//если бит=1 посылаем 1 { //PORTB &= ~(1<<DATA); PORTB = (1<<DATA); takt(); //запуск стробирующего импульса } else//иначе посылаем 0 { //PORTB |= 1<<DATA; PORTB = 0<<DATA; takt(); //запуск стробирующего импульса } } if (temp>99) { //вывод еденицы при температуре более 100гр //PORTB |= _BV(TRIG); //установить 1 PB3 PORTB = (1<<TRIG); } else { PORTB = (0<<TRIG); } _delay_us(5); PORTB |= _BV(RES); //сигнал защелки на PB1 _delay_us(20); PORTB &= ~_BV(RES);//снять сигнал защелки на PB1 } //функция разложения значения температуры на сотни.десятки.еденицы градусов 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(); if(temp > 1000)//если температура <0 { temp = 4096 - temp; temp = -temp; } reg_temp(temp); }*/ int main(void) { DDRB = 0b00001111; //настроить РВ0-4 на вывод PB5- вход PORTB = 0b00000000; temp = temp_18b20(); if(temp > 1000)//если температура <0 { temp = 4096 - temp; temp = -temp; } reg_temp(temp);//разложение температуры по знакоместам 123 = 1,2,3 - выводит в buf_temp[3] device_ON();//вывод сигнала ON - при включении TCCR1 = (1<<CS13)|(1<<CS12)|(1<<CS10); TCCR0B = (1<<CS01)|(1<<CS00);// коэф деления Таймера 0В 64 см.стр.79 TCNT1=0xf3; // 243 коррекция счетчика на 1 сек (243+1)/1000000Гц*4096(коэф деления)= 1сек TCNT0 = 0xf3; TIMSK=(1<<TOIE1)|(1<<TOIE0);// включить таймер на внутренние прерывание sei(); //разрешение прерываний while(1){ if (int_data_end == 0) { TCNT1=0xf3; TIMSK= (1<<TOIE1); //обнуление и вывод символа градуса send_reg2(0); send_data(led_table[14]); temp = temp_18b20(); if(temp > 1000)//если температура <0 { temp = 4096 - temp; temp = -temp; } reg_temp(temp); } } } Ну и сборка проекта в Протеусе, исходники и *.hex Все работает!
|
|||
| Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|



