Формирование ШИМ сигналов на контактах GPIO микроконтроллера PIC


ШИМ сигналы играют важную роль во многих современных электронных проектах – начиная от регулировки яркости свечения светодиоды и заканчивая управление серводвигателем. В микроконтроллерах PIC ШИМ сигнал можно сформировать с помощью модуля захвата, сравнения и ШИМ (Compare, Capture and PWM, CCP) при помощи конфигурирования необходимых регистров и этот вопрос ранее мы уже рассматривали на нашем сайте в этой статье. Но у этого метода есть один существенный недостаток.

При этом способе формирование ШИМ сигналов возможно только на контактах RC1 и RC2 микроконтроллера PIC16F877A. Но что делать если нам необходимо большее число контактов с ШИМ сигналами. Например, для управления роботизированной рукой нам необходимо управлять 6 сервомоторами. В этих ситуациях использование модулей CCP будет бесполезным. Поэтому в данной статье мы рассмотрим формирование ШИМ сигналов на обычных контактах ввода/вывода (GPIO pins) микроконтроллера PIC с помощью модулей таймеров. В этом случае мы сможем сформировать так много ШИМ сигналов, сколько нам будет необходимо (разумеется, при ограничениях на число физических контактов микроконтроллера).

Внешний вид проекта формирования ШИМ сигналов на контактах GPIO микроконтроллера PIC

Конечно, проблему увеличения числа контактов для формирования ШИМ сигналов можно было бы решить с помощью специальных мультиплексирующих микросхем, но зачем вкладываться в дополнительное аппаратное обеспечение если те же самые задачи можно решить программными средствами? Поэтому в данной статье мы рассмотрим преобразование обычных контактов ввода/вывода (GPIO) микроконтроллера PIC в контакты для формирования ШИМ сигналов (PWM pin). Для тестирования работы нашего проекта мы будем использовать симулятор Proteus с цифровым осциллографом, также с помощью сформированного ШИМ сигнала мы будем управлять положением оси серводвигателя.

Что такое ШИМ сигнал

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

Внешний вид ШИМ сигнала при различных коэффициентах заполнения показан на следующих рисунке.

ШИМ с коэффициентом заполнения 50%

ШИМ с коэффициентом заполнения 10%

ШИМ с коэффициентом заполнения 90%

Важным параметром ШИМ сигнала является его коэффициент заполнения (скважность, в англ. - duty cycle). Коэффициент заполнения ШИМ сигнала представляет собой процент времени, в течение которого сигнал имеет высокий уровень (HIGH, ON). Если ШИМ сигнал всегда находится в состоянии HIGH, то его коэффициент заполнения равен 100%, а если ШИМ сигнал всегда находится в состоянии LOW, то его коэффициент заполнения равен 0%.

Расчет коэффициента заполнения для ШИМ сигнала

Для формирования ШИМ сигнала на обычном контакте ввода/вывода (GPIO) микроконтроллера нам необходимо всего лишь переключать его состояния с заданными длительностями. Но это не так просто как может показаться на первый взгляд. Для каждого цикла ШИМ сигнала длительность состояний включения и выключения должна быть очень точной и для ее определения нельзя использовать обычную функцию задержки. Поэтому для этой цели мы будем использовать модуль таймера и прерывания от таймера. Таким образом, в программе нам необходимо будет задавать коэффициент заполнения/скважность ШИМ сигнала и его частоту. Имена переменных в программе, которые будут использоваться для задания этих значений, приведены в следующей таблице.

Будем предполагать что частоту (frequency) ШИМ сигнала будет задавать пользователь. Тогда период ШИМ сигнала можно будет определить по формуле:

Когда пользователь будет изменять значение коэффициента заполнения (Duty cycle) наша программа автоматически должна рассчитывать значения T_ON и T_OFF. Время включения T_ON в этом случае можно определить по формуле:

Поскольку период ШИМ сигнала равен сумме времен включения и выключения, то время выключения можно T_OFF можно определить по следующей простой формуле:

Используя эти формулы мы можем приступить к написанию программы для микроконтроллера PIC. В программе будет использовать модуль таймера и модуль АЦП (аналого-цифрового преобразования). Если вы неуверенно чувствуете себя в этих вопросах, то рекомендуем ознакомиться со статьями про использование таймеров и АЦП в микроконтроллерах PIC.

Схема проекта

Схема для формирования ШИМ сигналов на контактах GPIO микроконтроллера PIC представлена на следующем рисунке.

Схема для формирования ШИМ сигналов на контактах GPIO микроконтроллера PICКак видите, схема очень проста, необходимо всего лишь подать питание на микроконтроллер PIC, подключить к нему внешний кварцевый генератор, подключить потенциометр к контакту AN0, а сервомотор – к контакту RD1 (его мы случайным образом выбрали для формирования ШИМ сигнала). И потенциометр, и сервомотор получают питание 5V с регулятора напряжения 7805.

Объяснение программы для микроконтроллера PIC

Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.

Первым делом в программе настроим биты конфигурации для микроконтроллера PIC.

Затем укажем тактовую частоту микроконтроллера – в нашем случае она равна 20 МГц. Далее укажем частоту ШИМ сигнала. Поскольку в нашем проекте мы будем управлять простеньким сервомотором, то в качестве значения данной частоты мы будем использовать 50 Гц (0,05 кГц).

Затем на основе значения частоты ШИМ сигнала рассчитаем его период T_TOTAL по формуле, приведенной выше. Здесь мы его будем делить на 10 чтобы получить значение периода в миллисекундах. В нашем случае значение периода T_TOTAL будет равно 2 миллисекундам.

Затем мы инициализируем АЦП – он нам будет необходим чтобы считывать значение с потенциометра. Более подробно про работу с АЦП в микроконтроллерах PIC вы можете прочитать в этой статье. Также нам будет необходима функция обработки прерывания от таймера, которая будет вызываться каждый раз при переполнении таймера.

Внутри основной функции программы main мы будем настраивать модуль таймера. В нашем проекте мы настроим его так чтобы он переполнялся каждые 0.1ms. Значение для этого, загружаемое в таймер, может быть рассчитано по следующей формуле:

В нашем случае для задержки 0.0001 секунды (0.1ms) с коэффициентом деления предделителя равным 64 и частоты Fosc равной 20 МГц значение нашего регистра TMR0 должно быть равно 248. Таким образом, последовательность команд для конфигурации таймера будет выглядеть следующим образом:

Затем нам необходимо задать режимы работы используемых контактов. В нашем проекте мы используем контакт AN0 для считывания значения с потенциометра с помощью АЦП и контакты порта PORTD для формирования ШИМ сигналов. Поэтому сконфигурируем их для работы на вывод данных и установим на них уровень low.

Далее внутри бесконечного цикла while нам необходимо рассчитать значение времени включения T_ON ШИМ сигнала, из которого можно будет определить коэффициент заполнения ШИМ сигнала. Значение времени включения T_ON и коэффициента заполнения ШИМ сигнала в нашем случае будет зависеть от положения ручки потенциометра, поэтому его мы будем непрерывно проверять в цикле. 0.0976 – это значение, на которое нужно умножить число 1024 чтобы получить число 100 – это нам необходимо чтобы рассчитать T_ON. Далее мы умножаем его на 10 чтобы получить результат в миллисекундах.

Поскольку таймер у нас конфигурируется чтобы переполняться каждые 0.1ms, то функция обработки прерывания от него (ISR) также будет вызываться каждые 0.1ms. Внутри данной функции мы будем инкрементировать переменную count каждые 0.1ms. Таким образом мы будем отслеживать прошедшее время. Более подробно о работе с прерываниями в микроконтроллерах PIC вы можете прочитать в этой статье.

И, наконец, нам необходимо будет переключать состояние контактов GPIO в зависимости от значений времени T_ON и T_OFF. У нас есть переменная count, в которой хранится значение времени в миллисекундах. Поэтому мы будем использовать эту переменную чтобы проверить меньше ли время времени включения T_ON, если меньше, то мы будем удерживать на контакте GPIO состояние high. Если нет, то на контакте GPIO мы будем устанавливать состояние low до тех пор пока не начнется новый период ШИМ сигнала.

Моделирование работы проекта

Для моделирования работы проекта мы использовали симулятор Proteus. Схема нашего проекта, нарисованная в данном симуляторе, представлена на следующем рисунке.

Схема нашего проекта в симуляторе Proteus

После того как нарисовали схему в симуляторе, загрузите в нее hex файл программы для микроконтроллера и запустите ее на выполнение. После этого на контакте RD1 вы должны увидеть сформированный ШИМ сигнал – значение его коэффициента заполнения будет зависеть от положения ручки потенциометра. На представленной ниже GIF картинке показано как изменяется ШИМ сигнал в зависимости от значения на выходе АЦП, которое, в свою очередь, зависит от положения ручки потенциометра.

Проверка работы проекта с помощью сервомотора

Собранная нами конструкция проекта показана на рисунке ниже. Основой для этой конструкции послужила собранная перфорированная плата из статьи про мигание светодиодом с помощью микроконтроллера PIC.

Внешний вид собранной конструкции нашего проекта

Загрузите программу в микроконтроллер. После этого вы, вращая ручку потенциометра, сможете управлять положением оси сервомотора. Более подробно работу проекта вы можете посмотреть на видео, приведенном в конце статьи.

Исходный код программы

Видео, демонстрирующее работу проекта

(Проголосуй первым!)
Загрузка...
1 355 просмотров

Комментарии

Формирование ШИМ сигналов на контактах GPIO микроконтроллера PIC — 2 комментария

    • Ну а какую ошибку выдает? Если в код программы закралась опечатка (к сожалению, такое бывает), то давайте попробуем ее найти

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

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