

EOC0 |
|
0 |
|
0 |
Указывает, что преобразование по соответствующему |
|
|
|
|
|
каналу завершено. Соответствующий разряд сбрасывается |
EOC1 |
|
1 |
|
1 |
|
|
|
при чтении регистра ADC_CDRx. |
|||
|
|
|
|
|
|
EOC... |
|
... |
|
... |
|
|
|
|
|||
|
|
|
|
|
|
EOC7 |
|
7 |
|
7 |
|
|
|
|
|
|
|
OVRE0 |
|
8 |
|
0 |
Установленный бит указывает, что по соответствующему |
|
|
|
|
|
каналу было выполнено более одного преобразования с |
OVRE1 |
|
9 |
|
1 |
|
|
|
момента последнего прочтения регистра ADC_SR. Чтение |
|||
|
|
|
|
|
|
OVRE... |
|
... |
|
... |
|
|
|
данного регистра сбрасывает данные разряды. |
|||
OVRE7 |
|
15 |
|
7 |
|
|
|
|
|
|
|
DRDY |
|
16 |
|
|
Установленный бит указывает на то, что ранее было |
|
|
|
|
|
выполнено преобразование по одному из каналов и |
|
|
|
|
|
результат последнего аналого-цифрового преобразования |
|
|
|
|
|
сформирован в регистре ADC_LCDR. |
GOVRE |
|
17 |
|
|
Указывает, было выполнено более одного преобразования с |
|
|
|
|
|
момента последнего прочтения регистра ADC_SR. Данный |
|
|
|
|
|
бит автоматически сбрасывается после прочтения регистра |
|
|
|
|
|
ADC_SR. |
|
|
|
|
|
Таблица 7 |
|
|
|
|
|
ADC_LCDR |
|
|
|
|||
Символиче- |
Номер |
Описание |
|||
ское имя |
разряда |
|
|
||
LDATA |
0-9 |
|
Содержит результат последнего преобразования. При |
||
|
|
|
|
использовании 8-разрядного преобразования разряды 8 и 9 всегда |
|
|
|
|
|
сброшены. |
|
|
|
|
|
|
Таблица 8 |
|
|
|
|
|
ADC_CDRx (x= 0...7) |
|
|
|
|||
Символиче- |
Номер |
Описание |
|||
ское имя |
разряда |
|
|
||
DATA |
0-9 |
|
Содержит результат преобразования по каналу x. При |
||
|
|
|
|
использовании 8-разрядного преобразования разряды 8 и 9 всегда |
|
|
|
|
|
сброшены. |
|
|
|
|
|
В данный регистр канала x попадает результат преобразования |
|
|
|
|
|
только, если канал x был включён. |
Программный интерфейс для работы с АЦП на языке Си
Работа с регистрами АЦП на языке Си осуществляется с использованием структуры данных AT91S_ADC, объявленной в заголовочном файле AT91SAM7S64.h. Как видно из листинга 1, для данной структуры также объявлен тип указателя на неё (AT91PS_ADC).
Листинг 1. Фрагмент структуры AT91S_ADC, предназначенной для работы с АЦП
typedef struct _AT91S_ADC { |
ADC_CR; |
// ADC Control Register |
volatile unsigned int |
5

volatile unsigned int |
ADC_MR; |
// ADC Mode Register |
|
volatile unsigned int |
Reserved0[2]; |
// Неиспользуемая область |
|
volatile unsigned int |
ADC_CHER; |
// ADC Channel Enable Register |
|
volatile unsigned int |
ADC_CHDR; |
// ADC Channel Disable Register |
|
volatile unsigned int |
ADC_CHSR; |
// ADC Channel Status Register |
|
volatile unsigned int |
ADC_SR; |
// ADC Status Register |
|
volatile unsigned int |
ADC_LCDR; |
// ADC Last Converted Data Register |
|
volatile unsigned int |
ADC_IER; |
// ADC Interrupt Enable Register |
|
volatile unsigned int |
ADC_IDR; |
// ADC Interrupt Disable Register |
|
volatile unsigned int |
ADC_IMR; |
// ADC Interrupt Mask Register |
|
volatile unsigned int |
ADC_CDR0; |
// ADC Channel Data Register 0 |
|
volatile unsigned int |
ADC_CDR1; |
// ADC Channel Data Register 1 |
|
volatile unsigned int |
ADC_CDR2; |
// ADC Channel Data Register 2 |
|
volatile unsigned int |
ADC_CDR3; |
// ADC Channel Data Register 3 |
|
volatile unsigned int |
ADC_CDR4; |
// ADC Channel Data Register 4 |
|
volatile unsigned int |
ADC_CDR5; |
// ADC Channel Data Register 5 |
|
volatile unsigned int |
ADC_CDR6; |
// ADC Channel Data Register 6 |
|
volatile unsigned int |
ADC_CDR7; |
// ADC Channel Data Register 7 |
|
.... |
|
|
|
} AT91S_ADC, *AT91PS_ADC;
Для того, чтобы работать с АЦП с использованием данной структуры необходимо создать указатель на неё, и проинициализировать его адресом, начиная с которого в памяти располагаются регистры для работы с АЦП. В качестве этого адреса обычно используется макроопределение AT91C_BASE_ADC хранящее адрес 0xFFFD8000.
//Создать переменную типа 'указатель на структуру данных AT91S_ADC'
//и присвоить ей начальное значение AT91C_BASE_ADC
AT91PS_ADC adc = AT91C_BASE_ADC;
После этого доступ к регистрам АЦП осуществляется путём обращения к членам данной структуры через указатель на неё. Например:
// Запуск преобразования adc->ADC_CR = AT91C_ADC_START;
Для повышения удобства работы с АЦП и улучшения читаемости исходного кода в заголовочном файле также определены макроопределения, содержащие битовые маски и различные константы, предназначенные для формирования значений, пересылаемых в регистры АЦП. Данные макроопределения начинаются с префикса «AT91C_ADC_» и представлены в таблице 9.
Различные константы, заданные в макроопределениях, допускается комбинировать путём применения операции побитового логического «ИЛИ» (оператор «|» в Си) для формирования значений, пересылаемых в регистры АЦП. Для проверки значений конкретных битов (например, бита готовности результата преобразования по каналу) применяется побитовая логическая операция «И» (оператор «&»).
Листинг 2. Настройка, запуск АЦП, ожидание готовности и получение результата
//Настроить АЦП на использование 8-битного режима, нормальный (не спящий)
//режим работы; PRESCAL=0x63, SHTIM = 0x07
adc->ADC_MR = AT91C_ADC_LOWRES_8_BIT | AT91C_ADC_SLEEP_NORMAL_MODE | (0x63 << 8) | (0x07 << 24);
// Включить 4й канал (разрешить преобразование по 4му каналу) adc->ADC_CHER = AT91C_ADC_CH4;
6

// Запуск преобразования adc->ADC_CR = AT91C_ADC_START;
//В цикле постоянно проверяем флаг готовности результата по 4му каналу (ждём пока не завершится преобразование)
while (! (adc->ADC_SR & AT91C_ADC_EOC4)) {};
//Считываем результат по 4-му каналу
const unsigned int adcCode = adc->ADC_CDR4;
// Масштабирование результата (для 8-битного режима) const double voltage = adcCode * 3.3 / 256;
Примерный порядок работы с АЦП (минимальный набор действий)
Прежде всего необходимо выполнить настройку АЦП с использованием регистра ADC_MR, указав тем самым разрядность преобразования (8 или 10 бит), режим работы (нормальный/спящий), частоту тактирования АЦП, время выборки и другие параметры.
Также необходимо включить каналы, по которым будет выполняться преобразование с помощью регистра ADC_CHER.
Если предполагается работать с АЦП в режиме «по прерываниям», необходимо настроить контроллер прерываний на обработку сигналов прерываний от АЦП, указать процедуру обработки прерывания, а также включить выдачу сигналов прерываний на стороне АЦП по определённым событиям (например по окончании преобразования).
Далее производится запуск АЦП с использованием регистра ADC_CR.
Считывание результата преобразования (целого числа) производится либо из регистра результата преобразования по каналу (например, ADC_CDR4 для канала 4), либо из регистра последнего результата преобразования (ADC_LCDR). Считывание результата нельзя производить во время преобразования! Поэтому при работе с АЦП в режиме «по готовности» перед считыванием результата необходимо подождать, пока не установится соответствующий флаг готовности в регистре ADC_SR. Если микроконтроллер настроен на генерацию прерываний по окончании преобразования, результат считывается в обработчике прерывания.
Результат преобразования, полученный в виде целого числа не отражает значения напряжения на входе АЦП. Для получения данной величины необходимо выполнить процедуру «масштабирования». Для этого результат преобразования необходимо умножить на величину кванта преобразования. Величина кванта определяется как
q = Uref / 2n,
где Uref – опорное напряжение АЦП, n – разрядность преобразования (определяется полем LOW_RES регистра ADC_MR).
Текст программы, отражающий описанный порядок действий приведён в листинге 2.
Таблица 9. Макроопределения, используемые для программирования АЦП
Макроопределение |
Расшифровка |
Значение |
Назначение |
|
|
|
|
7
|
названия |
|
|
|
|
|
|
Для работы с регистром ADC_CR |
|
См. таблицу 1 |
|
|
|
|
|
AT91C_ADC_SWRST |
Software Reset |
0x1 << 0 |
|
|
|
|
|
AT91C_ADC_START |
Start Conversion |
0x1 << 1 |
|
|
|
|
|
Для работы с регистром ADC_MR |
|
См. таблицу 2 |
|
|
|
|
|
AT91C_ADC_TRGEN |
Triggers enabled |
0x1 << 0 |
Маска, выбирающая бит, |
|
|
|
определяющий включен ли |
|
|
|
аппаратный запуск |
|
|
|
преобразования |
AT91C_ADC_TRGEN_DIS |
Trigger disabled |
0x0 |
Аппаратный запуск |
|
|
|
выключен |
AT91C_ADC_TRGEN_EN |
Trigger enabled |
0x1 |
Аппаратный запуск |
|
|
|
преобразования включён |
AT91C_ADC_TRGSEL |
Trigger selection |
0x7 << 1 |
Битовая маска для |
|
|
|
извлечения выбранного |
|
|
|
источника аппаратного |
|
|
|
запуска. |
AT91C_ADC_TRGSEL_TIOA0 |
Selected TIAO0 |
0x0 << 1 |
канал 0 счётчика/таймера |
|
|
|
|
AT91C_ADC_TRGSEL_TIOA1 |
Selected TIAO1 |
0x1 << 1 |
канал 1 счётчика/таймера |
|
|
|
|
AT91C_ADC_TRGSEL_TIOA2 |
Selected TIAO2 |
0x2 << 1 |
канал 2 счётчика/таймера |
|
|
|
|
AT91C_ADC_TRGSEL_EXT |
Selected external |
0x6 << 1 |
внешний сигнал |
|
trigger |
|
|
|
|
|
|
AT91C_ADC_LOWRES |
Resolution |
0x1 << 4 |
Битовая маска, |
|
|
|
выбирающая поле, |
|
|
|
определяющее разрядность |
|
|
|
преобразования |
AT91C_ADC_LOWRES_10_BIT |
10-bit resolution |
0x0 << 4 |
|
|
|
|
|
AT91C_ADC_LOWRES_8_BIT |
8-bit resolution |
0x1 << 4 |
|
|
|
|
|
|
|
|
|
AT91C_ADC_SLEEP |
Sleep Mode |
0x1 << 5 |
Битовая маска, |
|
|
|
выбирающая поле режима |
|
|
|
работы АЦП |
|
|
|
(нормальный/спящий) |
AT91C_ADC_SLEEP_NORMAL |
Normal Mode |
0x0 << 5 |
Нормальный режим |
_MODE |
|
|
|
AT91C_ADC_SLEEP_MODE |
Sleep Mode |
0x1 << 5 |
Спящий режим |
|
|
|
|
|
|
|
|
AT91C_ADC_PRESCAL |
Prescaler rate |
0x3F << 8 |
Битовая маска, |
|
selection |
|
выбирающая поле делителя |
|
|
|
частоты тактирования АЦП |
8
AT91C_ADC_STARTUP |
Startup Time |
0x1F << |
Битовая маска, |
|
|
|
16 |
|
выбирающая поле времени |
|
|
|
|
подготовки к запуску |
AT91C_ADC_SHTIM |
Sample & Hold |
0xF << 24 |
Битовая маска, |
|
|
Time |
|
|
выбирающая поле времени |
|
|
|
|
выборки. |
|
|
|
|
Для |
|
|
|
|
включения/выключения |
Для работы с регистрами |
|
|
|
каналов, а также |
|
|
|
определения включён ли |
|
ADC_CHER, ADC_CHDR, ADC_CHSR |
|
|
канал. См. таблицы 3,4,5 |
|
AT91C_ADC_CH0 |
Channel 0 |
0x1 |
<< 0 |
|
|
|
|
|
|
AT91C_ADC_CH1 |
Channel 1 |
0x1 |
<< 1 |
|
|
|
|
|
|
AT91C_ADC_CH2 |
Channel 2 |
0x1 |
<< 2 |
|
|
|
|
|
|
AT91C_ADC_CH3 |
Channel 3 |
0x1 |
<< 3 |
|
|
|
|
|
|
AT91C_ADC_CH4 |
Channel 4 |
0x1 |
<< 4 |
|
|
|
|
|
|
AT91C_ADC_CH5 |
Channel 5 |
0x1 |
<< 5 |
|
|
|
|
|
|
AT91C_ADC_CH6 |
Channel 6 |
0x1 |
<< 6 |
|
|
|
|
|
|
AT91C_ADC_CH7 |
Channel 7 |
0x1 |
<< 7 |
|
|
|
|
|
|
Для работы с регистром ADC_SR |
|
|
См. таблицу 6 |
|
|
|
|
|
|
AT91C_ADC_EOC0 |
End of Conversion |
0x1 |
<< 0 |
Преобразование по каналу |
|
Channel 0 |
|
|
0 завершено |
AT91C_ADC_EOC1 |
End of Conversion |
0x1 |
<< 1 |
Преобразование по каналу |
|
Channel 1 |
|
|
1 завершено |
AT91C_ADC_EOC2 |
|
0x1 |
<< 2 |
|
|
|
|
|
|
AT91C_ADC_EOC3 |
|
0x1 |
<< 3 |
|
|
|
|
|
|
AT91C_ADC_EOC4 |
|
0x1 |
<< 4 |
|
|
|
|
|
|
AT91C_ADC_EOC5 |
|
0x1 |
<< 5 |
|
|
|
|
|
|
AT91C_ADC_EOC6 |
|
0x1 |
<< 6 |
|
|
|
|
|
|
AT91C_ADC_EOC7 |
End of Conversion |
0x1 |
<< 7 |
Преобразование по каналу |
|
Channel 7 |
|
|
7 завершено |
AT91C_ADC_OVRE0 |
Overrun Error |
0x1 |
<< 8 |
|
|
|
|
|
|
AT91C_ADC_OVRE1 |
|
0x1 |
<< 9 |
|
|
|
|
|
|
AT91C_ADC_OVRE2 |
|
0x1 |
<< 10 |
|
|
|
|
|
|
AT91C_ADC_OVRE3 |
|
0x1 |
<< 11 |
|
|
|
|
|
|
AT91C_ADC_OVRE4 |
|
0x1 |
<< 12 |
|
|
|
|
|
|
AT91C_ADC_OVRE5 |
|
0x1 |
<< 13 |
|
|
|
|
|
|
AT91C_ADC_OVRE6 |
|
0x1 |
<< 14 |
|
|
|
|
|
|
AT91C_ADC_OVRE7 |
|
0x1 |
<< 15 |
|
|
|
|
|
|
9
AT91C_ADC_DRDY |
Data Ready |
0x1 |
<< 16 |
|
|
|
|
|
|
AT91C_ADC_GOVRE |
General Overrun |
0x1 |
<< 17 |
|
|
|
|
|
|
Для работы с регистрами |
|
|
|
См. таблицы 7, 8. |
ADC_LCDR, |
|
|
|
|
ADC_CDR0, ADC_CDR1, … ADC_CDR7 |
|
|
|
|
AT91C_ADC_LDATA |
Last Data |
0x3FF << |
Битовая маска, |
|
|
Converted |
0 |
|
выбирающая поле |
|
|
|
|
результата аналого- |
|
|
|
|
цифрового преобразования |
10