СОВРЕМЕННАЯ ЭЛЕКТРОНИКА №3/2015
ЭЛЕМЕНТЫ И КОМПОНЕНТЫ 39 WWW.SOEL.RU СОВРЕМЕННАЯ ЭЛЕКТРОНИКА ◆ № 3 2015 водится либо внешним сигналом, либо установкой бита ADON в реги- стре ADC_CR2. Если внешний запуск инжектированных каналов происхо- дит во время преобразования сигналов группы регулярных каналов, то теку- щее преобразование приостанавли- вается и запускается преобразование последовательности инжекционных каналов в режиме однократного ска- нирования. Затем возобновляется преобразова- ние группы регулярных каналов, начи- ная с того канала, который был прер- ван. Если во время инжекционного преобразования происходит событие запуска регулярных каналов, то оно не прерывает это преобразование, но запуск регулярной последовательно- сти выполняется сразу после оконча- ния обработки инжекционной после- довательности. При использовании запуска инжектированных каналов внешним событием необходимо убе- диться, что интервал между события- ми запуска дольше, чем время преоб- разования инжекционных каналов. Например, если длительность последо- вательности преобразований составля- ет 28 циклов тактового АЦП, то мини- мальный интервал между событиями запуска должен быть 29 циклов. Если установлен бит JAUTO, то после завершения преобразования группы регулярных каналов автоматически запускается преобразование группы инжекционных каналов. Это можно использовать, чтобы преобразовать последовательность из 17–20 кана- лов, заданных в регистрах ADC_JSQR и ADC_SQRx. В этом режиме механизм запуска внешним событием должен быть отключён. Если в дополнение к биту JAUTO установлен бит CONT, то сразу после преобразования груп- пы инжекционных каналов вновь запу- скается преобразование группы регу- лярных каналов. Использовать одно- временно оба режима, автоматический запуск и запуск внешним событием, невозможно. К АЛИБРОВКА АЦП АЦП имеет встроенный механизм автоматической калибровки. Калибров- ка значительно уменьшает погреш- ность оцифровки, которая вызывается неоднородностью внутренних конден- саторов выборки и хранения сигна- лов. Во время калибровки вычисляет- ся цифровое значение АЦП для каждого конденсатора в виде корректирующе- го кода. Во время всех последующих преобразований этот код использует- ся для компенсации ошибки преобра- зования сигналов. Перед началом калибровки АЦП дол- жен находиться в отключённом состо- янии, то есть бит ADON должен быть равен нулю, по крайней мере в течение двух циклов тактового АЦП. Запуск калибровки производится уста- новкой бита CAL в регистре ADC_CR2. Как только калибровка закончена, бит CAL сбрасывается аппаратно, после чего может быть выполнено нормальное пре- образование. Рекомендуется калибро- вать АЦПодин раз при подаче питания. Коды калибровки сохраняются в ADC_ DR при завершении фазы калибровки. Листинг 1 //========================= // Функция инициализации АЦП //========================= void Init_ADC(void) { RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // Разрешить тактирование порта PORTA // Сконфигурировать PORTA.6 как аналоговый вход GPIOA->CRL &= ~GPIO_CRL_MODE6; // Очистить биты MODE GPIOA->CRL &= ~GPIO_CRL_CNF6; // Очистить биты CNF RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; // Включить тактирование АЦП RCC->CFGR &= ~RCC_CFGR_ADCPRE; // Задать значение делителя тактовой частоты ADC1->CR1 = 0; // Обнулить регистр управления ADC1->SQR1 = 0; // Обнулить регистр SQR1 ADC1->CR2 |= ADC_CR2_CAL; // Пуск калибровки while (!(ADC1->CR2 & ADC_CR2_CAL)){}; // Ждать окончания калибровки ADC1->CR2 = ADC_CR2_EXTSEL; // Выбрать источником запуска разряд SWSTART ADC1->CR2 |= ADC_CR2_EXTTRIG; // Разрешить внешний запуск регулярного канала ADC1->CR2 |= ADC_CR2_ADON; // Включить АЦП } //====================================================== // Функция запуска преобразования АЦП и чтение выбранного канала // Вход - номер канала для преобразования // Выход - результат преобразования //====================================================== uint16_t RD_ADC(uint8_t nk) { ADC1->SQR3 = nk; // Задать номер канала ADC1->CR2 |= ADC_CR2_SWSTART; // Пуск преобразования while(!(ADC1->SR & ADC_SR_EOC)){}; // Ждать окончания преобразования return ADC1->DR; // Считать результат преобразования } //========================= // Главный модуль программы //========================= void main(void) { unsigned int ai; // Инициализация переменных // Другие команды … while(1) // Бесконечный цикл { Init_ADC(); // Выполнить инициализацию и пуск АЦП ai = RD_ADC(6); // Считать данные АЦП для канала 6 // Другие команды … } }
RkJQdWJsaXNoZXIy MTQ4NjUy