Пищалка из ATtyni13, help?

Тема в разделе "Микроконтроллеры AVR", создана пользователем Сергей777, 6 дек 2016.

  1. Сергей777

    Сергей777 Нерд

    Грамотные люди, поможите?
    с tyni13 на пьезодинамик при помощи analogWrite() выводится сигнал. Как менять его частоту? В сторону какого регистра посмотреть?
    Функция tone() не подходит по понятным причинам.
     
  2. Airbus

    Airbus Радиохулиган Модератор

    А у Вас какие идеи?Под Тини 13 пишу на ассемблере очень редко под си. Полагаю что изменение тона длительностью задержки между дрыганием ножки (переходом 0 в 1 и обратно). Можно скетч глянуть?
     
  3. rkit

    rkit Гуру

    Регистры таймеров/счетчиков. Где-то в разделе даташита по ним было и про изменение параметров ШИМ.
     
  4. ostrov

    ostrov Гуру

    По сути это тот же blink только очень быстрый. Можно сделать кучей способов, и с помощью delay и с помощью millis, и с помощью прерыванию по таймеру (самое кошерное).
     
  5. mcureenab

    mcureenab Гуру

    Вкурите даташит 11. 8-bit Timer/Counter0 with PWM

    Таймеры управляют ножками OC0A и OC0B - Т.е. два таймера, два выхода - полифония, считай!

    Существует несколько режимов. Для генерации волны можно использовать:
    11.7.2 Clear Timer on Compare Match (CTC) Mode
    Таймер считает с частотой тактирования ввода/вывода деленной на масштаб 1, 8, 64, 256, или 1024. Формула для расчета частоты генерации написана в даташите.

    Когда счетчик достигает порога, он сбрасывается в 0, а ножка OC0A меняет состояние.

    Если нужно, МК генерирует прерывание. Обработчик прерывания может поменять порог таймера и масштаб чтобы следующие полупериоды стали длиннее или короче.
     
  6. Airbus

    Airbus Радиохулиган Модератор

    Вкурил уже лет 8 как. И как Вы это собираетесь сделать в среде Ардуино IDE? А самое главное зачем? Может всё таки AVR Studio или CV AVR?
     
  7. mcureenab

    mcureenab Гуру

    Без проблем. Arduino IDE это C++ со всеми его возможностями низкоуровневого программирования МК.
     
  8. Airbus

    Airbus Радиохулиган Модератор

    Понимаю там ещё танцы с бубном при выборе платы?И код в три раза большего размера чем на асме?
     
  9. mcureenab

    mcureenab Гуру

    Нет. Выбираешь модель МК и собираешь проект. Выбираешь программатор и заливаешь код в МК. -- IDE!

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

    Если программа помещается в память, то и пофиг, какой у нее размер. Сишный код из функции main() может быть в сотни байтов. Но дальше он не сильно растет.
     
  10. Airbus

    Airbus Радиохулиган Модератор

    Ну так скетч покажете?Там где заюзан таймер?
     
    Последнее редактирование: 7 дек 2016
  11. mcureenab

    mcureenab Гуру

    Код (C++):

    // http://www.atmel.com/webdoc/AVRLibcReferenceManual/index.html

    // ATtiny13

    void set_scale(char mode)
    {
      asm volatile (
        "cli"  "\n\t"
        "ldi r16, %[CLKPCE_]" "\n\t"
        "out %[CLKPR_], r16" "\n\t" // Enable change clock prescale
        "out %[CLKPR_], %[DIV_]" "\n\t"
        "sei" "\n\t"
        :
        : [CLKPCE_] "M" (1<<CLKPCE),
          [CLKPR_] "I" _SFR_IO_ADDR( CLKPR ),
          [DIV_] "r" ( mode )
        : "r16" );
    }

    const uint8_t octava [] = {
      (1<<CLKPS3)|(0<<CLKPS2)|(0<<CLKPS1)|(0<<CLKPS0),
      (0<<CLKPS3)|(1<<CLKPS2)|(1<<CLKPS1)|(1<<CLKPS0),
      (0<<CLKPS3)|(1<<CLKPS2)|(1<<CLKPS1)|(0<<CLKPS0),
      (0<<CLKPS3)|(1<<CLKPS2)|(0<<CLKPS1)|(1<<CLKPS0),
      (0<<CLKPS3)|(1<<CLKPS2)|(0<<CLKPS1)|(0<<CLKPS0),
      (0<<CLKPS3)|(0<<CLKPS2)|(1<<CLKPS1)|(1<<CLKPS0),
      (0<<CLKPS3)|(0<<CLKPS2)|(1<<CLKPS1)|(0<<CLKPS0),
      (0<<CLKPS3)|(0<<CLKPS2)|(0<<CLKPS1)|(1<<CLKPS0),
      (0<<CLKPS3)|(0<<CLKPS2)|(0<<CLKPS1)|(0<<CLKPS0),
    };

    void setup() {
      // put your setup code here, to run once:
      set_scale(octava[0]); // 256
      OCR0A = 240;  // Frequency divider
      TCCR0A = TCCR0A & !(_BV(COM0A1)|_BV(COM0A0)) | _BV(COM0A0); // COM0A1:0 = 1; Timer/Counter Control Register A; Toggle OC0A on Compare Match
      DDRB = DDRB | _BV(DDB0);  // I/O Output PB0 = COM0A
    }

    void loop() {
      // put your main code here, to run repeatedly:
    }
     
    просто пищалка, по сути tone.
    код 204 байта

    проверить пока не на чем
     
  12. Airbus

    Airbus Радиохулиган Модератор

    Я проверю.Должно просто пищать?Фьюзы дефолтные?
     
  13. VITAL_P

    VITAL_P Нерд

    И как, сей код будет понятен новичку который начинает осваивать МК... Причем здесь вообще ардуино в изначальной своей простоте?
     
    mcureenab нравится это.
  14. mcureenab

    mcureenab Гуру

    В изначальной простоте - никак. Если полезная функция получится, можно библиотекой оформить с простым интерфейсом.

    Новички думают, что Ардуино, это вещь в себе. А тут видно, что можно сочетать простые методы с ассемблером.
     
  15. VITAL_P

    VITAL_P Нерд

    Оно то так, но это не совсем понятный ответ на вопрос автора. Вполне понятное желание, собрать что то,
    на маленьком контроллере типа ATtiny13. Нужно разъяснять, что среда ардуино для этого не предназначена.
    А писать типа OCR0A =240; это в слепую, или вы скажете, что с помощью даташита это делаете)))
    Писать на ассемблере в ардуино это вообще мазохизм....(или понты) как вы смотрите что там в регистрах творится.... или тоже в слепую)))
    И вряд ли кто то ассемблере в чистую пишет... максимум это откомпилированный С оптимизируют на ассемблере.
    Просто такие ответы на вопрос зачастую только запутывают начинающих. И человек видит не понятное (типа очень сложное) бросает этим заниматься.
    Особо сложного там ничего нет, просто нужно использовать правильные инструменты.
    Главное понять принципы, а далее берешь любой контроллер и просто пишешь.... потом замечаешь что поле типа:
    void loop() {
    }
    вообще пустое, и зачем оно совсем нужно....
    Ответ прост: хотите что то писать на контроллеры отличные от стандартных ардуино, используйте более информативную среду разработки. Где видны все счетчики прерывания и т.д.
     
  16. ostrov

    ostrov Гуру

    Почему не взять Тини85? У 13 кроме малой памяти глюки замечены.
     
  17. mcureenab

    mcureenab Гуру

    Ваш опус длиннее моего скетча раза в три. Если что то непонятно, спрашивайте. Если есть решение лучше, предлагайте.
    loop () полезен для запуска асинхронных процедур после обработки прерывания.
    Хитрость в том, что команда sleep завершается после прерывания.
     
  18. Airbus

    Airbus Радиохулиган Модератор

    Пищалка на "чистом" (или Голом) си под тини 2313. При желании можно сделать под тини 13 если подправить регистры
    Код (C++):
    /*****************************************************
    Comments: Сигнализатор "Семь нот"
    Chip type           : ATtiny2313
    Clock frequency     : 4,000000 MHz
    *****************************************************/


    #include <tiny2313.h>

    // Объявление и инициализация массива коэффициентов деления
    flash unsigned int tabkd[7] = {4748,4480,4228,3992,3768,3556,3356};


    void main(void)
    {
    unsigned char count;  // Определяем переменную count
    unsigned char temp;  // Определяем переменную temp

    PORTB=0x08;   // Инициализация порта PB
    DDRB=0x08;

    PORTD=0x7F;   // Инициализация порта PD
    DDRD=0x00;

    ACSR=0x80;   // Инициализация (отключение) компаратора

    TCCR1A=0x00;   // Инициализация таймера счетчика T1
    TCCR1B=0x09;

    while (1)
          {
    m1:   temp=PIND;
          for (count=0; count<7; count++)
            {
            if ((temp&1)==0) goto m2;
            temp >>= 1;
            }
          TCCR1A=0x00;
          goto m1;
    m2:  
          OCR1A=tabkd[count];
          TCCR1A=0x40;
          };
    }
     
     
    Alex19 нравится это.
  19. VITAL_P

    VITAL_P Нерд

    Так просто не переделаешь... у ATtiny13 нет 16 разрядного счетчика.
    Код (Text):
    #include <avr/io.h>
    #include <avr/interrupt.h>
    ISR(TIM0_COMPA_vect)
    {
    PORTB^=(1<<0);    // 5 нога МК можно менять
    TCNT0=0;
            }
    int main(void)
    {
        DDRB=0b000001;
        PORTB=0b000000;
        TCCR0B=0x03;
        TIMSK0=0x04;
        asm("sei");
        OCR0A=100; //частота 255-280Гц.......1-40000Гц
        while(1)
        {
    }
    }
    9,6Мгц. делитель на 8 отключен.
    И вообще, какого рода пищалка нужна?
     
  20. mcureenab

    mcureenab Гуру

    Мне ассемблер понадобился для изменения масштаба осциллятора - октавы. Его нужно за 4 такта поменять.
    У тини 13 таймер 8 битный. По нотам на ней будет сложно играть. Грубая настройка. И низы он не берет.