Подписаться на получение новых статей на почту:

Шаг№26. Используем ШИМ для построения синусоиды на ATmega8

Здравствуйте дорогие читатели. В прошлый раз мы рассмотрели применение контроллера для проверки реле. В этой статье разберем работу самого контроллера. Итак все “крутится” вокруг генерирования синусоиды. Рассмотрим процесс генерирования. Тут нам не обойтись без ШИМ.

Познакомившись c ШИМ управлением на AVR и его настройкой, а также рассмотрев наглядные примеры его использования, такие как Контроллер на ЧПУ станок (Статья№15), ПИД-регулятор для синхронизации двигателей станка и многое др. В этой статье научимся использовать вывод OC2 как ШИМ для получения синусоиды. На рисунке изображен контроллер, где присутствует вход для синхронизации, генерации, а также кнопки для сдвига графика.

ШИМ как ЦАП на atmega8

            Настраиваем таймер Т2. Настраиваем регистр управления таймера/счетчика ТССR2=0×69. Выбираем режим работы FastPWM, вывод при равенстве регистров OCR2 иTCNT2 сбрасывается в 0, и источник тактового сигнала – частота контроллера без делителей. Таймер настроили. Чтобы получить синусоиду, естественно ШИМ должен меняться по определенным значениям, которые мы заносим в массив. Т.е. в каждый момент времени OCR2=sin_table[i]. При каждом шаге инкрементируем порядковый номер. Соответственно изменяется скважность выходящего сигнала.

            Далее разберемся где будем брать значения для построения графика. Есть два варианта. Первый: Значения в массив мы можем занести еще в исходнике, например

intsin[128]={127,134,140,146,152,158,164,170,176,182,187,193,198,203,208,213,217,222,226,230,233,236,240, 242,245, 247,249,251,252,253,254,254,254,254,254,253,252,251,249,247,245,242, 240,236,233,230, 226,222, 217,213,208,203,198,193,187,182,176,170,164,158,152,146,140,134,127,121,115,109,103,97,91 
,85,79,73,68,62,57,52,47,42,38,33,29,25,22,19,15,13,10,8,6,4,3,2,1,1,0,1,1,2,3,4,6,8,10,13,15,19,22,25,29,33,38,42,47,52,57,62,68, 
73,79,85,91,97,103,109,115,121};

Второй: рассчитываем по формуле прямо в программе. Я выбрал второй вариант. Будем использовать математическую библиотеку , функцию sin (x). Сигнал меняется от -1 до 1. Отрицательное напряжение мы не сгенерируем, поэтому поднимаем график на 1 по оси Y. Сигнал меняется от 2 до 0, формула приобретает вид: sin (x)+1. Т.к. ШИМ у нас 8-битный, то максимальное значение 255, до множим нашу формулу на 127, чтобы максимально приблизится к 255, получаем 254 и формула у нас имеет вид: (sin (x)+1)*127. Номер значения подставляемое в функцию запишем следующим образом 2*p/MAX_INT. Постоянная MAX_INT – дает возможность нам задавать разрешения построение синуса. И получим следующую формулу:

sin_table[i]=(byte)((sin ((float) j*(2*p/MAX_INT))+1.0)*127.0);

где j – порядковый номер элемента.

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

Ниже приведена функция для расчета точек синуса.

void sin_init () {
     bytei=0;     // счетчик
     do {
           sin_table[i]=(byte)((sin ((float) j*(2*p/MAX_INT))+1.0)*127.0);
           i++;
j++;
           if (j == MAX_INT) /* здесь происходит проверка сдвига волны, если сдвигаемое значение достигло максимума, то начинаем считать от нуля до максимума*/
           j=0; 
           #if MAX_INT<256
           } while (i!=MAX_INT);
           #else
          } while (i!=0);
         #endif
         }

Дальше нам необходимо строить точки графика с определенной частотой. Поместим строку OCR2=sin_table[i] в прерывание таймера Т1, который также будет прерываться по сравнению с регистром сравнения.

ISR (TIMER1_COMPA_vect){ // прерывание по сравнению
        OCR2=sin_table[i];   /*стоим синусоиду, подставляем в регистр сравнения таймера 2 значен7ия синуса изменения скважности импульсов */
        i++;
        if (i>MAX_INT-1)
       {
             i=0;  
       }
  } 

Теперь перейдем к настройке таймера Т1 МК ATmega8. Устанавливаем регистр управления TCCR1B = 9: режим работы сброс при совпадении  и источник тактового сигнала – частота контроллера без пред делителей. Теперь переходим к регистру сравнения таймера Т1  OCR1A, который будет отвечать за задание частоты. Данную константу можно задавать в начале программы, и подставлять в формулу:

OCR1A=Тактовая частота контроллера / MAX_INT / FREQUENCY ;
Где частоту контроллера делим на разрешение синуса и на заданную частоту.

Но если вдруг у нас станет вопрос синхронизации выходного сигнала с входным, например с частотой сети, то данная формула нам не поможет. Так как не секрет что частота сети колеблется , например 49,99-50,001… и это в лучшем случае. А также генератор контроллера с плавающей частотой,  которая зависит от температуры и всего прочего. Здесь нам придется задействовать еще два прерывания. Первое: внешнее прерывание по входящему импульсу по нарастающему фронту:

ISR (SIG_INTERRUPT0){
           fsin = (256*t0)+TCNT0;  /*рассчитываем частоту на входе*/
           t0 = 0;
          TCNT0 = 0;
}

Выше представленный код рассчитывает частоту по каждому прерыванию по входящему импульсу.

Второе прерывание подсчитывает количество прерываний таймера Т0.

SIGNAL (SIG_OVERFLOW0)
{
        t0++;
}

Всё, все три таймера дружно работают над формированием сигнала. И последнее я вышел писал что мы повторно используем инициализацию синуса. Это нам необходимо для сдвига. Посмотрим на рисунок ниже. В формуле представлена переменная j, которая отвечает за порядковый номер элемента. Меняя эту переменную в момент инициализации функции sin_init (), от 0 до 255 мы можем менять угол сдвига выходящего сигнала. Т.е. мы сдвигаем фазу за счет начала генерирования синусоиды с определённой точки.

 

сдвиг по фазе на atmega8

В предыдущей статье программа была опробована в устройстве для проверки реле. Там же можете просмотреть все скриншоты полученных графиков.  Ниже выкладываю файл для Proteus на ATmega 8A, с описанными выше функциями.

Генерирование, синхронизацция и сдвиг синосоиды в Proteus. ( Скачали: 844 чел. ) 

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

Просмотрено 21002 раз.

Я на Google+

Шаг№26. Используем ШИМ для построения синусоиды на ATmega8: 14 комментариев

  1. Довольно интересно решен вопрос сдвига и сихронизации переменого тока. Конечно насколько в реальности оно покажет стабильную работу. Но все равно спасибо за статью.

    • Здравствуйте. Если Вы посмотрите предыдущюю статью №25, то даннай способ был применен в устройсве для проверок реле РЗД, которое отслеживает сдвиг по фазе тока, и показало стабильную работу.

  2. Неплохо решен вопрос синхронизации и формирования синуса, наверное можно применить в отрасли альтернативной энергетики или что то подобное. Спасибо.

  3. Здравствуйте, подскажите, как изменится формула расчета синуса, если надо ее строить не от 0 до 255, а допустим от 64 до 255 или например от 100 до 255? (т.е. нижнее значение можно менять)

    • Злравствуйте, формула не меняется, просто j в цикле пусть начинается не с нуля а от 100 или 64.

  4. Эххх ... столько в нэте искал инфу, научился синусоиду шимить и вот только набрел на ваш сайт ((( Спасибо за интересную статью, с помощью уравнения не догадался строить массив синуса.

    Подскажите как прилепить к выходу ШИМ контроллера полевик и к его каналу D-S добавить RC-фильтр? Хочу получить синусоиду большей амплитуды, нежели 5 Вольт

    • Я когда — то делал ЧПУ контроллер , и производил управление шагового двигателя через полевик. Данную работу я описал в статье №15. Схему я не выкладывал, поэтому рисунок драйвера для шаговика на рисунке по ссылке(

      www.ap-impulse.ru/wp-cont...16/12/answer.jpg)

      Там видна обвязка, резистор на 1 или 10 ком, помогает открытся полевику, как бы прокачивая его высоким напряжением 12 В. Для защиты биполярного транзистора, необходимо поставить еще один резистор между затвором полевика и коллектором биполярного транзистора. Но я его себе не ставил

  5. скажите как сделать три фазный генератор какой контролер применить?и почему используется все 3 таймера если можно 2

    • Думаю можно былоб и на 8. Надо было б поиграться немного. Но для серьезных вещей 48, 88, 168. Ваш вариант кода на 2.

  6. Вроде как у него используется восьмибитный таймер номер 2 для генерации ШИМ и используется таймер номер один,для генерации прерываний и изминений скважности ШИМ в обработчике прерываний.

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

Ваш e-mail не будет опубликован.

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Subscribe without commenting