Перейти к содержанию
С Днём Победы! ×

Krendelyok

Members
  • Постов

    5
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные Krendelyok

  1. 1 минуту назад, andryxa сказал:

    И ты думаешь после этого тебе кто-то будет помогать?

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

  2. 22 часа назад, Alex сказал:

    Кренделёк, что же ты не идёшь на тот пропиаренный тобой форум, где тебе помогают без всяких проблем, лишних вопросов, советов и дают чёткие и верные ответы ? 
     

    Я просто на нескольких форумах советуюсь. Вопрос то сложный. Не для таких, как ты, неучей)

  3. Написал код для работы AtTiny13, DHT11, TM1637. Всё удачно уместилось в памяти микрухи. На первый взгляд всё работает. Данные передаются без сбоев, контрольная сумма в норме. Вот видео, если кому интересно. Но обнаружилась проблема. Периодически, примерно каждые 5-6 запросов данных от датчика DHT11, показания влажности и температуры скачут. На 5 - 10 единиц могут прыгнуть. При этом рассогласования с контрольной суммой нет. Поначалу списал всё на "несерьезность" датчика, но... Залил тот же самый код в Ардуино Уно - нет никаких скачков. Цепляю датчик и дисплей обратно к тиньке - пляшут данные. Подключаю питание непосредственно от этой ардуинки - не помогает, скачут показания. Припаиваю непосредственно к датчику конденсатор по питанию 100 нФ, как рекомендуется в даташите, - бесполезно. Меняю на тиньке частоты: 1.2, 4.8, 9,6 Мгц - никакого результата. Кстати, по ходу дела, заметил еще одну странность: на 9.6 Мгц тинька в этой связке запускается только от 3 вольт, от пяти - не хочет. На дисплей при этом нужно подавать 5 вольт. В общем, у меня закончились предположения, пришел за помощью к вам. В чем подвох может быть, ведь на ардуинке с тем же питанием показания стабильны?

    Код:

    Скрытый текст
    
    #define F_CPU 1200000LU
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include <avr/wdt.h> 
    
    unsigned char word_dht = 0x00;
    unsigned char time_bit[40];
    unsigned char data_dht[5];
    unsigned char bit_dht;
    
    
    #define Clkpin 3 //Clkpin TM1637
    #define Datapin 2 // Datapin TM1637
    #define PIN_DHT 0 //Пин датчика DHT
    
    #define DispPort PORTB // обзываем порт
    
    #define  BRIGHT_LCD 7  //Яркость дисплея от 0 до 7
    		
    		unsigned char _PointFlag; 	//_PointFlag=1:the clock point on
    		unsigned char _DispType;
    		unsigned char DecPoint;
    		unsigned char BlankingFlag;
    	
    		
    static unsigned char TubeTab[10] = {0x3f,0x06,0x5b,0x4f,// знакогенератор
                               0x66,0x6d,0x7d,0x07,
                               0x7f,0x6f};//,0x77,0x7c,
                               //0x39,0x5e,0x79,0x71,
                              // 0x40,0x00};//0~9,A,b,C,d,E,F,"-"," "  
    
    void TM1637_writeByte(char wr_data)// служебная функция записи данных по протоколу I2C, с подтверждением (ACK)
    {
      unsigned char i;
        for(i=0;i<8;i++)        
      {
       DispPort &= ~(1<<Clkpin);
        if(wr_data & 0x01)
    	{ DispPort |= 1<<Datapin;}
        else {DispPort &= ~(1<<Datapin);}
    	_delay_us(3);
        wr_data = wr_data>>1;      
        DispPort |= 1<<Clkpin;
    	_delay_us(3);  
      }  
     
      DispPort &= ~(1<<Clkpin);
      _delay_us(5);
      DDRB &= ~(1<<Datapin);// если поменяете порт на какой-то другой кроме DispPort, то тут тоже все DDRB на другие DDRx менять надо будет
      while((PINB & (1<<Datapin))); 
      DDRB |= (1<<Datapin);
      DispPort |= 1<<Clkpin;
      _delay_us(2);
      DispPort &= ~(1<<Clkpin);  
    }
    
    void TM1637_start(void) // просто функция "старт" для протокола I2C
    {
       DispPort |= 1<<Clkpin; 
       DispPort |= 1<<Datapin;
     _delay_us(2);
      DispPort &= ~(1<<Datapin); 
    } 
    
    void TM1637_stop(void) // просто функция "стоп" для протокола I2C
    {
      DispPort &= ~(1<<Clkpin);
     _delay_us(2);
      DispPort &= ~(1<<Datapin);
    _delay_us(2);
      DispPort |= 1<<Clkpin;;
    _delay_us(2);
      DispPort |= 1<<Datapin;
    }
    
    
    void TM1637_init()// Инициализируем дисплей. Как оказалось, можно удалить из этого блока стандартной библиотеки практически всё, кроме инициализации пинов.
    {
    	DDRB |= (1<<Clkpin) | (1<<Datapin);
    }
    
    //---------------------------------------------------------------------
    //Здесь код для датчика DHT11. Писал полностью сам.
    
    void start_tmr_us()
    {
    TCNT0 = 0x00;
    TCCR0B = 0x01; //Запускаем таймер0 с частотой 1,2 Мгц
    }
    
    void start_dht()                //Отправляем приветствие датчику
    {
    DDRB |= (1 << PIN_DHT);
    DispPort |= (1 << PIN_DHT);
    DispPort &= ~(1 << PIN_DHT);
    _delay_ms(18);
    DDRB &= ~(1 << PIN_DHT);
    DispPort |= (1 << PIN_DHT);
    while(PINB & (1 << PIN_DHT)){}
    while(~PINB & (1 << PIN_DHT)){}
    while(PINB & (1 << PIN_DHT)){}
    
    }
    
    void get_data()                            //Получаем 40 бит от датчика и записываем в массив
    {
    for(bit_dht = 0; bit_dht < 40; bit_dht++)
    {
    while(~PINB & (1 << PIN_DHT)){}
    start_tmr_us();
    while(PINB & (1 << PIN_DHT)){}
    time_bit[bit_dht] = TCNT0;
    }
    }
    
    void decoder_bit(){
    unsigned char bit_number = 1;
    unsigned char word_number = 0;
    for(bit_dht = 0; bit_dht < 40; bit_dht++){  //дербаним наш массив из 40 бит (5 байтов), в котором записана длительность каждого полученного  бита
    
    if(time_bit[bit_dht] > 50)                //Если длительность бита больше 28 мкс,
    {
    word_dht = word_dht << 1;            //сдвигаем байт влево и записываем в младший разряд 1
    word_dht |= (1 << 0);
    }else
    {
    word_dht = word_dht << 1;        //Если меньше 28 мкс, сдвигаем влево байт и записываем 0
    word_dht &= ~(1 << 0);
    }
    
    if(bit_number == 8){                     //Если имеем дело с восьмым битом, записываем полученный байт в массив
    data_dht[word_number] = word_dht;
    word_number += 1;
    bit_number = 0;       
    }
    bit_number +=1;
    }
    }
    
    
    
    ISR (WDT_vect){
    TM1637_writeByte(0x40);    //Выводим на дисплей Err1
    TM1637_stop();
    TM1637_start();
    TM1637_writeByte(0xC0);
    TM1637_writeByte(0x79);
    TM1637_writeByte(0x50);
    TM1637_writeByte(0x50);
    TM1637_writeByte(0x06);
    TM1637_stop();
    TM1637_start();
    TM1637_writeByte(0x8F);
    TM1637_stop();
    }
    
    
    
    
    int main(void)
    {
    wdt_reset();            //Запускаем вотч дог
    wdt_enable(WDTO_4S);
    WDTCR |= (1 << WDTIE);
    sei();
    TM1637_init();
    _delay_ms(500);  //Зачем-то тупим немного. Иначе, вроде как, дисплей может не зажечься.
     
    while(1)
    {
    start_dht();                         
    get_data();
    decoder_bit();
    if((data_dht[0] + data_dht[1] + data_dht[2] + data_dht[3]) != data_dht[4])
    {
    	TM1637_writeByte(0x40);    //Выводим на дисплей Err0
    	TM1637_stop();
    	TM1637_start();
    	TM1637_writeByte(0xC0);
    	TM1637_writeByte(0x79);
    	TM1637_writeByte(0x50);
    	TM1637_writeByte(0x50);
    	TM1637_writeByte(0x3f);
    	TM1637_stop();
    	TM1637_start();
    	TM1637_writeByte(0x8F);
    	TM1637_stop();
    	_delay_ms(3500);
    	wdt_reset();
    	_delay_ms(3500);
    	wdt_reset();	
    }
    
    TM1637_start();                     //Выводим на дисплей влажность.  
    TM1637_writeByte(0x40);
    TM1637_stop();
    TM1637_start();
    TM1637_writeByte(0xC0);
    TM1637_writeByte(0x76);
    TM1637_writeByte(0x00);
    TM1637_writeByte(TubeTab[(data_dht[0] / 10) % 10]);
    TM1637_writeByte(TubeTab[data_dht[0] % 10]);
    TM1637_stop();
    TM1637_start();
    TM1637_writeByte(0x8F);
    TM1637_stop();
    _delay_ms(2000);
    wdt_reset();
    
    TM1637_start();                                    //Выводим на дисплей температуру
    TM1637_writeByte(0x40);
    TM1637_stop();
    TM1637_start();
    TM1637_writeByte(0xC0);
    TM1637_writeByte(TubeTab[(data_dht[2] / 10) % 10]);
    TM1637_writeByte(TubeTab[data_dht[2] % 10]);
    TM1637_writeByte(0x63);
    TM1637_writeByte(0x39);
    TM1637_stop();
    TM1637_start();
    TM1637_writeByte(0x8F);
    TM1637_stop(); 
    _delay_ms(2000);
    wdt_reset();
    }
    }

     

     

×
×
  • Создать...