В одном из ранних уроков мы узнали, что при помощи ШИМ можно изменять скважность сигнала. Тем самым регулировали яркость свечения светодиода. Однако есть более интересный способ, использования широтно-импульсной модуляции.
Итак… Если пропустить генерируемый сигнал через фильтр низких частот, то получится постоянное напряжение.
Так как скважность изменяется от 0 до 0xFF(255), значит у нас будет 255 уровней постоянного напряжения. Проще говоря, есть диапазон напряжения, допустим от 0 до 5В, этот диапазон разбивается на 255 значений. С шагом 5/255=0,0196В можно выставить любое напряжение.
Используя в определенном порядке эти значения, можно получить практически любую форму сигнала. Например, увеличивая заполнение от 0 до 255, а потом уменьшая от 255 до 0 получим пилообразный сигнал.
Теперь перейдем к конкретной цели: получить синусоиду с частотой 50Гц с помощью микроконтроллера Atmega8. Глобальная задача — выставлять через определенные промежутки времени напряжение на выходе ШИМ, по синусоидальному закону.
Разберемся с первой частью задачи. Для того, получить определенные промежутки времени воспользуемся таймером. Допустим таймер настроен на частоту 8МГц, т.е. он будет тикать 8000000 раз в секунду. Синусоида колеблется 50 раз в секунду, значит на один период может приходиться 8000000/50=160000 тиков максимум. Раз у нас 256 уровней напряжения, то и максимальное разрешение синусоиды будет равняться 256.
Что же такое разрешение синуса? В данном случае это количество точек за период по которым построена синусоида. Для примера я построил в Excel, то как будет выглядеть синусоида для разного разрешения.
Для синуса с разрешением 4:
Для синуса с разрешением 8 точек:
Для синуса с разрешением 16 точек:
Думаю «эволюция» синуса наглядно видна — чем больше точек(разрешение), тем меньше угловатостей и тем больше он похож на нормальную синусоиду. В итоге я решил остановиться на разрешении синуса в 128 точек.
Теперь объединяем все сказанное ранее, 160000 тиков делим на разрешение 128 получаем 1250 — через столько тиков должно сработать прерывание, чтобы выставить следующий уровень напряжения. Значение 1250 нужно пихать в регистр сравнения OCR1A
OCR1AH=0x04;
OCR1AL=0xE2;
Вторая часть глобальной задачи — как построить синусоиду. Вспомним математику :D… Синус изменяется от -1 до 1. ШИМом сгенерить отрицательное напряжение не получится. Поэтому нужно сместить график над осью Х — sin(x)+1. Теперь он будет изменяться от 0 до 2, тоже не вариант, т.к. у нас 256 значений напряжения, поэтому умножим на 127, чтобы максимальным было значение 256. В итоге откопал такую формулу:
128 — разрешение синуса, х — номер точки по (от 0 до 128). Сосчитал в Excel, получился массив sin[] из 128 значений, которые по очереди подставляются в OCR2.
Последнее о чем стоит упомянуть — фильтр низких частот, возможно в ближайшее время появится урок по фильтрам. В данный момент, формулы для его расчета не имеет смысла приводить, т.к. есть сайты с возможностью онлайн расчетов, достаточно набрать «фнч» в гугле.
Файл прошивки и протеуса
Здравствуйте admin on. Схему сразу же собрал, запустил начал пенять значения чтоб посмотреть что будет. С разрешением при замене ни чего не получилось. ICR1 менял по формуле тем самым повысил частоту аж до 32 кГц, но при этом пропала генерация на других ножках. Значение SET_FREQ = 410 тоже пересчитывал подставлял. сейчас значения которые ставил сказать не могу пишу с работы.
nikola56rus, не интересно это давать готовые решения. Все что я могу посоветовать, это взять код из моей статьи и разобраться, поверьте это не сложно, Вам всего навсего нужно менять 1 регистр. Или если уж так лень разбираться, напишите на каком нибудь соответствующем форуме, вам за денежку напишут все что захотите.
вы используете таймер 2, а он считает до 255 и обнуляется(в режиме фаст пвм), а нам надо 1250тиков, что то не клеится
и зачем записывать значение OCR1AH=0x04; OCR1AL=0xE2; ?
или я что то не понял?
чёто я вообще запутался в вашем коде, OCR2 это регистр сравнения второго таймера, а мы используем первый таймер
первый таймер вы вообще не настроили(до скольки он будет считать и тд)
и выход в протеусе используем от второго таймера…
ничё не пойму
1 таймер регулирует «ширину» сигнала, 2 «высоту»
всё, разобрался, тогда да, всё нормально, немного комментов к коду было бы очень кстати
спасибо за статьи
Отличные уроки, много полезного. Кстати значение синуса можно получить не только из массива но и подгрузив библиотеку math.h и к примеру цикл for
Так как все таки разделить Шим на два транзистора, чтобы получилась синусоида. Это программно же делается, подскажите идею как
Чтобы разделить ШИМ сигнал на 2 транзистора(по полуволне каждому) есть несколько вариантов:
1. Использовать МК с комплементарными выходами(это когда например регистр OCR1A имеет 2 выхода прямой и инверсный)
2.Использовать для этого драйвер ключей(либо 1 сигнал на 2 входа драйвера — один прямой второй инверсный либо драйвер с 1 входом и 2 выходами…там варантов куча смотрите IR2101…2110) либо обычную инверсную логику типа к561лн.
Смысл в том ,что когда на ножке 1 — включен ,например, верхний ключ когда 0 — нижний. Тогда при скважности 50%(127 при 8 битном шиме) средне приложеный потонциал к точке будет равен 0, соответственно при 255 — полностью открыт верхний при 0 — полностью нижний ключи.
Только не забывайте про необходимость генерации мертвого времени, инчае сквозной ток убьет ключи.
можно ли сделать искуственные 3ф я имею ввиду изменнение частоты с 0 до 50 гц запуская плавно 3ф асинхронный двигатель
что вы предложите мега 8 не подходит.может мега 168
может
Подскажите, почему в программе atmel studio не находит директорию ?
Ругается что такой нет…
подскажите где взять директорию ее нет в скаченном файле. можно у вас ее приобрести? спасибо.
Владимир, все исходники для Codevision.
подскажите в codevision нет библиотеки mega8.h. Где ее можно скачать?
Буду очень признателен за ссылку. Благодарю!!!
либа стандартная, если ее нет значит CAVR корявый
Изучаю ваши уроки, но все же пока новичок 🙁 . У меня сейчас задача стоит создать трехфазный генератор с возможностью регулировать частоту от 1 до 100 Гц. Сдвиг между фазами 120 градусов. Регулировка амплитуды от 0.1 до 10 вольт. Как это можно сделать ❓ Мега 8, как я понимаю, не подходит? Подскажите, как программно сдвигать сигнал один относительно другого? Буду очень признателен за подробный ответ или создания продолжение данного урока. Конечная задача крутить бесколлекторный двигатель.
гуглите апнот AVR447
скажите а каким образом можно управлять частотой допустим от нуля до 400гц.дайте намёк
как менять частоту от нуля до 80гц
дайте наводку а программу буду сам грызть.
у меня на этот счет есть отличный ответ: http://avr-start.ru/?p=4500 читаем вопрос№4 в конце
а вы действительно учител.СПАСИБО.
ОГРОМНОЕ СПАСИБО АВТОРУ!!!!! ДАВАЙТЕ БОЛЬШЕ УРОКОВ!!!
Какой вы молодец!!!Всё понятно.Спасибо!!!!
Добрый день! А как можно сделать 3х фазную синусоиду со сдвигом 120 градусов?
запускать таймер и от него подставлять отсчеты
а мне кажется нужно сделать ещё два масива
А частоту 20-30 кГц получить можно??
Интересная идея организации синусоидального сигнала и стабилизации частоты. Я бы сказал иначе — получение синусоидального сигнала стабильной частоты. Таймер 1 изменяет частоту, а таймер два рисует синусоиду.
з массива я создал .Как создать ещё два.Просто изменить формулу подставить 2p/3 + или -.А вот как управлять процессом.Или частотой вот в чём вопрос?
вопрос не понятен) в статье дана формула, как посчитать частоту, подставляете, пересчитываете
А если я не 256 точек выберу а 512 .Частота синуса изменится?
Нет. Частота не изменится. Изменится кол-во точек, которые используются для построения синусоиды частотой 50 Гц
Здравствуйте, нужно Формировать 12-разрядное треугольное (две пилы — вверх и вниз) напряжение частотой от 10 Гц до 1 кГц, управлять частотой с помощью потенциометра в Proteus на ATMEGA8
Как это сделать?
У меня есть схема, а когда нет
Схема изображена на фото: Файл можно получить по ссылке:
IMG20231122175726.jpg
https://disk.yandex.ru/i/TOK1ulYc8MVGIg
У меня вопрос возник.А на stm32 те же частоты таймера используются.?Заранее говорю спасибо.И если увеличить число точек что будет?