Ищу педагога по МК!

Тема в разделе "Флудилка", создана пользователем partizanen, 27 июн 2018.

  1. ещё раз спасибо. Аппетит приходит во время еды). Когда понял что можно творить с помощью таймеров и счётчиков совсем покой потерял. Этож какие возможности !!! А он только вскользь прошёлся по режимам счётчиков. Попробую курс до конца досмотреть мож где ещё будет на эту тему
     
  2. ИгорьК

    ИгорьК Давно здесь

    Попробуйте почитать книжки - их полно, в т.ч. и в Интернете. Ох уж это высшее образование по фильмам...
     
    Igor68, CYITEP_BAC9I и Сусемьбек нравится это.
  3. parovoZZ

    parovoZZ Гуру

    Есть отличный ресурс gaw.ru. Там очень много по теме. Ну а лучшее - это даташит и апноуты на сайте микрочипа.
     
    CYITEP_BAC9I и Сусемьбек нравится это.
  4. parovoZZ

    parovoZZ Гуру

    сам посмотри. Я сам не терплю абдурино каналы, но в данном случае не про это)))
     
    CYITEP_BAC9I и Сусемьбек нравится это.
  5. ИгорьК

    ИгорьК Давно здесь

  6. parovoZZ

    parovoZZ Гуру

    У ди вообще сундук электроники)))
     
  7. Я наверное не острый. Но самостоятельно не получается работать с таймерами. Как работает понял. Но как самому все записать темный лес. И нигде нет подробного материала. Видно это удел избранных владеть этой информацией), кстати вопрос почему в даташите на схеме у ТС1 , обозначены два порта с которых он может принимать сигналы. T1, ICP1, но в дальнейшем описании описывается работа только с Т1(может ли он одновременно считать импульсы с 2х портов)??? И можно ли использовать этот таймер как таймер, если он работает в режиме счетчика. Понимаю что вопросы для профи возможно дикие. Но не нашел самостоятельно ответов. Как не крути нужен живой сенсей рядом, которого можно подастовать вопросами)
     
  8. parovoZZ

    parovoZZ Гуру

    МК какой? Таймер - это блок. В этом блоке счетчик. У этого счетчика есть предделитель. Предделитель тактируется от осциллятора мк. Каждый таймера может тактироваться от любого разряда предделителя, но сброс предделителя общий. Про ICP1 здесь хорошо описано
    http://microsin.net/programming/AVR/atmega-ct1-pulse-counting.html

    Что не понятно - спрашивай.
     
    Mitrandir, CYITEP_BAC9I и Сусемьбек нравится это.
  9. Спасибо! Atmega328. Повременю пока с вопросами, иначе задолбаю раньше чем пойму) попробую пописать в симуляторе, чтоб были наработки с которыми можно обращаться. Это как блинк на 13 пине у новичка, только на другом уровне. На народ стрим есть разжовывалка про стм32, тоже интересная весч. Хоть разорвись, или таймеры счётчики осваивать или стм изучать
     
  10. Mitrandir

    Mitrandir Гуру

    Симуляторе?
     
  11. https://arduinomaster.ru/program/simulyator-arduino-tinkercad-circuits/ прямую ссылку не помню так как с телефона пишу. Но там можно разобраться. Кто-то говорил что этот симулятор поддерживает прямое обращение к портам. Вот и попробую заодно. Сейчас правда планы на атмел студио перейти. На первый взгляд в чем то удобнее ардуино иде.
     
    Mitrandir нравится это.
  12. Mitrandir нравится это.
  13. parovoZZ

    parovoZZ Гуру

    ни в чем-то, а во всем)))
    Для абдурино накатываешь Visual Micro.
     
    CYITEP_BAC9I и Сусемьбек нравится это.
  14. parovoZZ

    parovoZZ Гуру

    CYITEP_BAC9I, Mitrandir и Сусемьбек нравится это.
  15. CYITEP_BAC9I

    CYITEP_BAC9I Гик

    продолжаю терзать даташит))). появляются смутные подозрения что на таймерах можно соорудить шим, который можно запустить абсолютно параллельно, задачам в основном цикле. интересно блин до жути. как Америку отрываю!
    Собственно вот и вопросы). если возможно только подскажите на правильном ли я пути или еще недогоняю. и какой материал нужно курить чтобы не разбрасываться временем. в общем скажем существуе дозиметр с 2 секциями датчиков. Сигналы с них принимать обычными внешними прерываниями пины 2,3 (если не забыл, давно уже не писал программки, а читать заново лениво), как имеющими самый высокий приоритет. затем на опрос компаратора раз 100 в секунду. выставить напряжение, как напряжение питания, если правильно понял даташит
    ADMUX |= (0 << REFS1)|(1 << REFS0) . само напряжение брать с делителя датчика. если напряжение меньше , запустить накачку датчика Шим сигналом. при срабатывании больше чем настроено в компараторе то отключить генерацию Шим (кстати или я неправильно подсчитал но больше 32000 гц не получить с шима?). а в основном цикле заниматься только рассчетами и выводом на экранчик. это возможно реализовать? или я неправильно понимаю суть , особенно работу АЦП?
     
    Последнее редактирование: 5 июл 2018
  16. parovoZZ

    parovoZZ Гуру

    Я тебе сейчас ещё одну хитрую штуку покажу.
    Код (C++):
        ADC_Init();  // Инициализация АЦП

        T0_Mode_CTC;   // Режим таймера - сброс при переполнении
        T0_Set_OCR0A;   // Записываем значение в регистр сравнения
        TIMSK0 = Bit(OCIE0A);   // Разрешаем прерывание от регистра сравнения
        T0_Start_64;   // Запускаем таймер

        ADC_Start_Conversion(ADC3);  // контрольный выстрел АЦП (в функции определен вход мультиплексора)

     
    Здесь настраиваем работу АЦП от таймера T0.
    Всё, что нам остаётся сделать, в прерывании считать значение АЦП
    Код (C++):
    ISR(ADC_vect)
    {
        Buf[in++] = ADC_Get_Data();
    }
    Функция инициализации АЦП
    Код (C++):
    void ADC_Init(void)
    {
        DIDR0 = (1<<ADC1D) | (1<<ADC2D) | (1<<ADC3D);
     
        ADMUX = (1<<REFS1) | (0<<REFS0);            // Внутренний ИОН 1.1в

        ADCSRB = (1<<ADLAR) | (1<<ADTS1) | (1<<ADTS0);        // Работаем только со старшими 8-ю битами, запуск от таймера T0

        ADCSRA = (1<<ADEN) | (1<<ADIE) | (1<<ADATE) | (0<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); // Прескалер = 8
    }
    Функция взятия значения из АЦП
    Код (C++):
     uint8_t ADC_Get_Data (void)
    {
         return ADCH;
    }
    Ручной запуск АЦП
    Код (C++):
     void ADC_Start_Conversion (uint8_t Analog_input)
    {
         ADMUX |= Analog_input;   // выбираем вход

         ADCSRA |= Bit(ADSC);    // запускаем преобразование
    }
    Дефайны
    Код (C++):
    //... Таймер 0
    #define T0_Start_64            TCCR0B = Prescaler_64; ClearPrescaler        // Пуск таймера с очисткой делителя
    #define T0_Start_256        TCCR0B = Prescaler_256; ClearPrescaler
    #define T0_Start_1024        TCCR0B = Prescaler_1024; ClearPrescaler
    #define T0_Stop            TCCR0B &= (~(Bit(CS00) | Bit(CS01) | Bit(CS02)))    // Останов таймера (делитель = 0)
    #define T0_Clear            TCNT0 = 0
    #define T0_Mode_Normal        TCCR0A = 0x00
    #define T0_Mode_CTC            TCCR0A = Bit(WGM01)

    #define T0_Set_OCR0A        OCR0A = 7//(F_CPU/(64 * Freq_dis) - 1)
    Т.Е. нам надо что-то оцифровывать в фоне с высокой стабильностью. Мы не запариваемся - таймер (в данном случае T0) всё делает вместо нас. Нам остаётся только уйти на прерывание и забрать значения из кольцевого буфера тогда, когда сможем. На стабильность работы АЦП это никак не влияет. Код для 24/44/84 аттини и легко переписывается под любой другой МК (инициализация АЦП и прерывание от него будут слегка отличатся).

    Все пины помеченные как PCINT способны вызывать прерывания. Работа с ними требует чуть побольше кода.

    Все прерывания в АВР имеют одинаковый приоритет (кроме сброса). Если возникает прерывание в момент, когда МК находится в обработчике текущего прерывания, оно становится в очередь. Если ещё одно - также в очередь. Если

    за один такт придет более одного прерывания - первым выполнится прерывание с меньшим адресом.
    На 16 МГц? Как считал?
     
    Последнее редактирование: 5 июл 2018
  17. CYITEP_BAC9I

    CYITEP_BAC9I Гик

    спасибо за ответ! таки да по моему можно и 62500 гц выжать
    TCCR0B=TCCR0B&0b11111000|0x01. пойду курить как скважность регулировать.
    УРААА!!!! работает!!!! радости как первый раз светодиодом помигал.))))
    Код (C++):
    void setup() {
      TCCR0B=TCCR0B&0b11111000|0x01;
      analogWrite(5, 100);
    }
    void loop() {
    }
    теперь думаю как его включать отключать когда накачка ненужна.
     
    Последнее редактирование: 6 июл 2018
  18. AlexU

    AlexU Гуру

    Раз заговорили о таймерах, то вставлю свои "пять копеек".
    Максимальная частота, которую можно получить аппаратно (т.е. без всяких digitalWrite() или PORTx = xxxxx), равна половине тактовой частоты процессора. Например для Ардуин на базе ATmega328P -- это 8 МГц. Но при этом с ШИМ'ом будут определённые трудности. Дело в том что начиная с определённой частоты (62,5 кГц), чем выше эта самая частота, тем меньше простора для регулирования скважности. При частоте 8 МГц скважность будет 50% и её ни как не поменять. При частоте 4 МГц скважность может быть: 25%, 50% или 75%. И так далее. Всё из-за того, что уменьшается диапазон счётчика таймера. Например для нулевого таймера штатно диапазон счёта от 0 до 255, но можно сделать от 0 до 1. Чем ниже диапазон, тем выше частота, но тем меньше возможностей влиять на ширину импульса.
    Ну и последнее ШИМ с высокой частотой доступен только на пинах 3,5,10, при этом на парных пинах (11,6,9) аппаратный ШИМ уже не получить (т.к. регистр OCRxA занят определением диапазона счёта).
     
    CYITEP_BAC9I, ИгорьК, Igor68 и ещё 1-му нравится это.
  19. AlexU

    AlexU Гуру

    Как-то эти две фразы не вяжутся друг с другом. Если приоритет одинаковый, то первым должно обработаться прерывание, возникшее раньше. А, если всё-таки, первым обработается прерывание с меньшим адресом, то это и называется прерыванием с более высоким приоритетом.
    Другое дело, что в AVR при обработке любого прерывания производится глобальный запрет обработки остальных прерываний. Поэтому новые прерывания не могут быть обработаны пока этот запрет не будет снят (а он может быть снят принудительно в обработчике). Такого же поведения можно добиться и в других видах процессоров, если при обработке прерываний глобально запрещать остальные.
    Но при этом всё-таки соглашусь, что приоритетность прерываний на аппаратном уровне реализована минимально упрощённо.
     
    CYITEP_BAC9I нравится это.
  20. AlexU

    AlexU Гуру

    Все Ваши задумки можно реализовать на прерываниях. Точнее на одном прерывании от ADC. Настраиваете ADC в режим постоянного семплирования, а в обработчике ADC_vect реализовываете функционал проверки уровня и при необходимости запускаете или останавливаете аппаратный ШИМ. При этом в основной программе можете делать другую работу.
    Но ранее сообщал, что время отклика такой системы будет выше, чем у специализированных микрух. Штатно ADC может работать на частоте 200 кГц (хотя можно и выше с понижением качества). На одно преобразование ему нужно 13,5 тактов, т.е. частота семплирования будет ~14кГц. Или другими словами замер будет делаться раз в 70 мксек. До какого уровня успеет зарядиться конденсатор за 70 мксек?
    Можно использовать не ADC, а аналоговый компаратор. У него время отклика будет меньше (честно говоря с компаратором ещё дела не имел поэтому точных цифр привести не могу). Но всё равно с учётом вызова обработчика прерывания и выполнения кода задержка реакции может быть в районе 2 мксек. Так что напряжение на выходе будет не очень стабильным и временами превышать максимальное.
     
    CYITEP_BAC9I нравится это.