Извращенский ШИМ из UART

Пока писал статью про UART пришла в голову одна извращенная идея — на базе UART же можно организовать самый натуральный низкодискретный ШИМ!

Достаточно только сделать где-нибудь в памяти переменную, куда мы будем совать число с заданной скважностью нулей и единиц, а по прерыванию опустошения буфера это число снова пихать в регистр UDRE. Таким образом, генерация ШИМ будет самопроизвольной, без лишних телодвижений. Правда можно получить всего 10 разных значений ШИМ, но зато нахаляву!!!

Для тех кто не понял как, приведу числа которые надо будет непрерывно слать через UART:
два дополнительных значения мы получим за счет старт и стоп битов.

00000000 — 1/10
00000001 — 2/10
00000011 — 3/10
00000111 — 4/10
00001111 — 5/10
00011111 — 6/10
00111111 — 7/10
01111111 — 8/10
11111111 — 9/10

Да и частоты там можно получить нефиговые!
Красота!=)))))

24 thoughts on “Извращенский ШИМ из UART”

        1. На gaw.ru есть русская версия этого документа. Рекомендую к прочтению тем, кто хочет поработать с 1-wire; там расписаны основные сигналы, и их временнЫе диаграммы.

    1. Конкретно этот, или вообще ШИМ? Этим можно движок крутить, например. 10 градаций скорости хватит за глаза обычно :)

    1. Как это какой?

      Получить нахаляву ШИМ не используя программные методы генерации.

      Тебе еще не приходилось забивать под завязку контроллер, когда начинаешь считать байты и выкидывать все лишнее? А у меня два раза такое было, когда память уже закончилась, а нужные фичи еще не реализованы. В итоге приходилось выкидывать все что можно и нельзя, сокращать текстовые строки и извращаться как только можно. В результате в 16кб прошивке, написанной на асме и заоптимизированной как тока можно, осталось свободными всего 14 байт.

      1. Дык в АВРках можно аппаратно реализовать ШИМ через таймер, генерируя его на OC1A/OC1B ногах. И проще этого способа явно никакого нет, экономия памяти как раз будет больше, да и UART всё таки чаще нужен, чем OC1 ноги. Или ты не знал?

        1. Ок, ну начнем с того, что на AVR свет клином не сошелся, и например в моем горяче любимом АТ89С51 нельзя сделать аппаратный ШИМ на таймере. Там из периферии есть только UART и порты. Все :) Во вторых иногда нужен не один шим, а дохера — мне как то раз потребовалось 15 каналов. Для управления многофазным двигателем. И когда у тебя кончаются ШИМы на таймерах можно, экономя программные ресурсы, сделать его еще и на UART. Иногда выводы ШИМ от таймеров оказываются заняты (например на них висит SPI память), или таймеры нужно пустить на что либо более нужное, скажем на подсчет частоты. Или просто разводку платы проще сделать так, что можно ШИМ вывести с УАРТа (если конечно качества этого ШИМ хватит). Короче, вариантов множество.

          Ты просто не сталкивался еще с такими задачами когда один МК делает сразу же дохера всего да еще с критичной ко времени выполнения скоростью.

  1. Тогда уж вывести ШИМ еще и через SPI, аналогично. :)))
    Частота будет максимально: такт/2/8.
    Вот только для вывода каждого байта заваливаться в прерывание… Или через каждые 16 тактов выводить очередной байт.
    С UART тоже придется делать что-то подобное.

    ИМХО — ерунда все это, если только побаловаться… Вместо того, чтобы выкручиваться и изголяться, дешевле (для нервов) железо под задачу подобрать нормально. :)

    1. Прерывания можно похерить. А по поводу побаловаться и железо под задачу… Есть такая вещь как стоимость. Порой цена на нужную железку превышает вдвое, а то и втрое. Когда один девайс то пофигу, а вот когда серийное производство? Я делаю мелкосерийку, максимум 50шт в месяц и то зажимаю каждую копейку.

  2. Да, действительно извращенческая идея! Но мне очень понравилась! Вообще, 10 градаций не предел — можно чередовать байты: 0x0f — 0x07 — 0x0f — 0x07 например будет давать что-то среднее…

        1. А можно и не 0x0F 0x7, а 0xB 0xC (в сумме тоже, но более равномерно). У меня один раз былов ТЗ 16 битный ШИП, еле обьяснил что такую точность невозможно достигнуть за адекватное время. Если за одно переполнение таймера конденсатор успеет раз/зарядится более чем на 1/2^16 напряжения — то это уже не 16 бит точности, а пила. А если он за то время не успевает, то наполный за/разряд будет уходить уйма времени и с такой латенсией никому не нужно.
          А вот если так делать или программно то можно, по крайней мере очень сильно пилу сгладить, правда реализовать — та еще забава. (Проще микросхему купить что и было сделано)

  3. Посоветуйте пожалуйста:
    У меня задействовано 9 ШИМ выходов, занято 3 таймера, больше нету, но мне нужно отсчитывать временные интервалы и так, что бы проц мог заниматься своими делами, что можно сделать в таком случае?

    1. Если частота ШИМ не меняется, то можно один из таймеров ШИМ параллельно задействовать как отсчетный таймер. Либо на лету пересчитывать его коэффициенты, чтобы отсчеты не плавали.

  4. А еще в этой идее наверно возможна простейшая реализация подачи сигналов на драйвер шагового двигателя если передавать 01010101 причем легко и точно можно выставить скорость. только вот не так много УАРТов

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

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

Перед отправкой формы:
Human test by Not Captcha