Обявления

Для полноценной работы рекомендуется пройти регистрацию.

Рекламные сообщения будут удаляться вместе с пользователем. Что есть реклама - буду решать я.

Термометр на Attiny13 і двох DS18B20

Здесь только проекты на ATtiny

Термометр на Attiny13 і двох DS18B20

Сообщение Tetera_Yura » 29 янв 2015 22:39

Доброго Вечора! Прошу Вашої допомоги) Ось сотворив термометр на Attiny13 і двох DS18B20. Вийшло таке:

Один датчик буде на вулиці, другий в домі) Коли натиснута кнопка то показує температуру в домі, а коли не натиснута то на вулиці.
Ось програма, не судіть строго...в програмуванні не сяю) частини програм брав з різних готових проектів, складав все в кучу і підганяв під себе і Attiny):

Код: Выделить всё
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/atomic.h>
#include <avr/wdt.h>
uint8_t a;
uint8_t ROM[ 2 ];
int temp,dig0,dig1,dig2,dig3,temp1;
#define PShift PB2 // сдвиг
#define PData  PB0 // данные
#define PLatch PB1 // вывод

#define bit_set(p,m)  ((p) |= (m))
#define bit_clear(p,m) ((p) &= ~(m))
#define bit_write(c,p,m) (c ? bit_set(p,m) : bit_clear(p,m))
#define BIT(x) (0x01 << (x))
#define STROBE(p) bit_set(PORTB,BIT(p)); bit_clear(PORTB,BIT(p));
#define write_port_bit(data) bit_write(data & 1, PORTB, BIT(PData)); STROBE(PShift);

#define OneWire_setPinAsOutput  DDRB |= (1<<PB4)
#define OneWire_setPinAsInput   DDRB &= ~(1<<PB4)
#define OneWire_writePinLOW     PORTB &=  ~(1<<PB4)
#define OneWire_writePinHIGH    PORTB |= (1<<PB4)
#define OneWire_readPin         ( ( PINB & (1<<PB4) ) ? 1 : 0 )

uint8_t sseg[] = {0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,0x01,0x09,0xFD,0xFF};
uint8_t sseg0[] = {0x02,0x9E,0x24,0x0C,0x98,0x48,0x40,0x1E,0x00,0x08};
uint8_t addr1[]= {0x28,0x6D,0xC2,0xE6,0x03,0x00,0x00,0x92};
uint8_t addr2[]= {0x28,0x38,0x07,0xB3,0x05,0x00,0x00,0x2F};

uint8_t OneWire_reset(){ 
        uint8_t Retries = 125;
        OneWire_setPinAsInput;
        do{
            if( --Retries == 0 ) return 0;
            _delay_us( 2 );
        }while( !OneWire_readPin );
        OneWire_writePinLOW;
        OneWire_setPinAsOutput;
        _delay_us( 480 );     
        OneWire_setPinAsInput;
        _delay_us( 70 );     
        uint8_t State = !OneWire_readPin;
        _delay_us( 410 );
        return State;
    }                   
void OneWire_writeBit( uint8_t Bit ){
        if( Bit & 1 ){
            OneWire_writePinLOW;
            OneWire_setPinAsOutput; 
            _delay_us( 10 );
            OneWire_writePinHIGH;
            _delay_us( 55 );
        }else{           
            OneWire_writePinLOW;
            OneWire_setPinAsOutput;
            _delay_us( 65 );
            OneWire_writePinHIGH;
            _delay_us( 5 );
        }
    }                               
uint8_t OneWire_readBit(){
        OneWire_setPinAsOutput;
        OneWire_writePinLOW;
        _delay_us( 3 );           
        OneWire_setPinAsInput;
        _delay_us( 10 );         
        uint8_t Bit = OneWire_readPin;
        _delay_us( 53 );
        return Bit;
    }                               
void OneWire_writeByte( const uint8_t Byte, uint8_t Power = 0 ){
        for( uint8_t BitMask = 0x01; BitMask; BitMask <<= 1 ) OneWire_writeBit( (BitMask & Byte) ? 1 : 0 );
        if( !Power ){
            OneWire_setPinAsInput;
            OneWire_writePinLOW;
        }
    }                             
inline uint8_t OneWire_readByte(){
        uint8_t Byte = 0;          // - Read all bits
        for( uint8_t BitMask = 0x01; BitMask; BitMask <<= 1 ){
            if( OneWire_readBit() ) Byte |= BitMask;
        }
        return Byte;
    }                             
inline void OneWire_read( uint8_t * Buffer, uint8_t Size ){
        for( uint8_t i = 0; i < Size; i++ ) Buffer[ i ] = OneWire_readByte();
    }                           
inline void OneWire_write(const uint8_t * Buffer, uint8_t Size, uint8_t Power = 0 ){
        for( uint8_t i = 0; i < Size; i++ )  OneWire_writeByte(  Buffer[ i ] );
        if( !Power ){       
            OneWire_setPinAsInput;
            OneWire_writePinLOW;
        }
    }   
void write_port_byte(uint8_t data) {
   for (uint8_t i=0;i<8;i++) {
   write_port_bit(data); data = data >> 1;
  }
}
ISR(SIG_OVERFLOW0)
{
temp=temp+1;
}
SIGNAL(SIG_PIN_CHANGE0)
{
  if (bit_is_set(PINB,PB3))
  a=1;  else a=0; 
}     
void lcd() {
  //STROBE(PLatch);
  if (dig0==0) {
  write_port_byte(0xEF);
  write_port_byte(0xFD);
  STROBE(PLatch);
} else {
  write_port_byte(0xEF);
  write_port_byte(0xFF);
  STROBE(PLatch);

  if (dig1==0) {
  write_port_byte(0xDF);
  write_port_byte(0xFF);
  STROBE(PLatch);
  write_port_byte(0xBF);
  write_port_byte(sseg0[dig2]);
  STROBE(PLatch);
  write_port_byte(0x7F);
  write_port_byte(sseg[dig3]);
  STROBE(PLatch);
} else {
  write_port_byte(0xDF);
  write_port_byte(sseg[dig1]);
  STROBE(PLatch);
  write_port_byte(0xBF);
  write_port_byte(sseg0[dig2]);
  STROBE(PLatch);
  write_port_byte(0x7F);
  write_port_byte(sseg[dig3]);
  STROBE(PLatch);
  }
  }
void tempe() {
  OneWire_reset();
  OneWire_writeByte( 0x55, 1 );
  if (a==1)
  OneWire_write( addr2, sizeof( addr2 ) );
  else
  OneWire_write( addr1, sizeof( addr1 ) );
  OneWire_writeByte( 0xBE, 1 );
  OneWire_read( ROM, sizeof( ROM ) );
  OneWire_reset();
  OneWire_writeByte( 0xCC, 1 );
  OneWire_writeByte( 0x44, 1 );
  ConvTempDi(); 
}
void ConvTempDi()
{
unsigned int tempint;//,tempint1,tempint2,tempint3; // переменные для целого значения температуры
unsigned int temppoint,temppoint1; // переменные для дробного значения температуры
unsigned char Temp_H,Temp_L,temp_flag;

Temp_L = ROM[0]; // читаем первые 2 байта
Temp_H = ROM[1];
temp_flag = 1;         // флаг знака температуры равен 1(плюс)

if(Temp_H &(1 << 3))   // проверяем бит знака температуры на равенство единице
{         
signed int tmp;
temp_flag = 0;      // флаг знака равен 0(минус)
tmp = (Temp_H << 8) | Temp_L;
tmp = -tmp;
Temp_L = tmp;
Temp_H = tmp >> 8; }     
tempint = ((Temp_H << 4) & 0x70)|(Temp_L >> 4); // вычисляем целое значение температуры
temppoint = Temp_L & 0x0F; // вычисляем дробное значение температуры
temppoint = temppoint * 625;     
temppoint1 = temppoint / 1000;
dig0 = temp_flag;
dig1 = tempint /10;
dig2 = tempint % 10;
dig3 = temppoint1;
}
int main(void) {
  a=0;
  DDRB = 1<<PShift|1<<PData|1<<PLatch;
  PORTB &= ~(1<<PShift|1<<PLatch);
  TCCR0A = 0;
  TCCR0B = 0b00000101; //делитель
  TIMSK0 = 0b00000010; // Разрешение прерываний по переполнению
  GIMSK = 0b00100000;  // Разрешение прерываний PCINTn
  PCMSK = 0b00001000;  // прерывание по входу PCINT1 (PB1)       
  sei();

while(1) {
 
if (temp>10){
tempe();
temp=0;}
lcd();

}
}

Питання ось в чому, все ніби не погано працює.
Але при зчитуванні температури з датчика присутнє одноразове моргання індикатора.
Можливо хтось побачить помилку в програмі і підскаже) бо я щось не можу її знайти) на мою думку це якесь переприсвоєння при спілкуванні з датчиком, або проблема в самому контролері (можливо він не справляється). Але більше всього це я не справляюсь з ним)) Допоможіть, кому не складно) Дякую!)
Последний раз редактировалось Tetera_Yura 02 фев 2015 22:25, всего редактировалось 1 раз.
Tetera_Yura
Пробегал мимо
 
Сообщения: 13
Зарегистрирован: 29 янв 2015 21:21

Re: Термометр на Attiny13 і двох DS18B20

Сообщение IYra » 30 янв 2015 10:39

Чтобы легче понять проблему желательно сразу выкладывать весь материал (Схему, проект)
и на русском.
И вообще к чему такие сложности. Есть же термометр на 2313 для 2-х датчиков и кнопки нажимать не надо
http://hardlock.org.ua/viewtopic.php?f=9&t=17&start=600#p10859
IYra
Живу тут
 
Сообщения: 535
Зарегистрирован: 01 фев 2012 19:36
Откуда: Санкт-Петербург

Re: Термометр на Attiny13 і двох DS18B20

Сообщение Tetera_Yura » 30 янв 2015 20:11

З російською в мене складно) а чому 13...сам не знаю) так вирішив, так і зробив, переробляти вже не буду. Хочу це довести до толку.
Ось схема, вибачайте що в такому варіанті) весь мій проект вмістився на 2 листках А4.

Кнопка для зручності, мені більше потрібна температура на вулиці, а коли потрібно в домі то нажав, подивився і все)
Я розумію що на 23 було б простіше, але трішки пізно вже)
Тим більше що в мене все вийшло і все працює. Просто невеличкий глюк, який хотілось би прибрати) тоді буде квітка)
Дякую!
Tetera_Yura
Пробегал мимо
 
Сообщения: 13
Зарегистрирован: 29 янв 2015 21:21

Re: Термометр на Attiny13 і двох DS18B20

Сообщение IYra » 30 янв 2015 21:31

Попробуй функцию lcd() вставить в функции OneWire_write и OneWire_read
в цикл for
например так
inline void OneWire_read( uint8_t * Buffer, uint8_t Size )
{
for( uint8_t i = 0; i < Size; i++ )
{
Buffer[ i ] = OneWire_readByte();
lcd() ;
}
}
IYra
Живу тут
 
Сообщения: 535
Зарегистрирован: 01 фев 2012 19:36
Откуда: Санкт-Петербург

Re: Термометр на Attiny13 і двох DS18B20

Сообщение Tetera_Yura » 30 янв 2015 23:56

Ну здається напрям правильний) я прибрав таймер, в головному циклі в мене тільки функція lcd(), а в lcd() дописав зчитування з датчика, короче глянь будь-ласка)

Код: Выделить всё
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/atomic.h>
#include <avr/wdt.h>
uint8_t a;
uint8_t ROM[ 2 ];
int dig0,dig1,dig2,dig3;
#define PShift PB2 // сдвиг
#define PData  PB0 // данные
#define PLatch PB1 // вывод

#define bit_set(p,m)  ((p) |= (m))
#define bit_clear(p,m) ((p) &= ~(m))
#define bit_write(c,p,m) (c ? bit_set(p,m) : bit_clear(p,m))
#define BIT(x) (0x01 << (x))
#define STROBE(p) bit_set(PORTB,BIT(p)); _delay_us(200); bit_clear(PORTB,BIT(p));
#define write_port_bit(data) bit_write(data & 1, PORTB, BIT(PData)); STROBE(PShift);

#define OneWire_setPinAsOutput  DDRB |= (1<<PB4)
#define OneWire_setPinAsInput   DDRB &= ~(1<<PB4)
#define OneWire_writePinLOW     PORTB &=  ~(1<<PB4)
#define OneWire_writePinHIGH    PORTB |= (1<<PB4)
#define OneWire_readPin         ( ( PINB & (1<<PB4) ) ? 1 : 0 )

uint8_t sseg[] = {0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,0x01,0x09,0xFD,0xFF};
uint8_t sseg0[] = {0x02,0x9E,0x24,0x0C,0x98,0x48,0x40,0x1E,0x00,0x08};
uint8_t addr1[]= {0x28,0x6D,0xC2,0xE6,0x03,0x00,0x00,0x92};
uint8_t addr2[]= {0x28,0x38,0x07,0xB3,0x05,0x00,0x00,0x2F};

uint8_t OneWire_reset(){  // - Wait for line
        uint8_t Retries = 125;
        OneWire_setPinAsInput;
        do{
            if( --Retries == 0 ) return 0;
            _delay_us( 2 );
        }while( !OneWire_readPin ); // - Drop line
        OneWire_writePinLOW;
        OneWire_setPinAsOutput;
        _delay_us( 480 );     // - Listen for reply pulse
        OneWire_setPinAsInput;
       _delay_us( 70 );     // - Read line state
        uint8_t State = !OneWire_readPin;
        _delay_us( 410 );
        return State;
    }                     //! Write single bit
void OneWire_writeBit( uint8_t Bit ){
        if( Bit & 1 ){       // - Drop line
            OneWire_writePinLOW;
            OneWire_setPinAsOutput;  // - Write Bit-1
            _delay_us( 10 );
            OneWire_writePinHIGH;
            _delay_us( 55 );
        }else{           // - Drop line
            OneWire_writePinLOW;
            OneWire_setPinAsOutput;  // - Write Bit-0
            _delay_us( 65 );
            OneWire_writePinHIGH;
            _delay_us( 5 );
        }
   }                                //! Read single bit
uint8_t OneWire_readBit(){       // - Drop line
        OneWire_setPinAsOutput;
        OneWire_writePinLOW;
        _delay_us( 3 );              // - Wait for data
        OneWire_setPinAsInput;
        _delay_us( 10 );             // - Read bit into byte
        uint8_t Bit = OneWire_readPin;
        _delay_us( 53 );
        return Bit;
    }                                //! Write byte
void OneWire_writeByte( const uint8_t Byte, uint8_t Power = 0 ){
        for( uint8_t BitMask = 0x01; BitMask; BitMask <<= 1 ) OneWire_writeBit( (BitMask & Byte) ? 1 : 0 );
        if( !Power ){
            OneWire_setPinAsInput;
            OneWire_writePinLOW;
        }
    }                              //! Read byte
inline uint8_t OneWire_readByte(){
        uint8_t Byte = 0;          // - Read all bits
        for( uint8_t BitMask = 0x01; BitMask; BitMask <<= 1 ){
            if( OneWire_readBit() ) Byte |= BitMask;
        }
        return Byte;
    }                             //! Read buffer
inline void OneWire_read( uint8_t * Buffer, uint8_t Size ){
        for( uint8_t i = 0; i < Size; i++ ) Buffer[ i ] = OneWire_readByte();
    }                            //! Write buffer
inline void OneWire_write(const uint8_t * Buffer, uint8_t Size, uint8_t Power = 0 ){
        for( uint8_t i = 0; i < Size; i++ )  OneWire_writeByte(  Buffer[ i ] );
        if( !Power ){            // - Disable power
            OneWire_setPinAsInput;
            OneWire_writePinLOW;
        }
    }   
void write_port_byte(uint8_t data) {
   for (uint8_t i=0;i<8;i++) {
   write_port_bit(data); data = data >> 1;
  }
}
SIGNAL(SIG_PIN_CHANGE0)
{
  if (bit_is_set(PINB,PB3))
  a=1;  else a=0; 
}     
void lcd() {
  uint8_t t=0.25;
  OneWire_reset();
  OneWire_writeByte( 0x55, 1 );
  if (a==1)
  OneWire_write( addr2, sizeof( addr2 ) );
  else
  OneWire_write( addr1, sizeof( addr1 ) );
  OneWire_writeByte( 0xBE, 1 );
  OneWire_read( ROM, sizeof( ROM ) );

  bit_clear(PORTB,BIT(PLatch));
  if (dig0==0) {
  write_port_byte(0xEF);
  write_port_byte(0xFD);
  } else {
  write_port_byte(0xEF);
  write_port_byte(0xFF);
  }
  bit_set(PORTB,BIT(PLatch));
  _delay_ms(t);
  bit_clear(PORTB,BIT(PLatch));
  if (dig1==0) {
  write_port_byte(0xDF);
  write_port_byte(0xFF);
  bit_set(PORTB,BIT(PLatch));
  _delay_ms(t);
  bit_clear(PORTB,BIT(PLatch));
  write_port_byte(0xBF);
  write_port_byte(sseg0[dig2]);
  bit_set(PORTB,BIT(PLatch));
  _delay_ms(t);
  bit_clear(PORTB,BIT(PLatch));
  write_port_byte(0x7F);
  write_port_byte(sseg[dig3]);
  bit_set(PORTB,BIT(PLatch));
} else {
  write_port_byte(0xDF);
  write_port_byte(sseg[dig1]);
  bit_set(PORTB,BIT(PLatch));
  _delay_ms(t);
  bit_clear(PORTB,BIT(PLatch));
  write_port_byte(0xBF);
  write_port_byte(sseg0[dig2]);
  bit_set(PORTB,BIT(PLatch));
  _delay_ms(t);
  bit_clear(PORTB,BIT(PLatch));
  write_port_byte(0x7F);
  write_port_byte(sseg[dig3]);
  bit_set(PORTB,BIT(PLatch));
  }
 
  OneWire_reset();
  OneWire_writeByte( 0xCC, 1 );
  OneWire_writeByte( 0x44, 1 );  // - Wait until conversion finished
  ConvTempDi();
  }
void ConvTempDi()
{
unsigned int tempint;//,tempint1,tempint2,tempint3; // переменные для целого значения температуры
unsigned int temppoint,temppoint1; // переменные для дробного значения температуры
unsigned char Temp_H,Temp_L,temp_flag;

Temp_L = ROM[0]; // читаем первые 2 байта блокнота
Temp_H = ROM[1];
temp_flag = 1;         // флаг знака температуры равен 1(плюс)

if(Temp_H &(1 << 3))   // проверяем бит знака температуры на равенство единице
{         
signed int tmp;
temp_flag = 0;      // флаг знака равен 0(минус)
tmp = (Temp_H << 8) | Temp_L;
tmp = -tmp;
Temp_L = tmp;
Temp_H = tmp >> 8; }     
tempint = ((Temp_H << 4) & 0x70)|(Temp_L >> 4); // вычисляем целое значение температуры
temppoint = Temp_L & 0x0F; // вычисляем дробное значение температуры
temppoint = temppoint * 625;       // точность температуры
temppoint1 = temppoint / 1000;
dig0 = temp_flag;
dig1 = tempint /10;
dig2 = tempint % 10;
dig3 = temppoint1;
}
int main(void) {
  a=0;
  DDRB = 1<<PShift|1<<PData|1<<PLatch;
  PORTB &= ~(1<<PShift|1<<PLatch);
  GIMSK = 0b00100000;  // Разрешение прерываний PCINTn
  PCMSK = 0b00001000;  // прерывание по входу PCINT1 (PB1)       
  sei();

while(1) {
 
lcd();

}
}


Але останній розряд чомусь світиться яскравіше. Що це може бути?
Последний раз редактировалось Tetera_Yura 02 фев 2015 22:24, всего редактировалось 1 раз.
Tetera_Yura
Пробегал мимо
 
Сообщения: 13
Зарегистрирован: 29 янв 2015 21:21

Re: Термометр на Attiny13 і двох DS18B20

Сообщение IYra » 31 янв 2015 10:09

Tetera_Yura писал(а):Але останній розряд чомусь світиться яскравіше. Що це може бути?

Потому-что не выключается в конце и остается включенным большее время. Визуально кажется ярче
Это обратная сторона выключения. Если выключать - моргает. Если оставлять включенным - горит ярче.
Поэтому что-бы динамическая индикация была нормальная - ее лучше выводить через прерывания по таймеру
У меня сделано так.
Настроено срабатывание таймера на 4 мсек. При каждом срабатывании включается один разряд по порядку 1.2.3.4
и не выключается. Через 4 мсек этот разряд выключается - включается следующий и так по кругу. Получается 16 мсек
на вывод 4 цифр (1000/16 = 60 Гц)
Обращение к датчикам тоже в таймере. Поставить счетчик++ и если счетчик=250 (1 сек) читать Температуру
Ну примерно так
И не стоит все засовывать в одну функцию. Надо отделять мух от котлет.
И выкладывать код лучше так
Код: Выделить всё
bit_clear(PORTB,BIT(PLatch));
write_port_byte(0x7F);
write_port_byte(sseg[dig3]);
bit_set(PORTB,BIT(PLatch));

а еще лучше присоединять файл проекта
А что там по поводу
Попробуй функцию lcd() вставить в функции OneWire_write и OneWire_read
Какой эффект от этого ?
IYra
Живу тут
 
Сообщения: 535
Зарегистрирован: 01 фев 2012 19:36
Откуда: Санкт-Петербург

Re: Термометр на Attiny13 і двох DS18B20

Сообщение Tetera_Yura » 31 янв 2015 19:42

Ефекту не було ніякого) Коли читав температуру через таймер з lcd() в OneWire_write и OneWire_read то нічого не показувало взагалі, а коли убирав таймер і читав температуру постійно, виводило чортзна що. До того всього в мене все було поділенно, то зараз я вже наворотив тут) і пробував я lcd() через таймер і температуру, тоді виходить той самий ефект, коли при зчитуванні температури моргає індикатор. Добре код буду викладати як скажеш, я тут новий, ще не знав) Дякую.
Виходить він в тебе 4 мсек світиться і виключається, і тоді включається інший, і так по кругу? Виходить коли він читає чи відправляє байти датчику то призупиняється робота індикатора, а коли я ставлю функцію індикатора в таймер то він не встигає читати температуру. Бо я так розумію приорітет по перериванню при переповненні таймера, чи не так? Я толком не знаю, логічно просто що переривання має більший приорітет.
Tetera_Yura
Пробегал мимо
 
Сообщения: 13
Зарегистрирован: 29 янв 2015 21:21

Re: Термометр на Attiny13 і двох DS18B20

Сообщение IYra » 31 янв 2015 20:21

Функцию индикатора надо ставить в прерывание по таймеру чтобы были равные интервалы включения
разрядов и не было моргания. Прерывание имеет приоритет - поэтому в критичных местах (чтение и запись 1-Wire)
надо запрещать прерывания cli() а затем разрешать sei()
Код: Выделить всё

write_port_byte(0xBF);
write_port_byte(sseg0[dig2]);
STROBE(PLatch);

этот код выводит один разряд. В таймере надо через каждые 4мс вызывать соответсвующий кусок
функции LCD(pos) - где pos - это разряд
А в функции OneWire_readByte() и OneWire_writeByte() вставить в цикл cli() и sei()
Код: Выделить всё
inline uint8_t OneWire_readByte()
{
  uint8_t Byte = 0; // - Read all bits
  for( uint8_t BitMask = 0x01; BitMask; BitMask <<= 1 )
  {
    cli() ;
     if( OneWire_readBit()) Byte |= BitMask;
    sei() ;
  }
return Byte;
}
IYra
Живу тут
 
Сообщения: 535
Зарегистрирован: 01 фев 2012 19:36
Откуда: Санкт-Петербург

Re: Термометр на Attiny13 і двох DS18B20

Сообщение Tetera_Yura » 31 янв 2015 20:32

Дякую) завтра спробую. Сьогодні вже сил не маю...закриття сезону полювання)

Добавлено спустя 23 часа 1 минуту 53 секунды:
А можеш підсказати як правильно оформити функцію lcd щоб виводилось кожні 4 мсек інший сегмент. Дякую.
Пробував кидати цілу lcd в таймер і вставив cli i sei в читання і запис байтів, то нічого не вийшло, немає обміну з датчиком. Але покази були якогось не зрозумілого числа.
Tetera_Yura
Пробегал мимо
 
Сообщения: 13
Зарегистрирован: 29 янв 2015 21:21

Re: Термометр на Attiny13 і двох DS18B20

Сообщение IYra » 01 фев 2015 21:43

Tetera_Yura писал(а):А можеш підсказати як правильно оформити функцію lcd щоб виводилось кожні 4 мсек інший сегмент.

Ну это надо таймер настроить
Код: Выделить всё
TCCR0B = 0b00000101; //делитель

заменить на
Код: Выделить всё
TCCR0B = 0b00000100; //делитель

прерывания будут каждые 6 мс
затем в само прерывание вставить вызов lcd(Pos)
Код: Выделить всё
ISR(SIG_OVERFLOW0)
{
temp=temp+1;
}

заменить на
Код: Выделить всё
ISR(SIG_OVERFLOW0)
{
temp=temp+1;
lcd(pos) ;
pos++;
if (pos>3) pos=0 ;
}

не забыть обьявить pos
Затем меняем lcd()
Код: Выделить всё
void lcd(uint8_t pos)
{
if (pos==0)
{
   if (dig0==0)
   {
     write_port_byte(0xEF);
     write_port_byte(0xFD);
    STROBE(PLatch);
   }
   else
   {
     write_port_byte(0xEF);
     write_port_byte(0xFF);
     STROBE(PLatch);
   }
}
else if (pos==1)
.......
else if (pos==2)
.......
else if (pos==3)
.......

}

Ну и последний штрих
заменить
Код: Выделить всё
while(1)
{
   if (temp>10){
   tempe();
   temp=0;}
   lcd();
}

на
Код: Выделить всё
while(1) {
if (temp>100){
tempe();
temp=0;}
}
IYra
Живу тут
 
Сообщения: 535
Зарегистрирован: 01 фев 2012 19:36
Откуда: Санкт-Петербург

Re: Термометр на Attiny13 і двох DS18B20

Сообщение Tetera_Yura » 01 фев 2015 23:06

Зробив все як ти сказав. Вийшло так:
Код: Выделить всё
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/atomic.h>
#include <avr/wdt.h>
uint8_t a=0;
uint8_t ROM[ 2 ];
int dig0,dig1,dig2,dig3,temp;
uint8_t pos;
#define PShift PB2 // сдвиг
#define PData  PB0 // данные
#define PLatch PB1 // вывод

#define bit_set(p,m)  ((p) |= (m))
#define bit_clear(p,m) ((p) &= ~(m))
#define bit_write(c,p,m) (c ? bit_set(p,m) : bit_clear(p,m))
#define BIT(x) (0x01 << (x))
#define STROBE(p) bit_set(PORTB,BIT(p)); bit_clear(PORTB,BIT(p));
#define write_port_bit(data) bit_write(data & 1, PORTB, BIT(PData)); STROBE(PShift);

#define OneWire_setPinAsOutput  DDRB |= (1<<PB4)
#define OneWire_setPinAsInput   DDRB &= ~(1<<PB4)
#define OneWire_writePinLOW     PORTB &=  ~(1<<PB4)
#define OneWire_writePinHIGH    PORTB |= (1<<PB4)
#define OneWire_readPin         ( ( PINB & (1<<PB4) ) ? 1 : 0 )

uint8_t sseg[] = {0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,0x01,0x09,0xFD,0xFF};
uint8_t sseg0[] = {0x02,0x9E,0x24,0x0C,0x98,0x48,0x40,0x1E,0x00,0x08};
uint8_t addr1[]= {0x28,0x6D,0xC2,0xE6,0x03,0x00,0x00,0x92};
uint8_t addr2[]= {0x28,0x38,0x07,0xB3,0x05,0x00,0x00,0x2F};

uint8_t OneWire_reset(){  // - Wait for line
        uint8_t Retries = 125;
        OneWire_setPinAsInput;
        do{
            if( --Retries == 0 ) return 0;
            _delay_us( 2 );
        }while( !OneWire_readPin ); // - Drop line
        OneWire_writePinLOW;
        OneWire_setPinAsOutput;
        _delay_us( 480 );     // - Listen for reply pulse
        OneWire_setPinAsInput;
       _delay_us( 70 );     // - Read line state
        uint8_t State = !OneWire_readPin;
        _delay_us( 410 );
        return State;
    }                     //! Write single bit
void OneWire_writeBit( uint8_t Bit ){
        if( Bit & 1 ){       // - Drop line
            OneWire_writePinLOW;
            OneWire_setPinAsOutput;  // - Write Bit-1
            _delay_us( 10 );
            OneWire_writePinHIGH;
            _delay_us( 55 );
        }else{           // - Drop line
            OneWire_writePinLOW;
            OneWire_setPinAsOutput;  // - Write Bit-0
            _delay_us( 65 );
            OneWire_writePinHIGH;
            _delay_us( 5 );
        }
}                                //! Read single bit
uint8_t OneWire_readBit(){       // - Drop line
        OneWire_setPinAsOutput;
        OneWire_writePinLOW;
        _delay_us( 3 );              // - Wait for data
        OneWire_setPinAsInput;
        _delay_us( 10 );             // - Read bit into byte
        uint8_t Bit = OneWire_readPin;
        _delay_us( 53 );
        return Bit; 
  }                                //! Write byte
void OneWire_writeByte( const uint8_t Byte, uint8_t Power = 0 ){
        for( uint8_t BitMask = 0x01; BitMask; BitMask <<= 1 ) OneWire_writeBit( (BitMask & Byte) ? 1 : 0 );
        if( !Power ){
            OneWire_setPinAsInput;
            OneWire_writePinLOW;
            }
      }                              //! Read byte
inline uint8_t OneWire_readByte(){
        uint8_t Byte = 0;          // - Read all bits
        for( uint8_t BitMask = 0x01; BitMask; BitMask <<= 1 ){
            if( OneWire_readBit() ) Byte |= BitMask;
         }
        return Byte;
    }                             //! Read buffer
inline void OneWire_read( uint8_t * Buffer, uint8_t Size ){
        for( uint8_t i = 0; i < Size; i++ )
          Buffer[ i ] = OneWire_readByte();
  }                            //! Write buffer
inline void OneWire_write(const uint8_t * Buffer, uint8_t Size, uint8_t Power = 0 ){
        for( uint8_t i = 0; i < Size; i++ )
          OneWire_writeByte(  Buffer[ i ] );
        if( !Power ){            // - Disable power
            OneWire_setPinAsInput;
            OneWire_writePinLOW;
        }
    }   
void write_port_byte(uint8_t data) {
   for (uint8_t i=0;i<8;i++) {
   write_port_bit(data); data = data >> 1;
  }
}
ISR(SIG_OVERFLOW0)
{
 
temp=temp+1;
lcd(pos);
pos++;
if (pos>3) pos=0;
}

void lcd(uint8_t pos) {
  if (pos==0) {
  write_port_byte(0xEF);
  write_port_byte(sseg[dig0]);
STROBE(PLatch); }
  if (pos==1) {
  write_port_byte(0xDF);
  write_port_byte(sseg[dig1]);
STROBE(PLatch);}
if (pos==2) {
  write_port_byte(0xBF);
  write_port_byte(sseg0[dig2]);
  STROBE(PLatch);}
if (pos==3) {
  write_port_byte(0x7F);
  write_port_byte(sseg[dig3]);
STROBE(PLatch);
}
   }
void tempe()
{
  OneWire_reset();
  OneWire_writeByte( 0x55, 1 );
  if (a==1)
  OneWire_write( addr2, sizeof( addr2 ) );
  else
  OneWire_write( addr1, sizeof( addr1 ) );
  OneWire_writeByte( 0xBE, 1 );
  OneWire_read( ROM, sizeof( ROM ) );
  OneWire_reset();
  OneWire_writeByte( 0xCC, 1 );
  OneWire_writeByte( 0x44, 1 );  // - Wait until conversion finished
ConvTempDi();
}

void ConvTempDi()
{
unsigned int tempint;//,tempint1,tempint2,tempint3; // переменные для целого значения температуры
unsigned int temppoint,temppoint1; // переменные для дробного значения температуры
unsigned char Temp_H,Temp_L,temp_flag;

Temp_L = ROM[0]; // читаем первые 2 байта блокнота
Temp_H = ROM[1];
temp_flag = 1;         // флаг знака температуры равен 1(плюс)

if(Temp_H &(1 << 3))   // проверяем бит знака температуры на равенство единице
{         
signed int tmp;
temp_flag = 0;      // флаг знака равен 0(минус)
tmp = (Temp_H << 8) | Temp_L;
tmp = -tmp;
Temp_L = tmp;
Temp_H = tmp >> 8; }     
tempint = ((Temp_H << 4) & 0x70)|(Temp_L >> 4); // вычисляем целое значение температуры
temppoint = Temp_L & 0x0F; // вычисляем дробное значение температуры
temppoint = temppoint * 625;       // точность температуры
temppoint1 = temppoint / 1000;
if (temp_flag==0)
dig0 = 10; else
dig0 = 11;
dig1 = tempint /10;
if (dig1==0) dig1=11;
dig2 = tempint % 10;
dig3 = temppoint1;
}

int main(void) {
// a=0;
  TCCR0A = 0;
  TCCR0B = 0b00000100; //делитель
  TIMSK0 = 0b00000010; // Разрешение прерываний по переполнению
  DDRB = 1<<PShift|1<<PData|1<<PLatch;
  PORTB &= ~(1<<PShift|1<<PLatch);
  GIMSK = 0b00100000;  // Разрешение прерываний PCINTn
  PCMSK = 0b00001000;  // прерывание по входу PCINT1 (PB1)       
  sei();

while(1) {
 
if (temp>100){
  tempe();
temp=0;
}

}
}

Але нічого не получилось... стандартно показує 003.0. Якась халепа( Дякую!
Tetera_Yura
Пробегал мимо
 
Сообщения: 13
Зарегистрирован: 29 янв 2015 21:21

Re: Термометр на Attiny13 і двох DS18B20

Сообщение IYra » 02 фев 2015 11:06

Tetera_Yura писал(а):Але нічого не получилось... стандартно показує 003.0.

Ну тогда давай так. На чем пишешь ? И прикрепи запакованный файл проекта
(если войти через цитату там есть возможность)


В CodeVisionAVR 2.05 сделал что-то похожее. Там выводится один датчик
На модели в Протеусе вроде работало (только без выходных транзисторов)
Попробуй в реале
Вложения
term.rar
(1.31 КБ) Скачиваний: 72
IYra
Живу тут
 
Сообщения: 535
Зарегистрирован: 01 фев 2012 19:36
Откуда: Санкт-Петербург

Re: Термометр на Attiny13 і двох DS18B20

Сообщение Tetera_Yura » 02 фев 2015 19:58

Прошиваю через Arduino ISP. Ось проект. Дякую!)
Це останній варіант, який показує 000,3.
Вложения
two_termp2_2.rar
(2.17 КБ) Скачиваний: 64
Tetera_Yura
Пробегал мимо
 
Сообщения: 13
Зарегистрирован: 29 янв 2015 21:21

Re: Термометр на Attiny13 і двох DS18B20

Сообщение IYra » 02 фев 2015 21:06

Tetera_Yura писал(а):Прошиваю через Arduino ISP. Ось проект.

Среда разработки то какая ? Ардуино что-ли ?
Я попробовал открыть и скомпилировать скетч в Ардуино. Выдало кучу ошибок

А что там с моим хексом на CodeVisionAVR 2.05 в предыдущем посте ?
IYra
Живу тут
 
Сообщения: 535
Зарегистрирован: 01 фев 2012 19:36
Откуда: Санкт-Петербург

Re: Термометр на Attiny13 і двох DS18B20

Сообщение Tetera_Yura » 02 фев 2015 21:25

Ардуино. Там треба плату поміняти на Аттіні. Буду пробувати звязати Ардуино и CodeVisionAVR 2.05, ще не пробував...
Tetera_Yura
Пробегал мимо
 
Сообщения: 13
Зарегистрирован: 29 янв 2015 21:21

Re: Термометр на Attiny13 і двох DS18B20

Сообщение IYra » 02 фев 2015 21:42

Tetera_Yura писал(а):Ардуино. Там треба плату поміняти на Аттіні.

Чего-то не нашел такой.
Tetera_Yura писал(а): Буду пробувати звязати Ардуино и CodeVisionAVR 2.05, ще не пробував...

Так там не надо связывать а просто зашить хекс. Или Arduino ISP так не умеет ?
IYra
Живу тут
 
Сообщения: 535
Зарегистрирован: 01 фев 2012 19:36
Откуда: Санкт-Петербург

Re: Термометр на Attiny13 і двох DS18B20

Сообщение Tetera_Yura » 02 фев 2015 22:19

Залив я HEX через SinaProg 2.1. Працює) Читає температуру раз в хвилину? Але коли не читає температуру то десята градуса змінюється від 0 до 5 сама по собі. Можеш кинути цей проект на Си?
А для того щоб була плата Аттіні13 на Ардуіно потрібно скачати ядро для Аттіні і закинути в бібліотеки. Тоді появиться. Я використовую Ардуино в якості програматора. Ось фото:

Дякую!!
Tetera_Yura
Пробегал мимо
 
Сообщения: 13
Зарегистрирован: 29 янв 2015 21:21

Re: Термометр на Attiny13 і двох DS18B20

Сообщение IYra » 02 фев 2015 23:20

Tetera_Yura писал(а):Залив я HEX через SinaProg 2.1. Працює) Читає температуру раз в хвилину

Забыл сказать что надо фьюзы частоты выставить на 9.6 мГц
Tetera_Yura писал(а):А для того щоб була плата Аттіні13 на Ардуіно потрібно скачати ядро для Аттіні

Это я погуглил и сообразил. Даже запустил твой ардуиновский хекс в Протеусе. Показывает 0030 хоть ты тресни

Добавлено спустя 20 часов 7 минут 51 секунду:
IYra писал(а): Даже запустил твой ардуиновский хекс в Протеусе. Показывает 0030 хоть ты тресни

С этим вроде разобрался. При вызове lcd() из прерывания не видит dig0 ... dig3
Стал вызывать из глобального цикла - стало нормально (чудеса)
Выкладываю твой скетч two_termp2_2.ino подправленный. Плата ATtiny13 9.6 МГц
Там еще модель Протеуса (без выходных транзисторов) и хекс для нее
Вложения
two_termp2_2.rar
(23.92 КБ) Скачиваний: 70
IYra
Живу тут
 
Сообщения: 535
Зарегистрирован: 01 фев 2012 19:36
Откуда: Санкт-Петербург

Re: Термометр на Attiny13 і двох DS18B20

Сообщение Tetera_Yura » 03 фев 2015 22:39

Дякую!!) Завтра буду тестувати і дам результат)

Добавлено спустя 51 минуту 17 секунд:
Не витримав) протестував сьогодні) Дивись який результат. Якщо використати варіант без кнопки, з автоматичним перемиканням при зчитування, то все супер, хіба таймер підстроїв під себе бо низька частота індикатора. А от якщо використовувати варіант з кнопкою, до якого я більш прагну, то всеодно є ледь замітний імпульсь по розрядах індикатора. Я залишив з кнопкою. Так як думаю, що буду путатись де яка температура) а так точно знатиму. Дуже дякую тобі друже за допомогу!!!))
Код: Выделить всё
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/atomic.h>
#include <avr/wdt.h>
uint8_t a=0,tec_pos,pos;
uint8_t ROM[ 2 ];
uint8_t dig0,dig1,dig2,dig3;
int temp;
#define PShift PB2 // сдвиг
#define PData  PB0 // данные
#define PLatch PB1 // вывод

#define bit_set(p,m)  ((p) |= (m))
#define bit_clear(p,m) ((p) &= ~(m))
#define bit_write(c,p,m) (c ? bit_set(p,m) : bit_clear(p,m))
#define BIT(x) (0x01 << (x))
#define STROBE(p) bit_set(PORTB,BIT(p)); bit_clear(PORTB,BIT(p));
#define write_port_bit(data) bit_write(data & 1, PORTB, BIT(PData)); STROBE(PShift);

#define OneWire_setPinAsOutput  DDRB |= (1<<PB4)
#define OneWire_setPinAsInput   DDRB &= ~(1<<PB4)
#define OneWire_writePinLOW     PORTB &=  ~(1<<PB4)
#define OneWire_writePinHIGH    PORTB |= (1<<PB4)
#define OneWire_readPin         ( ( PINB & (1<<PB4) ) ? 1 : 0 )

uint8_t sseg[] = {0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,0x01,0x09,0xFD,0xFF};
uint8_t addr1[]= {0x28,0x6D,0xC2,0xE6,0x03,0x00,0x00,0x92};
uint8_t addr2[]= {0x28,0x38,0x07,0xB3,0x05,0x00,0x00,0x2F}; 

uint8_t OneWire_reset(){  // - Wait for line
        uint8_t Retries = 125;
        OneWire_setPinAsInput;
        do{
            if( --Retries == 0 ) return 0;
            _delay_us( 2 );
        }while( !OneWire_readPin ); // - Drop line
        OneWire_writePinLOW;
        OneWire_setPinAsOutput;
        _delay_us( 480 );     // - Listen for reply pulse
        OneWire_setPinAsInput;
       _delay_us( 70 );     // - Read line state
        uint8_t State = !OneWire_readPin;
        _delay_us( 410 );
        return State;
    }                     //! Write single bit
void OneWire_writeBit( uint8_t Bit ){
        if( Bit & 1 ){       // - Drop line
            OneWire_writePinLOW;
            OneWire_setPinAsOutput;  // - Write Bit-1
            _delay_us( 10 );
            OneWire_writePinHIGH;
            _delay_us( 55 );
        }else{           // - Drop line
            OneWire_writePinLOW;
            OneWire_setPinAsOutput;  // - Write Bit-0
            _delay_us( 65 );
            OneWire_writePinHIGH;
            _delay_us( 5 );
        }
}                                //! Read single bit
uint8_t OneWire_readBit(){       // - Drop line
        OneWire_setPinAsOutput;
        OneWire_writePinLOW;
        _delay_us( 3 );              // - Wait for data
        OneWire_setPinAsInput;
        _delay_us( 10 );             // - Read bit into byte
        uint8_t Bit = OneWire_readPin;
        _delay_us( 53 );
        return Bit; 
  }                                //! Write byte
void OneWire_writeByte( const uint8_t Byte, uint8_t Power = 0 ){
        for( uint8_t BitMask = 0x01; BitMask; BitMask <<= 1 ) OneWire_writeBit( (BitMask & Byte) ? 1 : 0 );
        if( !Power ){
            OneWire_setPinAsInput;
            OneWire_writePinLOW;
            }
      }                              //! Read byte
inline uint8_t OneWire_readByte(){
        uint8_t Byte = 0;          // - Read all bits
        for( uint8_t BitMask = 0x01; BitMask; BitMask <<= 1 ){
            if( OneWire_readBit() ) Byte |= BitMask;
         }
        return Byte;
    }                             //! Read buffer
inline void OneWire_read( uint8_t * Buffer, uint8_t Size ){
        for( uint8_t i = 0; i < Size; i++ )
          Buffer[ i ] = OneWire_readByte();
  }                            //! Write buffer
inline void OneWire_write(const uint8_t * Buffer, uint8_t Size, uint8_t Power = 0 ){
        for( uint8_t i = 0; i < Size; i++ )
          OneWire_writeByte(  Buffer[ i ] );
        if( !Power ){            // - Disable power
            OneWire_setPinAsInput;
            OneWire_writePinLOW;
        }
    }   
void write_port_byte(uint8_t data) {
   for (uint8_t i=0;i<8;i++) {
   write_port_bit(data); data = data >> 1;
  }
}
ISR(SIG_OVERFLOW0)
{
temp=temp+1;
pos++;
if (pos>3) pos=0;
}
SIGNAL(SIG_PIN_CHANGE0)
{
  if (bit_is_set(PINB,PB3))
  a=1;  else a=0; 
}

void lcd(uint8_t pos)
{
  uint8_t i ;
  i = 0b10000000 ;
  i = i >> (pos) ;
  i = ~i ;    // Инверт
  write_port_byte(i);
  if (pos==0) i=dig3 ;
  else if (pos==1) i=dig2 ;
  else if (pos==2) i=dig1 ;
  else if (pos==3) i=dig0 ;
  i=sseg[i] ;
  if (pos==1) i &= 0b111111110  ;   // Точка для десятых
  write_port_byte(i);
  STROBE(PLatch);
}
void tempe()
{
  OneWire_reset();
  OneWire_writeByte( 0x55, 1 );
  if (a==1)
  OneWire_write( addr2, sizeof( addr2 ) );
  else
  OneWire_write( addr1, sizeof( addr1 ) );
  OneWire_writeByte( 0xBE, 1 );
  OneWire_read( ROM, sizeof( ROM ) );
  OneWire_reset();
  OneWire_writeByte( 0xCC, 1 );
  OneWire_writeByte( 0x44, 1 );  // - Wait until conversion finished
ConvTempDi();
}

void ConvTempDi()
{
unsigned int tempint;//,tempint1,tempint2,tempint3; // переменные для целого значения температуры
unsigned int temppoint,temppoint1; // переменные для дробного значения температуры
unsigned char Temp_H,Temp_L,temp_flag;

Temp_L = ROM[0]; // читаем первые 2 байта блокнота
Temp_H = ROM[1];
temp_flag = 1;         // флаг знака температуры равен 1(плюс)

if(Temp_H &(1 << 3))   // проверяем бит знака температуры на равенство единице
{         
signed int tmp;
temp_flag = 0;      // флаг знака равен 0(минус)
tmp = (Temp_H << 8) | Temp_L;
tmp = -tmp;
Temp_L = tmp;
Temp_H = tmp >> 8; }     
tempint = ((Temp_H << 4) & 0x70)|(Temp_L >> 4); // вычисляем целое значение температуры
temppoint = Temp_L & 0x0F; // вычисляем дробное значение температуры
temppoint = temppoint * 625;       // точность температуры
temppoint1 = temppoint / 1000;
if (temp_flag==0)
dig0 = 10; else
dig0 = 11;
dig1 = tempint /10;
if (dig1==0) dig1=11;
dig2 = tempint % 10;
dig3 = temppoint1;   //
}

int main(void) {
  TCCR0A = 0;
  TCCR0B = 0b00000011; //делитель
  TIMSK0 = 0b00000010; // Разрешение прерываний по переполнению
  DDRB = 1<<PShift|1<<PData|1<<PLatch;
  PORTB &= ~(1<<PShift|1<<PLatch);
  GIMSK = 0b00100000;  // Разрешение прерываний PCINTn
  PCMSK = 0b00001000;  // прерывание по входу PCINT1 (PB1)       
  sei();

while(1)
{
  if (temp>2000)
  {
    tempe();
    temp=0;
  }
  if (tec_pos != pos)
  {
    tec_pos = pos ;
    lcd(tec_pos);
  } 
}
}

Це варіант з кнопкою.

Код: Выделить всё
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/atomic.h>
#include <avr/wdt.h>
uint8_t a=0,tec_pos,pos;
uint8_t ROM[ 2 ];
uint8_t dig0,dig1,dig2,dig3;
int temp;
#define PShift PB2 // сдвиг
#define PData  PB0 // данные
#define PLatch PB1 // вывод

#define bit_set(p,m)  ((p) |= (m))
#define bit_clear(p,m) ((p) &= ~(m))
#define bit_write(c,p,m) (c ? bit_set(p,m) : bit_clear(p,m))
#define BIT(x) (0x01 << (x))
#define STROBE(p) bit_set(PORTB,BIT(p)); bit_clear(PORTB,BIT(p));
#define write_port_bit(data) bit_write(data & 1, PORTB, BIT(PData)); STROBE(PShift);

#define OneWire_setPinAsOutput  DDRB |= (1<<PB4)
#define OneWire_setPinAsInput   DDRB &= ~(1<<PB4)
#define OneWire_writePinLOW     PORTB &=  ~(1<<PB4)
#define OneWire_writePinHIGH    PORTB |= (1<<PB4)
#define OneWire_readPin         ( ( PINB & (1<<PB4) ) ? 1 : 0 )

uint8_t sseg[] = {0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,0x01,0x09,0xFD,0xFF};
uint8_t addr1[]= {0x28,0x6D,0xC2,0xE6,0x03,0x00,0x00,0x92};
uint8_t addr2[]= {0x28,0x38,0x07,0xB3,0x05,0x00,0x00,0x2F};  //

uint8_t OneWire_reset(){  // - Wait for line
        uint8_t Retries = 125;
        OneWire_setPinAsInput;
        do{
            if( --Retries == 0 ) return 0;
            _delay_us( 2 );
        }while( !OneWire_readPin ); // - Drop line
        OneWire_writePinLOW;
        OneWire_setPinAsOutput;
        _delay_us( 480 );     // - Listen for reply pulse
        OneWire_setPinAsInput;
       _delay_us( 70 );     // - Read line state
        uint8_t State = !OneWire_readPin;
        _delay_us( 410 );
        return State;
    }                     //! Write single bit
void OneWire_writeBit( uint8_t Bit ){
        if( Bit & 1 ){       // - Drop line
            OneWire_writePinLOW;
            OneWire_setPinAsOutput;  // - Write Bit-1
            _delay_us( 10 );
            OneWire_writePinHIGH;
            _delay_us( 55 );
        }else{           // - Drop line
            OneWire_writePinLOW;
            OneWire_setPinAsOutput;  // - Write Bit-0
            _delay_us( 65 );
            OneWire_writePinHIGH;
            _delay_us( 5 );
        }
}                                //! Read single bit
uint8_t OneWire_readBit(){       // - Drop line
        OneWire_setPinAsOutput;
        OneWire_writePinLOW;
        _delay_us( 3 );              // - Wait for data
        OneWire_setPinAsInput;
        _delay_us( 10 );             // - Read bit into byte
        uint8_t Bit = OneWire_readPin;
        _delay_us( 53 );
        return Bit; 
  }                                //! Write byte
void OneWire_writeByte( const uint8_t Byte, uint8_t Power = 0 ){
        for( uint8_t BitMask = 0x01; BitMask; BitMask <<= 1 ) OneWire_writeBit( (BitMask & Byte) ? 1 : 0 );
        if( !Power ){
            OneWire_setPinAsInput;
            OneWire_writePinLOW;
            }
      }                              //! Read byte
inline uint8_t OneWire_readByte(){
        uint8_t Byte = 0;          // - Read all bits
        for( uint8_t BitMask = 0x01; BitMask; BitMask <<= 1 ){
            if( OneWire_readBit() ) Byte |= BitMask;
         }
        return Byte;
    }                             //! Read buffer
inline void OneWire_read( uint8_t * Buffer, uint8_t Size ){
        for( uint8_t i = 0; i < Size; i++ )
          Buffer[ i ] = OneWire_readByte();
  }                            //! Write buffer
inline void OneWire_write(const uint8_t * Buffer, uint8_t Size, uint8_t Power = 0 ){
        for( uint8_t i = 0; i < Size; i++ )
          OneWire_writeByte(  Buffer[ i ] );
        if( !Power ){            // - Disable power
            OneWire_setPinAsInput;
            OneWire_writePinLOW;
        }
    }   
void write_port_byte(uint8_t data) {
   for (uint8_t i=0;i<8;i++) {
   write_port_bit(data); data = data >> 1;
  }
}
ISR(SIG_OVERFLOW0)
{
temp=temp+1;
pos++;
if (pos>3) pos=0;
}

void lcd(uint8_t pos)
{
  uint8_t i ;
  i = 0b10000000 ;
  i = i >> (pos) ;
  i = ~i ;    // Инверт
  write_port_byte(i);
  if (pos==0) i=dig3 ;
  else if (pos==1) i=dig2 ;
  else if (pos==2) i=dig1 ;
  else if (pos==3) i=dig0 ;
  i=sseg[i] ;
  if (pos==1) i &= 0b111111110  ;   // Точка для десятых
  write_port_byte(i);
  STROBE(PLatch);
}
void tempe()
{
  OneWire_reset();
  OneWire_writeByte( 0x55, 1 );
  if (a==1)
  OneWire_write( addr2, sizeof( addr2 ) );
  else
  OneWire_write( addr1, sizeof( addr1 ) );
  OneWire_writeByte( 0xBE, 1 );
  OneWire_read( ROM, sizeof( ROM ) );
  OneWire_reset();
  OneWire_writeByte( 0xCC, 1 );
  OneWire_writeByte( 0x44, 1 );  // - Wait until conversion finished
ConvTempDi();
}

void ConvTempDi()
{
unsigned int tempint;//,tempint1,tempint2,tempint3; // переменные для целого значения температуры
unsigned int temppoint,temppoint1; // переменные для дробного значения температуры
unsigned char Temp_H,Temp_L,temp_flag;

Temp_L = ROM[0]; // читаем первые 2 байта блокнота
Temp_H = ROM[1];
temp_flag = 1;         // флаг знака температуры равен 1(плюс)

if(Temp_H &(1 << 3))   // проверяем бит знака температуры на равенство единице
{         
signed int tmp;
temp_flag = 0;      // флаг знака равен 0(минус)
tmp = (Temp_H << 8) | Temp_L;
tmp = -tmp;
Temp_L = tmp;
Temp_H = tmp >> 8; }     
tempint = ((Temp_H << 4) & 0x70)|(Temp_L >> 4); // вычисляем целое значение температуры
temppoint = Temp_L & 0x0F; // вычисляем дробное значение температуры
temppoint = temppoint * 625;       // точность температуры
temppoint1 = temppoint / 1000;
if (temp_flag==0)
dig0 = 10; else
dig0 = 11;
dig1 = tempint /10;
if (dig1==0) dig1=11;
dig2 = tempint % 10;
dig3 = temppoint1;   //
}

int main(void) {
  TCCR0A = 0;
  TCCR0B = 0b00000011; //делитель
  TIMSK0 = 0b00000010; // Разрешение прерываний по переполнению
  DDRB = 1<<PShift|1<<PData|1<<PLatch;
  PORTB &= ~(1<<PShift|1<<PLatch);
  GIMSK = 0b00100000;  // Разрешение прерываний PCINTn
  PCMSK = 0b00001000;  // прерывание по входу PCINT1 (PB1)       
  sei();

while(1)
{
  if (temp>2000)
  {
    tempe();
    temp=0;
    a++ ; if (a>1) a=0 ;
  }
  if (tec_pos != pos)
  {
    tec_pos = pos ;
    lcd(tec_pos);
  } 
}
}

Це варіант з автоматичним перемиканням при зчитуванні.

Ще раз ДЯКУЮ!!!))
На цьому зупинюсь з цим термометром...

Добавлено спустя 4 минуты 27 секунд:
Частота 9,6 МГц.
І ти круто реалізував функцію lcd, професіонально)
Tetera_Yura
Пробегал мимо
 
Сообщения: 13
Зарегистрирован: 29 янв 2015 21:21

Re: Термометр на Attiny13 і двох DS18B20

Сообщение IYra » 04 фев 2015 21:52

Tetera_Yura писал(а):Дякую!!) Дуже дякую тобі друже за допомогу!!!))

Да не за что. Самому было интересно. Узнал много нового.
Там кстати можно сделать вывод сразу на два индикатора.
Еще остается свободная ножка и немного памяти
Выкладываю проект
Вложения
two_termp2_3.rar
(23.94 КБ) Скачиваний: 98
IYra
Живу тут
 
Сообщения: 535
Зарегистрирован: 01 фев 2012 19:36
Откуда: Санкт-Петербург

Re: Термометр на Attiny13 і двох DS18B20

Сообщение Tetera_Yura » 04 фев 2015 22:55

Так, можна) цікаве рішення. Шкода, що я раніше про це не подумав)
Такий маленький контролер, але якщо постаратись то можна такого наворотити на ньому)
Цікава штука...
Tetera_Yura
Пробегал мимо
 
Сообщения: 13
Зарегистрирован: 29 янв 2015 21:21

Re: Термометр на Attiny13 і двох DS18B20

Сообщение botan » 06 фев 2015 11:29

Доброго дня!Скажите пожалуйста почему не работают в протеусе датчики DS18B20 c другими номерами?
botan
Пробегал мимо
 
Сообщения: 17
Зарегистрирован: 20 янв 2015 14:22

Re: Термометр на Attiny13 і двох DS18B20

Сообщение propell_ant » 06 фев 2015 11:57

потому что адреса заданы жестко прямо в программе:
Код: Выделить всё
uint8_t addr1[]= {0x28,0x6D,0xC2,0xE6,0x03,0x00,0x00,0x92};
uint8_t addr2[]= {0x28,0x38,0x07,0xB3,0x05,0x00,0x00,0x2F};
propell_ant
Живу тут
 
Сообщения: 276
Зарегистрирован: 03 июн 2014 09:22

Re: Термометр на Attiny13 і двох DS18B20

Сообщение Tetera_Yura » 06 фев 2015 21:33

Тепер буду пробувати підключити до Attiny13 термопару...якщо справлюсь то видам результат)
Tetera_Yura
Пробегал мимо
 
Сообщения: 13
Зарегистрирован: 29 янв 2015 21:21

Re: Термометр на Attiny13 і двох DS18B20

Сообщение IYra » 06 фев 2015 22:38

botan писал(а): почему не работают в протеусе датчики DS18B20 c другими номерами?

Собрал проект в котором нет привязки к номерам датчиков. Каждый датчик подключается к своей
ножке. Так проще и надежней. Только кнопка подключается по хитрому. Так же при нажатии
выводит температуру второго датчика. Проект на CodeVisionAVR 2.05 + Протеус
Вложения
term.rar
(26.23 КБ) Скачиваний: 110
IYra
Живу тут
 
Сообщения: 535
Зарегистрирован: 01 фев 2012 19:36
Откуда: Санкт-Петербург

След.

Вернуться в ATtiny



Кто сейчас на конференции

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