24 февраля 2022 года в 5 утра, без объявления войны, россия напала на Украину.

Они пришли "освобождать народ от нацистов и националистов".
С этого момента наша жизнь изменилась на "до" и "после".
Нас освобождают от наших домов, от наших любимых, от наших родителей и от наших детей....
Тут я не буду никого агитировать или переубеждать, разумный человек найдёт всю информацию
в интернете, а для зомби никакие доводы и факты не послужат аргументом.

Я не умею много писать, да и без мата тут сложно что-то написать.
Поэтому выражу все мои чувства одним фото.

«Спасибо дедушка путин за счастливое детство и мое освобождение». ©

Дополню словами уважаемого человека, широко известного в узких кругах:
тут путин не виноват, не он нажал на кнопку сброса,
- виноват пилот, который нажал на кнопку сброса, мог промахнуться. виноваты жена/мать/брат/друг пилота, которые не позвонили ему, и не сказали "нет войне",
- виноват тот, кто отдал приказ, и виноваты его жена/мать/брат/друг,
- виноват тот, кто цеплял бомбу, потому что он мог её обезвредить, "ну бывает, не сработала",
- виноват кладовщик, виноват водитель, который перевозил эту бомбу. виноваты жена...и т.д., потому что не позвонили и не сказали "нет войне, не вези бомбы",
- виноваты все журналисты оркостана, потому что они врут,
- виноваты недограждане, потому что не сказали журналистам "не врите",
- виноваты все... все 160 миллионов,
- а те 2, 3, 5 тысяч, которые вышли, и которых запаковали, это даже не десятая процента, это погрешность... случайно оказавшиеся в мордоре люди. ©

PS: За несколько часов до вторжения был атакован и взломан крупный интернет хостинг в Киеве, где и размещался мой сайт. Только 16 марта отважным админам удалось частично восстановить работу хостинга. Далеко не все сайты выжили, т.к. были повреждены даже бэкапы.
Нет, нет, я не жалуюсь, нет. В цифровом мире нет ничего ценного, материального...


Due to periodic DDoS attacks, the forum may not be available.

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

Здесь только проекты на ATtiny
Tetera_Yura
Пробегал мимо
Posts: 13
Joined: 29 Jan 2015 20:21

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

Post by Tetera_Yura »

Доброго Вечора! Прошу Вашої допомоги) Ось сотворив термометр на Attiny13 і двох DS18B20. Вийшло таке:
2015-01-2ы9 20.jpg
2015-01-29 20ч.jpg
Один датчик буде на вулиці, другий в домі) Коли натиснута кнопка то показує температуру в домі, а коли не натиснута то на вулиці.
Ось програма, не судіть строго...в програмуванні не сяю) частини програм брав з різних готових проектів, складав все в кучу і підганяв під себе і Attiny):

Code: Select all

#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();

 }
}
Питання ось в чому, все ніби не погано працює.
Але при зчитуванні температури з датчика присутнє одноразове моргання індикатора.
Можливо хтось побачить помилку в програмі і підскаже) бо я щось не можу її знайти) на мою думку це якесь переприсвоєння при спілкуванні з датчиком, або проблема в самому контролері (можливо він не справляється). Але більше всього це я не справляюсь з ним)) Допоможіть, кому не складно) Дякую!)
Last edited by Tetera_Yura on 02 Feb 2015 21:25, edited 1 time in total.
IYra
Живу тут
Posts: 712
Joined: 01 Feb 2012 18:36
Location: Санкт-Петербург

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

Post by IYra »

Чтобы легче понять проблему желательно сразу выкладывать весь материал (Схему, проект)
и на русском.
И вообще к чему такие сложности. Есть же термометр на 2313 для 2-х датчиков и кнопки нажимать не надо
http://hardlock.org.ua/viewtopic.php?f= ... 600#p10859
Tetera_Yura
Пробегал мимо
Posts: 13
Joined: 29 Jan 2015 20:21

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

Post by Tetera_Yura »

З російською в мене складно) а чому 13...сам не знаю) так вирішив, так і зробив, переробляти вже не буду. Хочу це довести до толку.
Ось схема, вибачайте що в такому варіанті) весь мій проект вмістився на 2 листках А4.
2015-01-30 18.jpg
2015-01-30 18.53.jpg
Кнопка для зручності, мені більше потрібна температура на вулиці, а коли потрібно в домі то нажав, подивився і все)
Я розумію що на 23 було б простіше, але трішки пізно вже)
Тим більше що в мене все вийшло і все працює. Просто невеличкий глюк, який хотілось би прибрати) тоді буде квітка)
Дякую!
IYra
Живу тут
Posts: 712
Joined: 01 Feb 2012 18:36
Location: Санкт-Петербург

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

Post by IYra »

Попробуй функцию 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() ;
}
}
Tetera_Yura
Пробегал мимо
Posts: 13
Joined: 29 Jan 2015 20:21

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

Post by Tetera_Yura »

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

Code: Select all

#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();

 }
}
Але останній розряд чомусь світиться яскравіше. Що це може бути?
Last edited by Tetera_Yura on 02 Feb 2015 21:24, edited 1 time in total.
IYra
Живу тут
Posts: 712
Joined: 01 Feb 2012 18:36
Location: Санкт-Петербург

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

Post by IYra »

Tetera_Yura wrote:Але останній розряд чомусь світиться яскравіше. Що це може бути?
Потому-что не выключается в конце и остается включенным большее время. Визуально кажется ярче
Это обратная сторона выключения. Если выключать - моргает. Если оставлять включенным - горит ярче.
Поэтому что-бы динамическая индикация была нормальная - ее лучше выводить через прерывания по таймеру
У меня сделано так.
Настроено срабатывание таймера на 4 мсек. При каждом срабатывании включается один разряд по порядку 1.2.3.4
и не выключается. Через 4 мсек этот разряд выключается - включается следующий и так по кругу. Получается 16 мсек
на вывод 4 цифр (1000/16 = 60 Гц)
Обращение к датчикам тоже в таймере. Поставить счетчик++ и если счетчик=250 (1 сек) читать Температуру
Ну примерно так
И не стоит все засовывать в одну функцию. Надо отделять мух от котлет.
И выкладывать код лучше так

Code: Select all

 bit_clear(PORTB,BIT(PLatch));
 write_port_byte(0x7F);
 write_port_byte(sseg[dig3]);
 bit_set(PORTB,BIT(PLatch));
а еще лучше присоединять файл проекта
А что там по поводу
Попробуй функцию lcd() вставить в функции OneWire_write и OneWire_read
Какой эффект от этого ?
Tetera_Yura
Пробегал мимо
Posts: 13
Joined: 29 Jan 2015 20:21

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

Post by Tetera_Yura »

Ефекту не було ніякого) Коли читав температуру через таймер з lcd() в OneWire_write и OneWire_read то нічого не показувало взагалі, а коли убирав таймер і читав температуру постійно, виводило чортзна що. До того всього в мене все було поділенно, то зараз я вже наворотив тут) і пробував я lcd() через таймер і температуру, тоді виходить той самий ефект, коли при зчитуванні температури моргає індикатор. Добре код буду викладати як скажеш, я тут новий, ще не знав) Дякую.
Виходить він в тебе 4 мсек світиться і виключається, і тоді включається інший, і так по кругу? Виходить коли він читає чи відправляє байти датчику то призупиняється робота індикатора, а коли я ставлю функцію індикатора в таймер то він не встигає читати температуру. Бо я так розумію приорітет по перериванню при переповненні таймера, чи не так? Я толком не знаю, логічно просто що переривання має більший приорітет.
IYra
Живу тут
Posts: 712
Joined: 01 Feb 2012 18:36
Location: Санкт-Петербург

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

Post by IYra »

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

Code: Select all

 
 write_port_byte(0xBF);
 write_port_byte(sseg0[dig2]);
 STROBE(PLatch);
этот код выводит один разряд. В таймере надо через каждые 4мс вызывать соответсвующий кусок
функции LCD(pos) - где pos - это разряд
А в функции OneWire_readByte() и OneWire_writeByte() вставить в цикл cli() и sei()

Code: Select all

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;
 } 
Tetera_Yura
Пробегал мимо
Posts: 13
Joined: 29 Jan 2015 20:21

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

Post by Tetera_Yura »

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

Добавлено спустя 23 часа 1 минуту 53 секунды:
А можеш підсказати як правильно оформити функцію lcd щоб виводилось кожні 4 мсек інший сегмент. Дякую.
Пробував кидати цілу lcd в таймер і вставив cli i sei в читання і запис байтів, то нічого не вийшло, немає обміну з датчиком. Але покази були якогось не зрозумілого числа.
IYra
Живу тут
Posts: 712
Joined: 01 Feb 2012 18:36
Location: Санкт-Петербург

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

Post by IYra »

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

Code: Select all

 TCCR0B = 0b00000101; //делитель
заменить на

Code: Select all

 TCCR0B = 0b00000100; //делитель
прерывания будут каждые 6 мс
затем в само прерывание вставить вызов lcd(Pos)

Code: Select all

ISR(SIG_OVERFLOW0)
{
temp=temp+1;
}
заменить на

Code: Select all

ISR(SIG_OVERFLOW0)
{
 temp=temp+1;
 lcd(pos) ;
 pos++;
 if (pos>3) pos=0 ;
}
не забыть обьявить pos
Затем меняем lcd()

Code: Select all

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)
 .......

 }
Ну и последний штрих
заменить

Code: Select all

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

Code: Select all

while(1) {
 if (temp>100){
 tempe();
 temp=0;}
 }
Tetera_Yura
Пробегал мимо
Posts: 13
Joined: 29 Jan 2015 20:21

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

Post by Tetera_Yura »

Зробив все як ти сказав. Вийшло так:

Code: Select all

#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. Якась халепа( Дякую!
IYra
Живу тут
Posts: 712
Joined: 01 Feb 2012 18:36
Location: Санкт-Петербург

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

Post by IYra »

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


В CodeVisionAVR 2.05 сделал что-то похожее. Там выводится один датчик
На модели в Протеусе вроде работало (только без выходных транзисторов)
Попробуй в реале
Attachments
term.rar
(1.31 KiB) Downloaded 323 times
Tetera_Yura
Пробегал мимо
Posts: 13
Joined: 29 Jan 2015 20:21

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

Post by Tetera_Yura »

Прошиваю через Arduino ISP. Ось проект. Дякую!)
Це останній варіант, який показує 000,3.
Attachments
two_termp2_2.rar
(2.17 KiB) Downloaded 313 times
IYra
Живу тут
Posts: 712
Joined: 01 Feb 2012 18:36
Location: Санкт-Петербург

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

Post by IYra »

Tetera_Yura wrote:Прошиваю через Arduino ISP. Ось проект.
Среда разработки то какая ? Ардуино что-ли ?
Я попробовал открыть и скомпилировать скетч в Ардуино. Выдало кучу ошибок

А что там с моим хексом на CodeVisionAVR 2.05 в предыдущем посте ?
Tetera_Yura
Пробегал мимо
Posts: 13
Joined: 29 Jan 2015 20:21

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

Post by Tetera_Yura »

Ардуино. Там треба плату поміняти на Аттіні. Буду пробувати звязати Ардуино и CodeVisionAVR 2.05, ще не пробував...
IYra
Живу тут
Posts: 712
Joined: 01 Feb 2012 18:36
Location: Санкт-Петербург

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

Post by IYra »

Tetera_Yura wrote:Ардуино. Там треба плату поміняти на Аттіні.
Чего-то не нашел такой.
Tetera_Yura wrote: Буду пробувати звязати Ардуино и CodeVisionAVR 2.05, ще не пробував...
Так там не надо связывать а просто зашить хекс. Или Arduino ISP так не умеет ?
Tetera_Yura
Пробегал мимо
Posts: 13
Joined: 29 Jan 2015 20:21

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

Post by Tetera_Yura »

Залив я HEX через SinaProg 2.1. Працює) Читає температуру раз в хвилину? Але коли не читає температуру то десята градуса змінюється від 0 до 5 сама по собі. Можеш кинути цей проект на Си?
А для того щоб була плата Аттіні13 на Ардуіно потрібно скачати ядро для Аттіні і закинути в бібліотеки. Тоді появиться. Я використовую Ардуино в якості програматора. Ось фото:
2015-02-02 л21.jpg
Дякую!!
IYra
Живу тут
Posts: 712
Joined: 01 Feb 2012 18:36
Location: Санкт-Петербург

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

Post by IYra »

Tetera_Yura wrote:Залив я HEX через SinaProg 2.1. Працює) Читає температуру раз в хвилину
Забыл сказать что надо фьюзы частоты выставить на 9.6 мГц
Tetera_Yura wrote:А для того щоб була плата Аттіні13 на Ардуіно потрібно скачати ядро для Аттіні
Это я погуглил и сообразил. Даже запустил твой ардуиновский хекс в Протеусе. Показывает 0030 хоть ты тресни

Добавлено спустя 20 часов 7 минут 51 секунду:
IYra wrote: Даже запустил твой ардуиновский хекс в Протеусе. Показывает 0030 хоть ты тресни
С этим вроде разобрался. При вызове lcd() из прерывания не видит dig0 ... dig3
Стал вызывать из глобального цикла - стало нормально (чудеса)
Выкладываю твой скетч two_termp2_2.ino подправленный. Плата ATtiny13 9.6 МГц
Там еще модель Протеуса (без выходных транзисторов) и хекс для нее
Attachments
two_termp2_2.rar
(23.92 KiB) Downloaded 335 times
Tetera_Yura
Пробегал мимо
Posts: 13
Joined: 29 Jan 2015 20:21

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

Post by Tetera_Yura »

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

Добавлено спустя 51 минуту 17 секунд:
Не витримав) протестував сьогодні) Дивись який результат. Якщо використати варіант без кнопки, з автоматичним перемиканням при зчитування, то все супер, хіба таймер підстроїв під себе бо низька частота індикатора. А от якщо використовувати варіант з кнопкою, до якого я більш прагну, то всеодно є ледь замітний імпульсь по розрядах індикатора. Я залишив з кнопкою. Так як думаю, що буду путатись де яка температура) а так точно знатиму. Дуже дякую тобі друже за допомогу!!!))

Code: Select all

#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);
  }  
}
}

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

Code: Select all

#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, професіонально)
IYra
Живу тут
Posts: 712
Joined: 01 Feb 2012 18:36
Location: Санкт-Петербург

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

Post by IYra »

Tetera_Yura wrote:Дякую!!) Дуже дякую тобі друже за допомогу!!!))
Да не за что. Самому было интересно. Узнал много нового.
Там кстати можно сделать вывод сразу на два индикатора.
Еще остается свободная ножка и немного памяти
Выкладываю проект
Attachments
two_termp2_3.rar
(23.94 KiB) Downloaded 382 times
Tetera_Yura
Пробегал мимо
Posts: 13
Joined: 29 Jan 2015 20:21

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

Post by Tetera_Yura »

Так, можна) цікаве рішення. Шкода, що я раніше про це не подумав)
Такий маленький контролер, але якщо постаратись то можна такого наворотити на ньому)
Цікава штука...
botan
Пробегал мимо
Posts: 17
Joined: 20 Jan 2015 13:22

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

Post by botan »

Доброго дня!Скажите пожалуйста почему не работают в протеусе датчики DS18B20 c другими номерами?
propell_ant
Живу тут
Posts: 490
Joined: 03 Jun 2014 09:22

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

Post by propell_ant »

потому что адреса заданы жестко прямо в программе:

Code: Select all

uint8_t addr1[]= {0x28,0x6D,0xC2,0xE6,0x03,0x00,0x00,0x92};
uint8_t addr2[]= {0x28,0x38,0x07,0xB3,0x05,0x00,0x00,0x2F};
Tetera_Yura
Пробегал мимо
Posts: 13
Joined: 29 Jan 2015 20:21

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

Post by Tetera_Yura »

Тепер буду пробувати підключити до Attiny13 термопару...якщо справлюсь то видам результат)
IYra
Живу тут
Posts: 712
Joined: 01 Feb 2012 18:36
Location: Санкт-Петербург

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

Post by IYra »

botan wrote: почему не работают в протеусе датчики DS18B20 c другими номерами?
Собрал проект в котором нет привязки к номерам датчиков. Каждый датчик подключается к своей
ножке. Так проще и надежней. Только кнопка подключается по хитрому. Так же при нажатии
выводит температуру второго датчика. Проект на CodeVisionAVR 2.05 + Протеус
Attachments
term.rar
(26.23 KiB) Downloaded 430 times
Post Reply