PIC Урок 25. Модуль ADC (АЦП). Измеряем напряжение. Часть 2



В предыдущей части занятия мы познакомились с АЦП, с тем, как он реализован в контроллере PIC16 и подключили схему урока.

Проект соберём из проекта урока 21 по работе с переходником I2c-LCD с именем I2C_LCD80 и назовём его ADC.

Откроем проект в среде MPLAB X, сделаем его главным, убедимся в свойствах, что питание от программатора не используется.

В файле i2c.c изменим тип возвращаемого значения у следующей функции, иначе обновлённая IDE ругается на тип bit

void I2C_Write_Byte(unsigned char Byte)

Также в теле данной функции уберём возврат результата

return ACKSTAT;

В файле main.c подключим библиотеку для работы со строковыми функциями, а также добавим функцию задержки, которая нам нужна будет вначале для того, чтобы модуль ADC успел инициализироваться

 

В функции main удалим переменную и инициализацию порта B, так как мы с ним не работаем

int i;
TRISB = 0x00;
PORTB = 0xFF;

А вот в инициализации порта A исправим направление нулевой ножки

TRISA = 0x01;

Начнём писать настройку модуля АЦП.

Применим выравнивание по правому краю, вход включим AN0, а источник опорного напряжения — Vdd

 

Настроим частоту тактирования шины АЦП — Fosc/8

 

И включим АЦП

 

 

Удалим тестовый код от LCD_Init(); до LCD_Clear();, а также весь код из бесконечного цикла.

После очистки дисплея перед началом бесконечного цикла немного подождём, применив нашу функцию задержки

 

Данная задержка вполне достаточна для инициализации АЦП, а также для заряда конденсатора.

В бесконечном цикле дадим команду на старт АЦП

 

Дождёмся окончания преобразования с помощью отслеживания перехода в низкое состояния бита GO

 

Дальнейшая наша задача — считать байты со значением измеренного напряжения, преобразовать их в величину напряжения и показать на экране дисплея.

Для этого сначала добавим в начале функции main() две локальные переменные

 

 

В бесконечном цикле считаем регистры с преобразованным значением напряжения и запишем их в первую переменную

 

С помощью мультиметра измерим напряжение на крайних ножках резистора — это и будет наше опорное напряжение. У меня получилось 5.06 вольт.

Вернём курсор дисплея на исходную позицию — в верхний левый угол, и затем посчитаем наше напряжение, используя нехитрую формулу

 

Отобразим значение на дисплее и немного подождём до следующего цикла измерения

 

Соберём код, прошьём контроллер и посмотрим результат нашей работы, вращая регулятор на переменном резисторе и отслеживая результат на дисплее

Всё отлично измеряется. Хотя показания иногда подёргиваются, но мы же не писали никаких фильтров, да это и не входит в наши планы.

Попробуем теперь измерить напряжение одновременно на двух входах. Для этого нам надо будет первым делом на нашу макетную плату поместить ещё один такой же переменный резистор, крайние ножки которого мы соединим с соответствующими ножками первого резистора, а центральный вывод второго резистора мы соединим с входом контроллера AN1

 

 

В функции main() включим на вход данную ножку

 

TRISA = 0x03;

 

Немного изменим конфигурацию битов, отвечающих за ножки и опорное напряжение, регистра ADCON1

 

//AN0,AN1,AN3 analog, Vref+ = Vdd, Vref- = Vss

PCFG3 = 0;

PCFG2 = 1;

PCFG1 = 0;

PCFG0 = 0;

 

Канал пока никакой не выбираем, по умолчанию, когда все биты CHS2:CHS0 в нуле, получается AN0.

Для того, чтобы контроллер знал, какой в данный момент текущий канал, добавим локальную переменную

 

 

В бесконечном цикле после того, как аппаратно сбросится флаг GO, добавим небольшую задержку, которая, как выяснилось в одном из форумов, снижает влияние измеренных величин в разных каналов друг на друга, хотя в документации этого нет

 

 

Пока уберём установку позиции курсора дисплея

 

LCD_SetPos(0,0);

 

После преобразования результата в значение в вольтах с плавающей точкой узнаем, какой у нас канал, и установим курсор в нужное место, переключим канал c помощью установки или сброса бита CHS0, а затем переключим также значение переменной, хранящей текущей номер канала, значение которой будет использоваться в следующем цикле измерения

 

 

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

 

 

Таким образом, в данном занятии мы познакомились с ещё одной очень важной периферией — модулем АЦП (ADC), который позволяет нам измерять напряжение на входах контроллера и затем использовать его по нашему назначению, например как в нашем занятии, в котором мы создали простой, но вполне неплохо функционирующий вольтметр на два входа.

Всем спасибо за внимание!

 

 

Предыдущая часть Программирование МК PIC Следующий урок

 

Исходный код

 

 

Купить программатор (неоригинальный) можно здесь: PICKit3

Купить программатор (оригинальный) можно здесь: PICKit3 original

Отладочную плату PIC Open18F4520-16F877A можно приобрести здесь: PIC Open18F4520-16F877A

Дисплей LCD 20×4 можно приобрести тут: Дисплей LCD 20×4

Переходник I2C to LCD можно приобрести здесьI2C to LCD1602 2004

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

PIC Модуль ADC (АЦП). Измеряем напряжение

3 комментария на “PIC Урок 25. Модуль ADC (АЦП). Измеряем напряжение. Часть 2
  1. Сергей:

    Спасибо за урок. Сделал контроллер разряда двух литий полимерных батарей.
    выглядит так https://disk.yandex.ru/i/uBcPjr4BFRZHWg

  2. Сергей:

    Плохо, что у вас на сайте картинки пользователи выкладывать не могут.

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

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

*