Например TDA7294

Форум РадиоКот • Просмотр темы - Еще один термометр на Attiny45 и сдвиговом регистре
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Пн дек 22, 2025 15:22:37

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 8 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: Еще один термометр на Attiny45 и сдвиговом регистре
СообщениеДобавлено: Чт янв 24, 2013 14:52:03 
Родился
Аватар пользователя

Зарегистрирован: Пн дек 24, 2012 02:56:24
Сообщений: 8
Рейтинг сообщения: 0
Наводя порядок нашел 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){   }
}



Вложения:
и.JPG [95.95 KiB]
Скачиваний: 1575
Комментарий к файлу: Дополнительно проект в atmelStudio
7seg_AStudio.zip [44.03 KiB]
Скачиваний: 173
Комментарий к файлу: Во вложении проект и разводка в Протеусе , библиотеки 1wire исходники на Си , *.hex, *.elf
term.zip [219.63 KiB]
Скачиваний: 172


Последний раз редактировалось drBOR Чт янв 24, 2013 18:23:45, всего редактировалось 2 раз(а).
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Еще один термометр на Attiny45 и сдвиговом регистре
СообщениеДобавлено: Чт янв 24, 2013 17:06:22 
Вымогатель припоя

Зарегистрирован: Сб фев 19, 2011 18:04:08
Сообщений: 513
Откуда: Татарстан, пос. Актюбинский
Рейтинг сообщения: 0
Как вариант можно попробовать подогнать OSCCAL – Oscillator Calibration Register ,хотя с изменением температуры частота все равно будет меняться..
Поэтому нужно сделать авто калибровку обнуляем OSCCAL и пока датчик не отвечает увеличиваем значение OSCCAL.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Еще один термометр на Attiny45 и сдвиговом регистре
СообщениеДобавлено: Чт янв 24, 2013 18:08:53 
Родился
Аватар пользователя

Зарегистрирован: Пн дек 24, 2012 02:56:24
Сообщений: 8
Рейтинг сообщения: 0
phanis писал(а):
Поэтому нужно сделать авто калибровку обнуляем OSCCAL и пока датчик не отвечает увеличиваем значение OSCCAL.

изменение регистра OSCCALя думаю актуально только в случае явного влияния температуры на внутрен RС цепочку применить это можно как термозависимость . Ну а вообще это интересная идея(там только изменять кратному 2), но а вдруг частоты запроса по шине отличаются в разы и есть ошибка, тогда это не поможет. Пока не могу представить как это сделать т.к. не решал еще такую задачу кроме как в AVR DUDE.
Определить временные показатели посылки запроса на датчик представляется только по осцилограмме с1-55- все вроде сходится - вопрос - насколько датчик критичен к частоте. Хотя наглядно все нормально, датчик работает неккоректно, по осцилограмме вижу - МК передает зараза 8ки, а не комнатную температуру.
В программе работа только двух прерываний по таймеру первое обслуживает индикатор, а только потом начинает работать программа по второму прерыванию для датчика. Датчик впринципе не может влезть в передачу данных на сд.регистр. У меня еще подозрения что датчик не успевает выйти на рабочий режим, хотя все задержки на имитаторе сг. рекомендаций по 1wire.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Еще один термометр на Attiny45 и сдвиговом регистре
СообщениеДобавлено: Чт янв 24, 2013 18:59:53 
Вымогатель припоя

Зарегистрирован: Сб фев 19, 2011 18:04:08
Сообщений: 513
Откуда: Татарстан, пос. Актюбинский
Рейтинг сообщения: 0
Нужно определится при какой тактовой будет работать сие устройство. F_CPU объявлено 8000000UL а в протеусе все работает на 1 МГц
тк фьюз делитель на 8 включен и таймеры тож настроены на тактовую в 1МГц. Формировать точные задержки в несколько микросекунд, при низкой тактовой весьма проблематично.


Вернуться наверх
 
Эиком - электронные компоненты и радиодетали
Не в сети
 Заголовок сообщения: Re: Еще один термометр на Attiny45 и сдвиговом регистре
СообщениеДобавлено: Чт янв 24, 2013 19:14:40 
Родился
Аватар пользователя

Зарегистрирован: Пн дек 24, 2012 02:56:24
Сообщений: 8
Рейтинг сообщения: 0
phanis писал(а):
Нужно определится при какой тактовой будет работать сие устройство. Формировать точные задержки в несколько микросекунд, при низкой тактовой весьма проблематично.

Кабы изначально было решено 1МГц, т.к. подавляюшее большинство однотипных схем по 18в20 привязано к 1МГц. А в тиньке конструктивно вн. делитель не опустить на ту временную задержку с 8МГЦ (???). Т.к. используются 2 таймера то им более подходит 1МГц


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Еще один термометр на Attiny45 и сдвиговом регистре
СообщениеДобавлено: Чт янв 24, 2013 19:26:55 
Вымогатель припоя

Зарегистрирован: Сб фев 19, 2011 18:04:08
Сообщений: 513
Откуда: Татарстан, пос. Актюбинский
Рейтинг сообщения: 0
Датчик правильно подключен? 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% от номинальной


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Еще один термометр на Attiny45 и сдвиговом регистре
СообщениеДобавлено: Пн янв 28, 2013 11:12:00 
Родился
Аватар пользователя

Зарегистрирован: Пн дек 24, 2012 02:56:24
Сообщений: 8
Рейтинг сообщения: 0
phanis писал(а):
Датчик правильно подключен? В ARES печатной плате 3 пин датчика весит в ввоздухе

Прошу прощения забыл указать - Пин VСС датчика специально в воздухе, что бы его по выбору можно было подключить к питанию или земле. По схемам подключения я в курсе:)
phanis писал(а):
По поводу OSCCAL он может плавно изменять частоту.

Попробую реализовать это в ближайшее время, может у кого с временем получше, раньше выложит!?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Еще один термометр на Attiny45 и сдвиговом регистре
СообщениеДобавлено: Пн фев 11, 2013 17:16:37 
Родился
Аватар пользователя

Зарегистрирован: Пн дек 24, 2012 02:56:24
Сообщений: 8
Рейтинг сообщения: 0
Схему немного переработал, после многочисленных попыток так и не получилось адекватно выводить данные с вывода 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);
}

// вывод данных о знакоместе на сд.регистр - два знакоместа
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 Все работает!


Вложения:
term.zip [209.41 KiB]
Скачиваний: 196
Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 8 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 28


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y