Когда мы подключаем датчики к микроконтроллеру, выход датчика во многих случаях является аналоговым по своей природе. Но микроконтроллер обрабатывает цифровые сигналы.
Следовательно, мы используем АЦП между датчиками и микроконтроллерами. Он преобразует аналоговый сигнал в цифровой и передает его микроконтроллеру.
Существует множество приложений ADC, таких как биометрические приложения, мониторинг окружающей среды, обнаружение утечки газа и т. д.
Рассмотрим работу АЦП PIC на примере микроконтроллера PIC18f4550.
- PIC18f4550 имеет встроенный 10-битный 13-канальный АЦП.
- 13-канальный АЦП в даташите обозначается как AN0-AN12. Это означает, что мы можем подключить 13 различных датчиков одновременно.
- 10-битный АЦП означает, что на выходе мы получим число в диапазоне от 0 до 1023 (210).


Для простоты понимания предположим, что Vref равно 5 В, значит
- Для 0В на выходе АЦП = 0.
- Для 5В на выходе АЦП = 1023 (10 бит).
- Для 2,5В на выходе АЦП = 512 (10 бит).
Регистры АЦП для PIC18F4550
Регистры ADRESH и ADRESL
Регистры ADRESH (старший байт) и ADRESL (младший байт) используются в комбинации для хранения преобразованных данных, т. е. цифровых данных. Но данные имеют ширину всего 10 бит, поэтому оставшиеся шесть битов не используются.
ADCON0: регистр аналого-цифрового управления 0

CHS3:CHS0: Биты выбора аналогового канала
| CHS3:CHS0 | Каналы (Channels) | Имя канала (Channel Name) |
|---|---|---|
| 0000 | Channel 0 | AN0 |
| 0001 | Channel 1 | AN1 |
| 0010 | Channel 2 | AN2 |
| 0011 | Channel 3 | AN3 |
| 0100 | Channel 4 | AN4 |
| 0101 | Channel 5 | AN5 |
| 0110 | Channel 6 | AN6 |
| 0111 | Channel 7 | AN7 |
| 1000 | Channel 8 | AN8 |
| 1001 | Channel 9 | AN9 |
| 1010 | Channel 10 | AN10 |
| 1011 | Channel 11 | AN11 |
| 1100 | Channel 12 | AN12 |
GO/DONE: Бит состояния аналого-цифрового преобразования
Когда ADON = 1
1 = выполняется аналого-цифровое преобразование.
0 = АЦП не используется
ADON: Бит разрешения/включения аналого-цифрового преобразования
1 = аналого-цифровое преобразование включено (начало преобразования).
0 = аналого-цифровое преобразование отключено.
ADCON1: регистр аналого-цифрового управления 1

VCFG1: Бит конфигурации опорного напряжения
1 = Vref –
0 = Vcc
VCFG0: Бит конфигурации опорного напряжения
1 = Vref +
0 = Vdd
ADCON2: регистр аналого-цифрового управления 2

ADCS2:ADCS0: Биты выбора аналого-цифрового преобразования тактового сигнала:
Эти биты используются для назначения часов АЦП.
111 = тактовый сигнал FRC, полученный из аналого-цифрового RC-генератора.
110 = FOSC/64
101 = FOSC/16
100 = FOSC/4
011 = тактовая частота FRC, полученная из аналого-цифрового RC-генератора.
010 = FOSC/32
001 = FOSC/8
000 = FOSC/2
ADFM: бит выбора формата результата преобразования:
10-битный результат будет помещен в ADRESH (8-бит) и ADRESL (8-бит).
Рассмотрим 10-битные данные следующим образом:

1 = Результат преобразования выравнивается по правому краю. Однако младшие 8 бит сохраняются в ADRESL, а оставшиеся два бита со стороны MSB сохраняются в ADRESH. 6 бит (биты 2-7) ADRESH заполнены нулями.

0 = Результат преобразования выравнивается по левому краю. Однако старшие 8 битов сохраняются в ADRESH, а оставшиеся два младших бита помещаются в ADRESL в позиции битов 7-6. 6 младших бит ADRESL заполнены нулями.

ACQT2:ACQT0: Биты выбора времени сбора данных АЦП:
Пользователь может запрограммировать время в течении которого будет производится сбор данных.
Ниже приведено минимальное время ожидания перед началом следующего сбора данных.
TAD = (время сбора аналого-цифрового сигнала)
- 000 = 0 TAD. Время сбора данных по умолчанию для аналого-цифрового преобразования.
- 001 = 2 TAD
- 010 = 4 TAD
- 011 = 6 TAD
- 100 = 8 TAD
- 101 = 12 TAD
- 110 = 16 TAD
- 111 = 20 TAD
Шаги для программирования
Инициализация
- Настройте регистр ADCON1 для выбора опорного напряжения с помощью битов VCFG1: VCFG0, а также настройте выводы порта, которые нам нужны в качестве аналогового входа, с помощью битов PCFG3: PCFG0.
- Настройте регистр ADCON2, чтобы выбрать формат результата АЦП, часы и время сбора данных.
void ADC_Init()
{
TRISA = 0xFF; /* Установка порта на вход */
ADCON1 = 0x0E; /* настраиваем Ref как Vdd и устанавливаем вывод, как аналоговый */
ADCON2 = 0x92; /* 4Tad и Fosc/32. */
ADRESH=0; /* очищаем входной регистр */
ADRESL=0;
}
Аналого-цифровое преобразование и чтение цифровых значений
- Настройте регистр ADCON0, чтобы выбрать канал, который нам нужен, используя CHS3: CHS0.
- Запустите аналого-цифровое преобразование, установив бит ADON и бит GO/DONE в регистре ADCON0.
- Дождитесь бита GO/DONE, который сбрасывается после завершения преобразования.
- Затем скопируйте цифровые данные, которые хранятся в регистрах ADRESH и ADRESL.
int ADC_Read(int channel)
{
int digital;
/* Выбираем 0 канал(CHS3CHS2CHS1CHS0=0000) & ADC отключен */
ADCON0 =(ADCON0 & 0b11000011)|((channel<<2) & 0b00111100);
ADCON0 |= ((1<<ADON)|(1<<GO)); /*Включаем ADC и стартуем преобразование*/
/* ждем пока Go/done = 0 не завершится преобразование */
while(ADCON0bits.GO_nDONE==1);
digital = (ADRESH*256) | (ADRESL); /*соединяем старший и младший байты преобразования*/
return(digital);
}
Полный код проекта можно скачать по ссылке.
Пример кода чтения АЦП PIC
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <P18F4550.h>
#include "config_intosc.h" /* Заголовочный файл для конфигурации битов */
#include "LCD_8bit_file.h" /* Заголовочный файл для нработы с LCD */
void ADC_Init();
int ADC_Read(int);
#define vref 5.00 /* Опорное напряжение 5V*/
void main()
{
char data[10];
int digital;
float voltage;
OSCCON=0x72; /*Внутрений генератор на 8Мгц*/
LCD_Init(); /*Инициализация16x2 LCD*/
ADC_Init(); /*Инициализация 10-bit ADC*/
LCD_String_xy(1,1,"Voltage is...");
while(1)
{
digital=ADC_Read(0);
/*переводим цифровой код в аналоговое напряжение*/
voltage= digital*((float)vref/(float)1023);
/*переводим число в строку для вывода на экран*/
sprintf(data,"%.2f",voltage);
strcat(data," V");
LCD_String_xy(2,4,data);
}
}
void ADC_Init()
{
TRISA = 0xff;
ADCON1 = 0x0e;
ADCON2 = 0x92;
ADRESH=0;
ADRESL=0;
}
int ADC_Read(int channel)
{
int digital;
ADCON0 =(ADCON0 & 0b11000011)|((channel<<2) & 0b00111100);
ADCON0 |= ((1<<ADON)|(1<<GO));
while(ADCON0bits.GO_nDONE==1);
digital = (ADRESH*256) | (ADRESL);
return(digital);
}
Загрузки
Где купить
- PIC18F4550 DIP-40
- LCD 1602
- Набор подстроечных резисторов






