Как сделать прерывания для считывания показаний датчика при динамической индикации

Тема в разделе "Arduino & Shields", создана пользователем blackflash2009, 8 авг 2023.

  1. Есть некий код написанный на ардуино иде выполняет функции по динамической индикации 3 секционного 7 сегментного индикатора. устройство на выходе это термостат с изображением данных на дисплей. Дисплей представляет из себя микросхему счетчика cd4026 на пины которого подается быстрые импульсы для счета , то есть надо вывести число 7 подается сигнал на включение 1 разряда дисплея затем МК с частотой 1Мгц включает и отключает ногу подключенную к 1 ноге микросхемы cd4026 8 раз затем отключает 1 разряд, сбрасывает счетчик подовая импульс на 15 ногу и также делает для 2 разряда и 3. Все в принципе работает но проблема в том что датчик DC18B20 работает по хитрому способу сначала посылается запрос затем получаешь ответ между запросом и ответом долно пройти не менее 750мили секнд. Может кто занет как написать прерывание которое послала бы запрос датчику, затем продолжалось отрисовка дисплея через 1с получили ответ и послали снова запрос и дальше продолжили отрисовку дисплея. На данный момент в коде используется delay и delayMicroseconds для задержки между командами на счет сегментов и разрядов. Если нужно будет могу выложить код (кривые костыли дилетанта )
     
  2. забыл указать связался я с cd4026 потому что код пишется для аттини 13 отображение числа 65 например занимает 20% памяти (вывод на дисплей разбивка числа на составляющие ) код на считывание данных с датчика + вывод на дисплей занимает 56% но вовремя опроса датчика дисплей не показывает думаю вряд ли прерывание должно занять оставшиеся 44% памяти
     
  3. parovoZZ

    parovoZZ Гуру

    На самом деле, прерывания - очень сложная тема. Всю программу надо писать с учётом того, что в коде есть прерывания. В одной из своих тем я показывал, как работать с прерываниями и шиной I2C. C 1-wire - аналогично.
    И это - русский бы подтянуть. ЭТО невозможно читать.
     
  4. b707

    b707 Гуру

    для этого не нужно прерывание.
    Делайте как написали - сгачала посылайте запрос на датчик, потом в течении 1 сек отрисовывайте дисплей, потом читаете данные с датчика и показываете. Только от delay() надо избавится и переписать это на миллис.
    Обычный конечный автомат или по-анлийски "finite state machine" - поищите в гугле
     
  5. User248

    User248 Гик

    Библиотеку TimerOne посмотрите. Прерывает работу delay на период своего выполнения.
     
  6. В общем как термометр он пытается работать только опрос датчика занимает какое то время в результаты при получении ответа дисплей моргает раз в секунду ( ориентировочно 2 миллисекунды время маргания. ) Прерывания не делал вкорячил цикл счетчик как задержка на большее мозгов не хватило.
     
  7. a1000

    a1000 Гуру

    Не пугай людей. Всё элементарно делается на таймере. Я даже когда-то встречал библиотеку для таймеров для нежелающих вникать в регистры. ТС не захотел вникать а аппаратный таймер, создал программный аналог.
     
  8. parovoZZ

    parovoZZ Гуру

    А зачем библиотека для 3-х строчек кода?
     
    a1000 и DetSimen нравится это.
  9. User248

    User248 Гик

    TimerOne, о которой я сказал выше?
     
  10. User248

    User248 Гик

    Потому что удобно. Библиотеки заточены сразу под разные микроконтроллеры. Макросы делают своё дело. Лично мне не нужны лишние заморочки.
     
  11. parovoZZ

    parovoZZ Гуру

    китайская промышленность предлагает огромное разнообразие градусников на любой вкус и кошелёк.
     
  12. a1000

    a1000 Гуру

    Я знаю, что надо всего лишь подправить значение пары-тройки регистров, но надо ведь знать каких и что именно туда писать. А ардуинщик лучше пол дня будет искать готовую библиотеку чем почитает мануал по микроконтроллеру.
    Ну хочется человеку DC18B20, и что с этим поделаешь?;)
     
  13. a1000

    a1000 Гуру

    Знакомое название, скорее всего она.
    Не всё там так страшно как кажется. Один раз разобраться и понять сам принцип управления таймером. В других моделях всё будет аналогично. Могут немного поменяться символические имена регистров или пара битов.
     
  14. А как таймерами управлять ? когда запрос от мк к датчику занимает время (я фиг знаю что он там передает так долго ) моргает дисплей тогда когда мк отправляет запрос датчику.
    Да и резиновых баб тоже там делаю. Покупай
     
  15. User248

    User248 Гик

    Примеры посмотрите в папке examples.
     
  16. Есть переменная полученная в результате преобразования числа в десятки единицы (скажем условно 2) компилируется код занимает 2% памяти. Скомпилировал код для проверки с монитором порта увидел значение 2. Как только эту переменную ставлю в код (цикл фор ) Сразу появляется значение 112% памяти занято. Убираю переменную ставлю цифру 2 в цикле занято 5% памяти не могу понять в чем прикол ?
     
  17. b707

    b707 Гуру

    Может в том, что никакого кода у вас и нет?
    Я, во всяком случае, не видел.

    @blackflash2009, а нафига вам такое хобби, если вы ни черта в программировании не понимаете и учиться не хотите?
     
  18. parovoZZ

    parovoZZ Гуру

    в отсутствии базовых знаний.

    В программировании как в спорте - перестаёшь заниматься, сразу теряешь хватку.
     
  19. Чтобы перестать надо когда то делать.
    Да пожалуйста
    Код (C++):
    #include <avr/io.h>    
    #include <util/delay.h>
    #define SHE PB2         // нога импульсов на счет PB2
    #define SBR PB1         // нога сброса счетчика  PB1
    #define SEG1 PB4         // нога сброса счетчика  PB4
    #define SEG2 PB3         // нога сброса счетчика  PB3
    int8_t temp;    // освобождаем память для переменной "temp"
    int8_t grad; // освобождаем память для переменной "grad"

    void setup() {
       pinMode(A0, INPUT);
    // нога подачи сигнала на отсчет
       DDRB |= (1<<SHE);     // конфигурируем пин как выход
       PORTB &= ~(1<<SHE);   // по умолчанию  выключен
        // нога сброса счетчика
        DDRB |= (1<<SBR);     // конфигурируем пин как выход
        PORTB &= ~(1<<SBR);   // по умолчанию  выключен
       // нога первого сегмента
          DDRB |= (1<<SEG1);     // конфигурируем пин как выход первый сегмент
          PORTB &= ~(1<<SEG1);   // по умолчанию  выключен
       // нога второго сегмента
            DDRB |= (1<<SEG2);     // конфигурируем пин как выход второй сегмент
            PORTB &= ~(1<<SEG2);   // по умолчанию  выключен
    }

    void loop() {
    temp = analogRead(A0); // переменная находится в интервале 0 - 1023
    grad = ( temp/1023.0 )*5.0*1000/10; // формулу можно изменять
      int8_t var2 = (grad/10%10);
      int8_t var3 = (grad%10%10);
         //  --------выводим значения на 1 знак   ------------------
    //------------сбрасываем микрасхему cd2026------------------------------
         PORTB |= (1<<SBR);// состояние пина включить
         delayMicroseconds(1);    // задержка
         PORTB &= ~(1<<SBR); //  состояние пина выключить
    //------------------------------------------------------------              
    for (int i = 0; i < var3 ; i++) {
       delayMicroseconds(1); // задержка между импулсами на пин клок с частотой 1мГц
       PORTB |= (1<<SHE);  // инвертируем состояние пина включить
       delayMicroseconds(1);
       PORTB &= ~(1<<SHE);  // инвертируем состояние пина выключить
    //----------------------------------------------------------------  
    }
    PORTB |= (1<<SEG1);     // включаем 1 знак
    delayMicroseconds(6000) ;
      PORTB &= ~(1<<SEG1);   // выключаем 1 сегмент
    }
     
  20. grad проблема в этой переменной если написать int8_t grad =22; по занято 8% памяти если как в коде 102%