Содержание
Урок 1. Первый проект
Урок 2. Управление кнопками
Урок 3. Подключение LCD
Урок 4. Использование ШИМ
Урок 5. Таймеры
Урок 6.1. Статическая индикация
Урок 6.2. Динамическая индикация
Урок 7.1. Генерация звука
Урок 7.2. Генерация звука. Продолжение
Урок 8.1. Передача данных через UART
Урок 8.2. Передача данных через UART. Продолжение»
Урок 9. Передача данных через SPI
Урок 10. Изучение АЦП. Простой вольтметр
Урок 11. Получение синуса при помощи ШИМ
Урок 12. Измерение температуры
Урок 13. Внешние прерывания.
Урок 14. Использование отладчика
Урок 15.1. Управление инкрементальным энкодером
Урок 15.2. Управление громкостью, при помощи энкодера
Урок 16. Управление RGB светодиодом
Урок 17. Использование ИК
Урок 18.1. Знакомство с графическим дисплеем
Урок 18.2 Вывод изображения на графический дисплей
Урок 18.3 Вывод русскоязычного текста
Урок 19. Формирование сигнала, при помощи ЦАП (R2R)
Урок 20. Опрос матричной клавиатуры
Урок 21. Сторожевой таймер
Урок 22.1 Воспроизведение wav. Введение.
Урок 22.2 Воспроизведение wav. Продолжение.
Урок 23.1 Работа с внешней памятью
Урок 23.2 Работа с файловой системой Fat

termoПродолжаем осваивать периферию, на очереди измерение температуры. Рассмотрим вариант измерения, при помощи датчика температуры DS18b20.

Характеристики датчика: диапазон измерения от -55 до +125°С. Точность измерения ±0,5°С гарантируется в диапазоне от -10 до +85°С. Возможность измерения с разрешением 9, 10, 11 и 12 бит, т.е. с шагом 0,5; 0,25; 0,125; 0,0625°С. Для обмена информацией с AVR микроконтроллером используется 1-Wire протокол. Каждый датчик имеет свой уникальный адрес, поэтому имеется возможность посадить на шину сразу несколько датчиков.

les12-2

Для сборки схемы понадобится жк дисплей, датчик и резистор на 4,7кОм. Теперь перейдем непосредственно к прошивке.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <mega8.h>
#include <delay.h>
// 1 Wire Bus functions
#asm
   .equ __w1_port=0x18 ;PORTB
   .equ __w1_bit=2
#endasm
#include <1wire.h>
#include <ds18b20.h>
 
// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h>
#include <stdio.h> 
 
char lcd_buf[17];
void main(void)
{
 
float temper;  
lcd_init(16);   
w1_init();
ds18b20_init(0,-20,50,DS18B20_12BIT_RES); 
 
while(1)                 
      {
          temper=ds18b20_temperature(0);  
          sprintf(lcd_buf,"t=%.1f\xdfC",temper);    
          lcd_clear();                
          lcd_puts(lcd_buf);        
          delay_ms(1500);              
      }; 
}

Теперь обо всем по порядку:

1
2
3
4
#asm
   .equ __w1_port=0x18 ;PORTB
   .equ __w1_bit=2
#endasm

Данный код означает, что датчик подключен к порту В, PB2 ножке

1
2
#include <1wire.h>
#include <ds18b20.h>

Используется протокол 1wire, тип датчика ds18b20

1
2
3
float temper;  
w1_init();
ds18b20_init(0,-20,50,DS18B20_12BIT_RES);

Переменная temper (с плавающей точкой) используется для хранения температуры,
w1_init(); — ищем датчик,
ds18b20_init(0,-20,50,DS18B20_12BIT_RES); — настройка датчика: 0-номер датчика, -20 -нижний предел измерения, 50 — верхний предел измерения,
DS18B20_12BIT_RES используется 12 битный режим(с шагом 0,0625°С). В принципе настройку можно не производить, по умолчанию выставлен 12 битный режим. Показано лишь для того, чтобы вы могли самостоятельно изменить режим измерения, если это понадобится.

1
2
3
4
5
6
          temper=ds18b20_temperature(0);  
 
          sprintf(lcd_buf,"t=%.1f\xdfC",temper);    
          lcd_clear();                
          lcd_puts(lcd_buf);        
          delay_ms(1500);

temper=ds18b20_temperature(0); — читаем значение температуры с датчика
sprintf(lcd_buf,»t=%.1f\xdfC»,temper); преобразовываем к понятному для lcd виду %.1f — вывод числа с плавающей точкой 1 знак после запятой, не забываем в свойствах проекта указать (s)printf features float.
\xdf — вывод на экран значка градуса.

В результате должно получиться нечто похожее
les12-4

Отрицательной температуры поблизости не было :D, поэтому попробовал остудить бутылочкой соуса из холодильника, результат что то не сильно впечатлил.
les12-5

Зато от нагрева рукой, температура довольно быстро повысилась.
les12-3
Проект доступен тут
Проект для DS18s20
Проект для двух датчиков
Проект для DS18b20 на семисегментниках
Проект Алексея(Alyes)для Atmega16 и шести сегментов + бонус видео устройства

259 комментариев: Урок 12. Измерение температуры при помощи AVR. Простой термометр на AVR.

  • Пробовал скорее всего где то в сакете или в пайке , Но это ерунда разберусь.Вообще то я учусь по Вашим урокам и у меня вопрос как делается колибровка на 0 или на другое число.
    Как это записывается в память. Допустим мне надо сделать вольтметр или как привезать данные АЦП к другим чесловым данным. Я сейчас хочу сделать что то типа весов с тензодатчиками а как сделать что бы допустим АЦП ==512 а на дисплее допустим 10кг
    но делать это не в программе а кнопкой типа запись.

  • по нажатию кнопки просто пересчитываете коэффициент относительно известной величины

  • Спасибо . Но уровень моих знаний пока таков что для меня это не просто. Тем более что данные надо записались в память.Я сделал емкостный датчик уровня топлива генератор на 555мк. контроллер по захвату настроеный на ШИМ ,далее ОУ и АЦП так вот
    я хотел сделать так что бы «0» бака бензина полный бак и несколько контрольных точек можно было бы торировать. Пока отложил потому что прошивать программу для каждого объеама бака хлопотно и не интересно. Интерес не комерческий , я сделал дава датчика второй по захвату таймера от компаратора. Если кому интересно могу все выслать.
    С уважением Александр.

  • Здравствуйте ув Админ. Все пытаюсь повторить сей проект и никак не получается (сначала Т=-9999 была проблема со фьюзами), теперь Т=1f»C . Спасибо

  • похоже ответ на вопрос найден (s)printf features float

  • Здравствуйте! Не подскажите как реализовать, чтоб выводилась минимальная и максимальная температура?Как термометр с памятью.

  • Создать переменные min max и в них складывать соответствующие значения.

  • Алексей а не могли бы вы привести пример?

  • Не получается у меня,Создать переменные мин.и макс. Меняется всё вместе.
    #include
    #include
    // 1 Wire Bus functions
    #asm
    .equ __w1_port=0x18 ;PORTB
    .equ __w1_bit=2
    #endasm
    #include
    #include

    // Alphanumeric LCD Module functions
    #asm
    .equ __lcd_port=0x12 ;PORTD
    #endasm
    #include
    #include

    char lcd_buf[16];
    void main(void)
    {

    float temper;
    float max;
    float min;

    lcd_init(16);
    w1_init();
    ds18b20_init(0,-20,50,DS18B20_12BIT_RES);

    while(1)
    {
    temper=ds18b20_temperature(0);
    max=ds18b20_temperature(0);
    if(temper > max)
    { max = temper;}
    min=ds18b20_temperature(0);
    if(temper < min)
    { min = temper;}
    sprintf( lcd_buf,"t1=%.1f\xdfC", temper );
    lcd_gotoxy(0,0);
    lcd_puts( lcd_buf );
    sprintf( lcd_buf,"max=%.1f" "min=%.1f",max,min );
    lcd_gotoxy(0,1);
    lcd_puts( lcd_buf );

    };
    }

  • Все верно.Так и должно быть.
    Это что?
    temper=ds18b20_temperature(0);
    max=ds18b20_temperature(0);
    if(temper > max)
    { max = temper;}
    Как можно сравнивать два значения если у них всегда одно и тоже значение?
    Сначала положите в переменные мин и макс нули до функции меин. Затем получите температуру. Далее сравните температуру с максимум и если она больше чем предыдущее значение, то в максимум запишите текущее значение. Если температура ниже значения максимума, то сравните со значением минимум. Здесь тоже самое, если значение меньше минимума, то записываем в переменную минимум текущее значение, а если больше, то просто ничего никуда не записываем. Температура в промежутке. И так по кругу.

  • А это тоже самое, но в коде.
    temper=ds18b20_temperature(0);
    if(max temper) min = temper;

    Вот и весь код.)))

  • Опа на… Третья строка стерлась и знаки больше, меньше пропали??? Как это???
    temper=ds18b20_temperature(0);
    if(max меньше temper) max = temper;
    if(min больше temper) min = temper;

  • От себя админу: Этому сайту необходим форум.

  • Алексею огромное спасибо!Заработало! 😀

  • У меня нет времени, чтобы заниматься форумом, если найдутся желающие им заниматься, то я не против.

  • Ну можно у меня топтаться.
    avrki.ru/forum/forum.php
    Если есть желание то могу организовать ветку для AVR-START

  • Пожалуй, озвучу свои мысли.
    1.Не дробить, ни переносить сайт, или его часть в планы не входит. Кого нить подмять это можно 🙂
    2.При текущем положении дел на весь сайт 10Гб. Поэтому, когда народ начал лить картинки мегабайтами, то стало понятно нужен нормальный хостинг.
    3.Подавляющее большинство тем было из разряда «помогите решить контрольную». Любые попытки объяснить превращаются, «нет ты давай готовое», понятно, что раз это не нужно по жизни, то не хочется тратить время. Но мне это не интересно и мне не нужен форум по решению контрольных.
    Итог — при текущем раскладе форум не нужен. Все проблемы решает группа вк. Если я знаю ответ на вопрос, то всегда даю ответ. Кроме того, там нет спама и прочей хрени, открытая регистрация. Можно лить видео, фото, исходники, можно создавать свои темы, статьи и не беспокоиться что завтра сайт закроется, т.е. не надо ничего придумывать, все уже есть — пользуйтесь.

  • Ну я лишь предложил, а там как скажешь.

  • Добрый вечер.На атмега8 всё работает,всё чики пуки.А вот на атмега168 нет.Проект на атмега 168 точно такой же,только библиотека вместо — .В протеусе на экране t=-9999.0 C.Если отсоединить датчик,та же картина.В протеусе CKSEL Fuses стоит на 8 МГ(Внутрений).В CodeVision тоже 8 МГ. Предделитель основной частоты — 1. В Configure Project во вкладке С compiler Clock тоже 8 МГ.При компиляции тоже пишет что 8 МГ.Помогите пожалуйста мне срочно надо…Давно уже не могу понять причину.

  • Библиотека вместо atmega8, atmega168. P.S Не работает в протеусе.(В реале пока не пробовал).

  • перегенерите проект визардом для начала

  • Здравствуйте) помогите разобраться с кусочком кода.Почему именно 4096( это 2^12 разрешающая способность датчика?)Чет я глянул в даташит там биты признака и он последний 7 стоит если не ошибаюсь . Совсем запутался откуда 1000..)
    if (temper>1000)
    {
    temper=4096.0-temper;
    temper=-temper;
    }

  • 4096 потому что 2^12, про эти строки забудьте, внутри библиотеки это уже все реализовано.

  • Протупил) Не внимательно читал комменты)Набрался смелости)написать сюда)Не получается получить ничего с датчика ds18b20 )хД т к я совсем отчаялся обрезал до 1 цифры чтоб хоть что-то .. но не тут то было)Порт на датчике настраивал и на вход и на выход. Как и с частотой контроллера(программа на 4 мгц проверял и фьюзы и настройки) .Факт в том что и в протеусе и в железе у меня горит число девять из 2 оператора свич(который почему то отказывается работать???? хотя ошибок нет )для меня главное понять почему 2 оператор свича не работает ( я пониманию что нужно учитывать тайминги общих и сегментов для динам. индикации) ,но он ни в какую не работает!!
    (s)printf Features: в настройках стоит float.Почитал разной инфы , пробывал впихивать задержки(может не туда?пихал 1000мс перед и после запись в переменную температуры) чтоб что-то хоть менялось — нифига( пошел вот таким куском
    x=temper;
    x/=10;
    if(x==1)
    {PORTB=0xFF;
    }
    else {PORTB=0x00;
    } ////менял температуру на датчике с 19 на 20 градусов и порты стабильно переключались)

    #include
    #include
    #include
    float temper;
    int z;
    int x;
    char i;
    interrupt [TIM1_COMPA] void timer1_compa_isr(void)
    {
    PORTD=0x00;(порт д — общие порт б — сегменты.

    switch(z)
    {
    case 0:PORTD.0=1;z++;break;//присваивал и тут переменной i — значение переменной ,нифига…
    case 1:PORTD.1=1;z++;break;//
    case 2:PORTD.2=1;z++;break;
    case 3:PORTD.3=1;z=0;break;
    }
    switch(i)
    {
    case 0:PORTB=0xff;
    case 1:PORTB=0x42;
    case 2:PORTB=0x65;
    case 3:PORTB=0x6B;
    case 4:PORTB=0x5A;
    case 5:PORTB=0x3B;
    case 6:PORTB=0x3F;
    case 7:PORTB=0x62;
    case 8:PORTB=0x7F;
    case 9:PORTB=0x7B;
    }
    }
    void main(void)
    {

    // Crystal Oscillator division factor: 1
    #pragma optsize-
    CLKPR=(1<<CLKPCE);
    CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
    #ifdef _OPTIMIZE_SIZE_
    #pragma optsize+
    #endif
    // Port B initialization
    // Function: Bit7=In Bit6=Out Bit5=Out Bit4=Out Bit3=Out Bit2=Out Bit1=Out Bit0=Out
    DDRB=(0<<DDB7) | (1<<DDB6) | (1<<DDB5) | (1<<DDB4) | (1<<DDB3) | (1<<DDB2) | (1<<DDB1) | (1<<DDB0);
    // State: Bit7=T Bit6=0 Bit5=0 Bit4=0 Bit3=0 Bit2=0 Bit1=0 Bit0=0
    PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

    // Port D initialization
    // Function: Bit6=In Bit5=In Bit4=In Bit3=Out Bit2=Out Bit1=Out Bit0=Out
    DDRD=(0<<DDD6) | (0<<DDD5) | (1<<DDD4) | (1<<DDD3) | (1<<DDD2) | (1<<DDD1) | (1<<DDD0);
    // State: Bit6=T Bit5=T Bit4=T Bit3=0 Bit2=0 Bit1=0 Bit0=0
    PORTD=(0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: 500,000 kHz
    // Mode: CTC top=OCR1A
    // Input Capture on Falling Edge
    // Timer Period: 2,082 ms
    // Compare A Match Interrupt: On
    TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
    TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (1<<CS11) | (0<<CS10);
    TCNT1H=0x00;
    TCNT1L=0x00;
    ICR1H=0x00;
    ICR1L=0x00;
    OCR1AH=0x04;
    OCR1AL=0x10;
    OCR1BH=0x00;
    OCR1BL=0x00;
    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=(0<<TOIE1) | (1<<OCIE1A) | (0<<OCIE1B) | (0<<ICIE1) | (0<<OCIE0B) | (0<<TOIE0) | (0<<OCIE0A);
    // 1 Wire Data port: PORTD
    // 1 Wire Data bit: 4
    w1_init();
    #asm("sei")
    while (1)
    {
    temper=ds18b20_temperature(0);
    x=temper;
    i=x%10; //пытался вывести любое число (единицы градусов) через оператор свич , но не тут то было….

    }
    }

  • Уважаемый admin. Доброго времени суток. Назрел такой вопрос, используя ваш код из примера для семисегментников попробовал сделать нечто своё, под atmega8 на четыре цифры. И всё бы ничего, он работает, но температуры ниже нуля не выводятся, горят все нули. Бьюсь над этим вот уже неделю, пробовал и так и сяк, но не работает. Вот пример кода

    Chip type : ATmega8
    Program type : Application
    AVR Core Clock frequency: 8,000000 MHz
    Memory model : Small
    External RAM size : 0
    Data Stack size : 256
    *****************************************************/

    #include

    // 1 Wire Bus functions
    #asm
    .equ __w1_port=0x15 ;PORTC
    .equ __w1_bit=5
    #endasm
    #include

    // DS1820 Temperature Sensor functions
    #include
    unsigned char number = 0;
    unsigned int number1 = 0;
    unsigned int number2 = 0;
    unsigned int number3 = 0;
    unsigned int number4 = 0;
    bit minus=0;
    unsigned char i=0;
    // Timer1 output compare A interrupt service routine
    interrupt [TIM1_COMPA] void timer1_compa_isr(void)
    {
    PORTB=0x00;

    switch (i)
    {
    //выбираем ПИН
    case 0:PORTB.3=1;number=number1;i++;break;
    case 1:PORTB.2=1;number=number2;i++;break;
    case 2:PORTB.1=1;number=number3;i++;break;
    case 3:PORTB.0=1;number=number4;i=0;break;

    }
    if(i==3)
    {
    switch(number)
    {
    //этот массив с запятой…
    case 0:{PORTD=0xbf;break;}//если номер с запятой и ном=0 тогда зажгем 0 и выйдем…
    case 1:{PORTD=0x86;break;}
    case 2:{PORTD=0xdb;break;}
    case 3:{PORTD=0xcf;break;}
    case 4:{PORTD=0xe6;break;}
    case 5:{PORTD=0xed;break;}
    case 6:{PORTD=0xfd;break;}
    case 7:{PORTD=0x87;break;}
    case 8:{PORTD=0xff;break;}
    case 9:{PORTD=0xef;break;}
    case 10:{PORTD=0x63;break;}//знак градуса…
    case 11:{PORTD=0x39;break;}//цельсия
    case 12:{PORTD=0x00;break;}//пустое место
    case 13:{PORTD=0x40;break;}//минус
    }
    }
    else
    {
    switch (number)
    {
    //этот если без запятой
    case 0:{PORTD=0x3f;break;}//если номер без запятой и ном=0 тогда зажгем 0 и выйдем…
    case 1:{PORTD=0x06;break;}
    case 2:{PORTD=0x5b;break;}
    case 3:{PORTD=0x4f;break;}
    case 4:{PORTD=0x66;break;}
    case 5:{PORTD=0x6d;break;}
    case 6:{PORTD=0x7d;break;}
    case 7:{PORTD=0x07;break;}
    case 8:{PORTD=0x7f;break;}
    case 9:{PORTD=0x6f;break;}
    case 10:{PORTD=0x63;break;}
    case 11:{PORTD=0x39;break;}
    case 12:{PORTD=0x00;break;} //пустое место
    case 13:{PORTD=0x40;break;}//минус
    }
    }
    }

    // Declare your global variables here

    void main(void)
    {
    // Declare your local variables here
    float temper;
    unsigned int x;
    // Input/Output Ports initialization
    // Port B initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTB=0x00;
    DDRB=0xFF;

    // Port C initialization
    // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTC=0x00;
    DDRC=0x00;

    // Port D initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTD=0x00;
    DDRD=0xFF;

    // Timer/Counter 0 initialization
    // Clock source: System Clock
    // Clock value: Timer 0 Stopped
    TCCR0=0x00;
    TCNT0=0x00;

    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: 1000,000 kHz
    // Mode: CTC top=OCR1A
    // OC1A output: Discon.
    // OC1B output: Discon.
    // Noise Canceler: Off
    // Input Capture on Falling Edge
    // Timer1 Overflow Interrupt: Off
    // Input Capture Interrupt: Off
    // Compare A Match Interrupt: On
    // Compare B Match Interrupt: Off
    TCCR1A=0x00;
    TCCR1B=0x0A;
    TCNT1H=0x00;
    TCNT1L=0x00;
    ICR1H=0x00;
    ICR1L=0x00;
    OCR1AH=0x10;
    OCR1AL=0x46;
    OCR1BH=0x00;
    OCR1BL=0x00;

    // Timer/Counter 2 initialization
    // Clock source: System Clock
    // Clock value: Timer2 Stopped
    // Mode: Normal top=FFh
    // OC2 output: Disconnected
    ASSR=0x00;
    TCCR2=0x00;
    TCNT2=0x00;
    OCR2=0x00;

    // External Interrupt(s) initialization
    // INT0: Off
    // INT1: Off
    MCUCR=0x00;

    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=0x10;

    // Analog Comparator initialization
    // Analog Comparator: Off
    // Analog Comparator Input Capture by Timer/Counter 1: Off
    ACSR=0x80;
    SFIOR=0x00;

    // 1 Wire Bus initialization

    // 1 Wire Bus initialization
    // 1 Wire Data port: PORTC
    // 1 Wire Data bit: 5
    // Note: 1 Wire port settings must be specified in the
    // Project|Configure|C Compiler|Libraries|1 Wire IDE menu.
    w1_init();
    ds18b20_init(0,-20,50,DS18B20_12BIT_RES);
    // Global enable interrupts
    #asm(«sei»)

    while (1)
    {
    // Place your code here
    temper=ds18b20_temperature(0);
    if (temper>1000)
    {
    temper=4096.0-temper;
    minus=1;
    }

    x=temper*10;
    number4=x%10;
    x=x/10;
    number3=x%10;
    number2=x/10;
    if(minus==0)
    {
    number1=12;
    }
    else
    {
    number1=13;
    }
    }
    }

  • попробуйте завести в протеусе, там можно пошагово смотреть каждую строчку, каждую переменную.

  • Хочу поделится опытом. Столкнулся с такой проблемой, при использовании функции измерения температуры совместно с любым прерыванием, возникают периодически «глюки» в показаниях термометра, отловить подобные «глюки» тяжело поскольку появляться они могут с большим периодом времени. Лечение банально просто, перед выполнением функции опроса датчика температуры нужно запретить глобальные прерывания, а затем разрешить. Проверенно!!! Пример кода ниже.
    #asm(«cli») // Запрет прерывания
    temp_reg=ds18b20_temperature(0);// Чтение температуры из датчика
    #asm(«sei»)// Снова разрешения разрешить прерывания
    delay_ms(1000); // Затем идет только пауза между опросами датчика.

  • Андрей,да это так. Работа шины 1wire реализована на задержках. Каждое прерывание влияет на них отсюда и проблемы.

  • Уважаемые знатоки… Я прекрасно понимаю что система 1-проводная построена на задержках ( а точнее датчик в зависимости от «битности» нужно на преобразование температуры от 100 до 700 мс)И все знатоки говорят что надо запрещать прерывание!Но 1 , 2 , 3 индикатора их частота динамической индикации в пределах( 1-10 мс) Я все понимаю… НО ничего не понимаю!!!!В лучшем случае прерывание будет запрещено на 100 мс (это 9 бит и 100 гц!)мб с 1 индикатором это и не заметно но , 3,4 и более? а время преобразования 750 мс(12 бит)? это же провал в 1 секунду от прерываний (грубо говоря).У меня диссонанс образуется в голове!! А люди не запрещающие прерываний видимо вообще «читера » какие-то раз у всех все работает)

  • Все верно. Вариантов решения несколько. Гасить индикаторы на время изменения. Не использовать динамическую индикацию. Поставить сдвиговый регистр или другую внешнюю микросхему. Можете ещё загуглить апнот как работать с 1wire через уарт.

  • Для Tenken.
    Я решил проблему проще. При «глюках» функция выдает значение -9999 или +9999 (не помню), заблокируйте программно все что выходит за пределы -55гр. до +120гр., и все. Поскольку «глюки» «выскакивают» не часто особых неудобств это не доставляет. И добавьте алгоритм обработки ошибки, если выпадает 5 «глюков» подряд значить датчик отвалился. Что-то вроде этого:
    if(temp-55) // Если температура больше -55 гр. То.

  • Правда я использовал символьный дисплей, при прерывании каждые 100 мс. «глюк» проявлялся раз в 15 минут. Стало явно видно поскольку символьный дисплей запоминает предыдущее состояние.

  • Андрей дал мне надежду) хоть и не помог) Кое что получилось , но пока рано о результатах. Заработал себе»сдвиг» по фазе)Шутка.Вообщем сейчас я получаю температуру, Как и положено из 2 первых байт.Целые числа я понимаю как вытянуть)

    data[0] = onewire_read();
    data[1] = onewire_read();
    t = (data[1] << 8) | data[0];
    t1=t/16; //тут все понятно , вроде, я запихиваю 2 байта в переменную т,двигая внутрь сначала 1 потом второй)(стащил эту фичу))) которую я создал в виде.int16_t t; .А потом делю число на 16 и получаю чистое десятичное число))запихивая в инт t1
    Но с операциями сдвига у меня туго.Проблема в том что значения минусовой температуры и значения температуры после знака .Хранятся в первом полубайте старшего байта и во втором полубайте младшего байта.Вообщем моя голова пока не может понять как мне сдвинуть (и надо ли вообще двигать их )чтобы из числа например
    1010 1001 (вытянуть 1001 это числа после запятой.)

  • стоп!) не надо ничего подсказывать) сначала прочту» Студентам. О переменных. Популярно» .не увидел)

  • Для Tenken Код который использовал бы я.

    temp_izm=ds18b20_temperature(0);// Чтение температуры из датчика
    delay_ms(1000); //Задержка между измерениями
    if(temp_reg-55) // Если температура больше -55 гр.
    { // То
    temp_otob= temp_izm; // Температура отображения равна температуре измерения.
    } Все что выходит из диапазона до -55 до+120 отсекается (глюки ошибки и т. д.), хочу оговорится, я не знаю сколько ошибок будет «вылетать» при использовании нескольких датчиков.
    Далее число temp_otob нужно разложить на составляющие (каждую цифру по отдельности) для дальнейшего отображения на семисегментном индикаторе, как это сделать Администратор объяснит лучше меня, в зависимости сколько разрядов вы используете.

  • Знаки «больше» и «меньше» почему-то не отображаются при выкладывании кода в комментариях, просто имейте ввиду.

  • Добрый день. Объясните пожалуйста форматирование из примера для 2х датчиков ds18b20? lcd_buf,"t1=%.1f\xefC t2=%.1f\xefC" Что за слеш после 1f? что такое xef?

  • Не разберусь как вывести на LCD, float temper через LCD_putchar( )? Пробовал как в теме с часами, но получается какая-то ересь.

  • Спасибо, почитал, изучил. Дошло как пользоваться указателем. А вот как вывести число с запятой, так и не пойму. Хочу вывести значение температуры на LCD с ds18b20.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Последние комментарии
  • Загрузка...
Счетчик
Яндекс.Метрика