- АЦП в PIC микроконтроллере PIC16F877A:
- Программирование для АЦП:
- Настройка и тестирование оборудования:
Это наш 9-й учебник по изучению микроконтроллеров PIC с использованием MPLAB и XC8. До сих пор мы рассмотрели множество базовых руководств, таких как начало работы с MPLABX, мигание светодиода с PIC, таймеры в PIC, сопряжение с ЖК-дисплеем, сопряжение с 7-сегментным интерфейсом и т. Д. Если вы абсолютный новичок, посетите полный список руководств по PIC здесь и начни учиться.
В этом руководстве мы узнаем, как использовать АЦП с нашим микроконтроллером PIC PICF877A.. Большинство проектов микроконтроллеров будут включать в себя АЦП (аналого-цифровой преобразователь), потому что это один из наиболее часто используемых способов чтения данных из реального мира. Почти все датчики, такие как датчик температуры, датчик потока, датчик давления, датчики тока, датчики напряжения, гироскопы, акселерометры, датчик расстояния, и почти каждый известный датчик или преобразователь вырабатывает аналоговое напряжение от 0 В до 5 В на основе показаний датчиков. Датчик температуры, например, может выдавать 2,1 В при температуре 25 ° C и повышаться до 4,7 при температуре 60 ° C. Чтобы узнать температуру в реальном мире, микроконтроллер должен просто прочитать выходное напряжение этого датчика температуры и связать его с реальной температурой. Следовательно, ADC является важным рабочим инструментом для проектов MCU и позволяет узнать, как мы можем использовать его на нашем PIC16F877A.
Также проверьте наши предыдущие статьи об использовании ADC в других микроконтроллерах:
- Как использовать АЦП в Arduino Uno?
- Учебник Raspberry Pi ADC
- Взаимодействие ADC0808 с микроконтроллером 8051
АЦП в PIC микроконтроллере PIC16F877A:
Доступно множество типов АЦП, каждый из которых имеет свою скорость и разрешение. Наиболее распространенными типами АЦП являются флэш-память, последовательное приближение и сигма-дельта. Тип АЦП используется в PIC16F877A называется как АЦП последовательного приближения или SAR короче. Итак, давайте узнаем немного о АЦП SAR, прежде чем мы начнем его использовать.
АЦП последовательного приближения: АЦП последовательного приближения работает с помощью компаратора и некоторых логических схем. Этот тип АЦПА использует опорное напряжение (которое является переменным) и сравнивает входное напряжение с опорным напряжением с помощью компаратора и разности, который будет цифровым выходом, сохраняются от самого старшего бита (MSB). Скорость сравнения зависит от тактовой частоты (Fosc), на которой работает PIC.
Теперь, когда мы знаем некоторые основы АЦП, давайте откроем нашу таблицу и узнаем, как использовать АЦП на нашем микроконтроллере PIC16F877A. Используемый нами PIC имеет 10-битный 8-канальный АЦП. Это означает, что выходное значение нашего АЦП будет 0-1024 (2 ^ 10), и на нашем MCU есть 8 контактов (каналов), которые могут считывать аналоговое напряжение. Значение 1024 получается как 2 ^ 10, так как наш АЦП 10-битный. Восемь контактов, которые могут считывать аналоговое напряжение, указаны в таблице данных. Давайте посмотрим на картинку ниже.
Аналоговые каналы от AN0 до AN7 выделены для вас. Только эти контакты смогут считывать аналоговое напряжение. Поэтому перед считыванием входного напряжения мы должны указать в нашем коде, какой канал должен использоваться для чтения входного напряжения. В этом руководстве мы будем использовать канал 4 с потенциометром для считывания аналогового напряжения на этом канале.
Модуль A / D имеет четыре регистра, которые необходимо настроить для чтения данных с входных контактов. Эти регистры:
• Регистр высокого уровня результата A / D (ADRESH)
• Нижний регистр результата A / D (ADRESL)
• Регистр управления аналого-цифровым преобразователем 0 (ADCON0)
• Регистр A / D управления 1 (ADCON1)
Программирование для АЦП:
Программа для использования АЦП с PIC микроконтроллером очень проста, мы просто должны понять эти четыре регистра, а затем читает любое аналоговое напряжение будет простым. Как обычно, инициализируйте биты конфигурации и начнем с void main ().
Внутри void main () мы должны инициализировать наш АЦП, используя регистры ADCON1 и ADCON0. Регистр ADCON0 имеет следующие биты:
В этом регистре мы должны включить модуль АЦП, установив ADON = 1, и включить часы аналого-цифрового преобразования, используя биты ADCS1 и ADCS0, остальные пока не устанавливаются. В нашей программе частота аналогово-цифрового преобразования выбрана как Fosc / 16, вы можете попробовать свои собственные частоты и посмотреть, как изменится результат. Полная информация доступна на странице 127 таблицы данных. Следовательно, ADCON0 будет инициализирован следующим образом.
ADCON0 = 0b01000001;
Теперь регистр ADCON1 имеет следующие биты:
В этом регистре мы должны установить бит выбора формата результата аналого-цифрового преобразования в высокий уровень с помощью ADFM = 1 и сделать ADCS2 = 1, чтобы снова выбрать Fosc / 16. Остальные биты остаются нулю, как мы планировали использовать внутренний источник опорного напряжения. Полная информация доступна на странице 128. Следовательно, ADCON1 мы установим следующим образом.
ADCON1 = 0x11000000;
Теперь, после инициализации модуля ADC внутри нашей основной функции, давайте войдем в цикл while и начнем чтение значений ADC. Чтобы прочитать значение АЦП, необходимо выполнить следующие шаги.
- Инициализируйте модуль ADC
- Выберите аналоговый канал
- Запустите АЦП, установив бит Go / Done в высокий уровень
- Подождите, пока бит Go / DONE опустится
- Получите результат АЦП из регистра ADRESH и ADRESL
1. Инициализируйте модуль ADC: мы уже узнали, как инициализировать ADC, поэтому мы просто вызываем эту функцию ниже для инициализации ADC.
Функция void ADC_Initialize () выглядит следующим образом.
void ADC_Initialize () {ADCON0 = 0b01000001; // ADC ON и выбран Fosc / 16 ADCON1 = 0b11000000; // Внутреннее опорное напряжение выбрано}
2. Выберите аналоговый канал: Теперь нам нужно выбрать, какой канал мы собираемся использовать для чтения значения АЦП. Позволяет создать функцию для этого, так что это будет легко для нас, чтобы переключаться между каждым каналом внутри в то время цикла.
unsigned int ADC_Read (unsigned char channel) {// **** Выбор канала ** /// ADCON0 & = 0x11000101; // Очистка битов выбора канала ADCON0 - = channel << 3; // Установка необходимых битов // ** Выбор канала завершен *** ///}
Затем канал, который нужно выбрать, принимается внутри переменного канала. В линии
ADCON0 & = 0x1100101;
Предыдущий выбор канала (если таковой был) очищен. Это делается с помощью побитового оператора «&». Биты 3, 4 и 5 принудительно устанавливаются равными 0, в то время как остальные остаются в своих предыдущих значениях.
Затем желаемый канал выбирается путем трехкратного сдвига номера канала влево и установки битов с помощью побитового оператора или оператора «-».
ADCON0 - = канал << 3; // Установка необходимых битов
3. Запустите АЦП, установив бит Go / Done в высокий уровень: После выбора канала мы должны запустить преобразование АЦП, просто установив бит GO_nDONE в высокий уровень:
GO_nDONE = 1; // Инициализирует аналого-цифровое преобразование
4. Подождите, пока бит Go / DONE не станет низким: бит GO / DONE будет оставаться на высоком уровне до тех пор, пока преобразование АЦП не будет завершено, поэтому мы должны подождать, пока этот бит снова не станет низким. Это может быть сделано с помощью то время как цикл.
пока (GO_nDONE); // Ждем завершения аналого-цифрового преобразования
5. Получите результат АЦП из регистров ADRESH и ADRESL: когда бит Go / DONE снова становится низким, это означает, что преобразование АЦП завершено. Результатом АЦП будет 10-битное значение. Поскольку наш MCU является 8-битным MCU, результат делится на старшие 8 бит и младшие 2 бита. Старшие 8-битные результаты сохраняются в регистре ADRESH, а младшие 2-битные хранятся в регистре ADRESL. Следовательно, мы должны добавить их в регистры, чтобы получить значение нашего 10-битного АЦП. Этот результат возвращается функцией, как показано ниже:
return ((ADRESH << 8) + ADRESL); // Возвращает результат
Полная функция, которая используется для выбора канала АЦП, запуска АЦП и возврата результата, показана здесь.
unsigned int ADC_Read (канал символов без знака) {ADCON0 & = 0x11000101; // Очистка битов выбора канала ADCON0 - = channel << 3; // Установка необходимых битов __delay_ms (2); // Время получения заряда запоминающего конденсатора GO_nDONE = 1; // Инициализирует аналого-цифровое преобразование while (GO_nDONE); // Дождитесь завершения аналого-цифрового преобразования return ((ADRESH << 8) + ADRESL); // Возвращает результат}
Теперь у нас есть функция, которая принимает выбор канала в качестве входных данных и возвращает нам значение АЦП. Следовательно, мы можем непосредственно вызывать эту функцию внутри нашего в то время цикла, так как мы здесь аналоговое напряжение от канала 4 в этом руководстве, вызов функции будет выглядеть следующим образом.
я = (ADC_Read (4)); // сохраняем результат adc в «i».
Чтобы визуализировать вывод нашего АЦП, нам понадобятся какие-то модули дисплея, такие как ЖК-дисплей или 7-сегментный. В этом руководстве мы используем 7-сегментный дисплей для проверки вывода. Если вы хотите узнать, как использовать 7-сегментный с рисунком, следуйте инструкциям здесь.
Полный код приведен ниже, и процесс также объясняется в видео в конце.
Настройка и тестирование оборудования:
Как обычно, моделируйте код с помощью Proteus перед тем, как использовать наше оборудование, схема проекта показана ниже:
Соединения 4-значного семисегментного модуля дисплея с микроконтроллером PIC такие же, как и в предыдущем проекте, мы только что добавили потенциометр к контакту 7, который является аналоговым каналом 4. При изменении потенциометра на MCU будет отправляться переменное напряжение. который будет считываться модулем ADC и отображаться на модуле 7-сегментного дисплея. Посмотрите предыдущее руководство, чтобы узнать больше о 4-значном 7-сегментном дисплее и его взаимодействии с PIC MCU.
Здесь мы использовали ту же плату микроконтроллера PIC, которую мы создали в учебнике по миганию светодиодов. После проверки соединения загрузите программу в PIC, и вы должны увидеть такой вывод
Здесь мы считали значение АЦП из потенциометра и преобразовали его в фактическое напряжение, сопоставив выход 0-1024 как 0-5 вольт (как показано в программе). Затем значение отображается на 7-сегментном сегменте и проверяется с помощью мультиметра.
Вот и все, теперь мы готовы использовать все аналоговые датчики, доступные на рынке, попробуйте это, и если у вас возникнут какие-либо проблемы, как обычно, используйте раздел комментариев, мы будем рады помочь вам.