STM32 АЦП.
Давайте рассмотрим какими особенностями обладает АЦП в STM32.
Режим регулярных преобразований.
В этом режиме задаётся группа от 1 до 16 каналов, обработка которых производится последовательно, а результат помещается в один-единственный 12-разрядный регистр, подразумевается, что данные будут сохраняться с помощью DMA. Ещё раз хотелось бы подчеркнуть, что нельзя просто выбрать один канал, надо задать группу, а в ней выбрать количество каналов. Преобразования могут быть циклическими и периодическими, запускаться по таймеру или внешнему прерыванию.
Режим инжектированных преобразований.
В последовательность инжектированных преобразований может входить до 4 каналов, они имеют собственные регистры для сохранения результата. Сразу после запуска инжектированных преобразований, приостанавливается оцифровка регулярных, затем по окончании инжектированных, возобновляется оцифровка регулярных. В регистры компенсации можно записать число, которое будет автоматически вычитаться из результата преобразования, если в результате вычитания получается отрицательное число, регистр инжектированного преобразования дополняется знаком.
Оконный компаратор.
В специальных регистрах ADC_HTR и ADC_LTR мы задаём верхнее и нижнее значение результата преобразования, при выходе за которые устанавливается флаг AWD.
Для работы с АЦП в STM32 выделен 1 регистр статуса — SR и два регистра настройки CR1, CR2.
SR(Status Register)
AWD(Analog watchdog flag) — флаг оконного компаратора, устанавливается в 1, когда результат преобразования пересёк ADC_HTR и ADC_LTR.
EOC (End of conversion) – флаг окончания группового преобразования, устанавливается в 1 по окончании регулярного или инжектированного преобразования.
JEOC(Injected channel end of conversion) — флаг окончания инжетированного преобразования, устанавливается в 1 по окончании инжектированого преобразования.
JSTRT(Injected channel Start flag) — флаг запуска инжектированного преобразования, устанавливается в 1 при старте инжектированного преобразования.
STRT(Regular channel Start flag) — флаг запуска регулярного преобразования, устанавливается в 1 при старте регулярного преобразования.
Описанные выше флаги выставляются аппаратно, а сбрасывать их надо программно!!!
ADC_CR1(ADC control register 1)
AWDCH[4:0] (Analog watchdog channel select bits) — выбор канала для оконного компаратора, при условии, что битAWDSGL=1.
00000: Канал № 0.
00001: Канал №1.
………
10001: Канал №17.
EOCIE(Interrupt enable for EOC) — разрешение прерывания по окончании преобразования, 1 — разрешить, 0 — запретить.
AWDIE(Analog watchdog interrupt enable) — разрешение прерывания по сигналу оконного компаратора, 1 — разрешить, 0 — запретить.
JEOCIE(Interrupt enable for injected channels) — разрешение прерывания по окончании инжектированного преобразования, 1 — разрешить, 0 — запретить.
SCAN(Scan mode) — разрешить сканирование каналов по списку указанному в регистрах ADC_SQRx, 1 — разрешить, 0 — запретить.
AWDSGL(Enable the watchdog on a single channel in scan mode) — задаёт режим сканирования оконного компаратора, 0 — все каналы, 1 — только канал указанный в AWDCH[4:0].
JAUTO(Automatic Injected Group conversion) — непрерывное преобразование инжектированных каналов, 1 — разрешить, 0 — запретить.
DISCEN(Discontinuous mode on regular channels) — дискретный(прерывистый) режим преобразования регулярных каналов, 1 — разрешить, 0 — запретить.
JDISCEN(Discontinuous mode on injected channels) — дискретный(прерывистый) режим преобразования инжектированных каналов, 1 — разрешить, 0 — запретить.
DISCNUM[2:0](Discontinuous mode channel count) — количество каналов регулярного преобразования.
000: 1 канал
001: 2 канала
…..
111: 8 каналов
DUALMOD[3:0](Dual mode selection) — определяет режим совместной работы двух АЦП.
JAWDEN(Analog watchdog enable on injected channels) — подключение оконного компаратора к инжектированным каналам, 1 — разрешить, 0 — запретить.
AWDEN(Analog watchdog enable on regular channels) — подключение оконного компаратора к регулярным каналам, 1 — разрешить, 0 — запретить.
ADC_CR2(ADC control register 2)
ADON(A/D converter ON / OFF) — управление АЦП, 1 — разрешает работу АЦП, 0 — прерывает преобразование/калибровку и переводит АЦП в режим пониженного энергопотребления.
CONT(Continuous conversion) — режим преобразования, 0 — однократный, 1 — непрерывный.
CAL(A/D Calibration) — запуск калибровки, 1 — запустить калибровку, 0 — устанавливается аппаратно по завершении калибровки. Производить до включения АЦП, каждый раз после подачи питания.
RSTCAL(Reset calibration) — сброс значений калибровки, 1 — сбросить, 0 — устанавливается по завершении сброса.
DMA(Direct memory access mode) — разрешает работу DMA, 1 – разрешает, 0 — запрещает.
ALIGN(Data alignment) — выравнивание данных, 1 — по правому краю, 0 — по левому. Здесь хорошо будет посмотреть на картинку, так как при инжектированных преобразованиях появляется ещё и знак, на картинке ячейки со знаком обозначены как SEXT.
JEXTSEL[2:0](External event select for injected group) – выбор внешнего источника запуска инжектированных каналов.
JEXTTRIG(External trigger conversion mode for injected channels) — разрешение запуска инжектированного преобразования внешним сигналом, 1 — разрешить, 0 — запретить.
EXTSEL[2:0](External event select for regular group) — выбор внешнего источника запуска регулярных каналов.
EXTTRIG(External trigger conversion mode for regular channels) — разрешение запуска регулярного преобразования внешним сигналом, 1 — разрешить, 0 — запретить.
JSWSTART(Start conversion of injected channels) — запуск преобразования инжектированных каналов, 1 — запустить преобразование, сбрасывается после запуска преобразования аппаратно. Также для запуска в JEXTSEL[2:0] источником запуска должен быть выбран JSWSTART.
SWSTART(Start conversion of regular channels) — запуск преобразования регулярных каналов, 1 — запустить преобразование, сбрасывается после запуска преобразования аппаратно. Также для запуска в EXTSEL[2:0] источником запуска должен быть выбран SWSTART.
TSVREFE(Temperature sensor and VREFINT enable) — включает измерение температуры и ИОН, 1 — включить, 0 — выключить. Есть только в ADC1.
SMPR[2:1](Channel x Sample time selection).
В этих регистрах задаётся количество тактов между выборками, отдельно для каждого канала.
В SMPR1 с 10 по 17-й канал.
В SMPR2 с 0 по 9-й канал.
Длительность преобразования составляет 12.5 цикла, для того чтобы найти период выборок надо к длительности преобразования прибавить значение SMPx[2:0].
Т = время между выборки + 12.5 цикла
Получается минимальный период выборок равен
Т = 12.5 + 1.5 = 14 тактов
Максимальная частота, с которой может тактироваться АЦП составляет 14MHz, таким образом, минимальный период выборок равен 1uS.
JOFRx(x=1..4)
Компенсационные регистры инжектированных каналов, в эти регистры можно записать значение, которое по окончании преобразования будет вычитаться из результата.
HTR и LTR
Верхний и нижний предел оконного компаратора.
SQRх[3:1] – этот регистр можно условно разделить на две части: биты L[3:0] и биты SQx[4:0].
Номер секции SQx определяет номер в группе регулярных преобразований, а число записанное в секцию определяет номер канала.
Узнать какому выводу соответствует канал можно из даташита в разделе Pinouts and pin description.
А битами L[3:0] в регистре SQR1 задаётся длина регулярной последовательности
0000: 1 преобразование
0001: 2 преобразования
….......
1111: 16 преобразований
Например
L = 0010
SQ1=00000, SQ2=00100, SQ3=00010
Означает что длина последовательности равна 3 и выполняться она будет в следующем порядке 1-й , 5-й , 3-й канал.
JSQR — в этих регистрах задаётся длина инжектированной последовательности и порядок преобразований. Битами JL[1:0] задаётся длина последовательности
00: 1 преобразование
01: 2 преобразования
10: 3 преобразования
11: 4 преобразования
Номер секции JSQx определяет номер в группе инжектированных преобразований, а число записанное в секцию определяет номер канала.
Узнать какому выводу соответствует канал можно из даташита в разделе Pinouts and pin description.
Если количество преобразований меньше 4, например 3, то порядок преобразования для записи
ADC_JSQR[21:0] = 10 00011 00011 00111 00010
Будет 7-й,3-й,3-й, а не 2-й,7-й,3-й.
JDR(x = 1...4)
Регистры данных инжектированных преобразований.
DR
Регистр данных регулярных преобразований.
Ниже пример кода для запуска АЦП.
Понятно, что проверить работает ли проект, в симуляторе не получится, так как на вход АЦП ни чего не приходит. Также возникает вопрос, что за строчки закомментированы в цикле while. Проверить проект в симуляторе можно, а закомментированые строчки напоминают как это сделать.
Для начала создаём текстовый документ, записываем в него следующий код и сохраняем его с названием sine.ini
Перемещаем sine.ini в папку проекта, после запуска отладки выполняем то, что написано в закомментированной строчке, в итоге на входе АЦП получаем синус, теперь данные АЦП будут меняться. Картинку можно увеличить кликнув по ней.
- Разрядность 12 бит
- Опорное напряжение от 2.4 до 3.6 Вольта
- Скорость оцифровки до 1MSPS
- 18 каналов(16 внешних и 2 внутренних – опорное напряжение и температурный датчик)
- Прерывание по окончании регулярных и инжектированных преобразований
- Прерывание от оконного компаратора(Analog watchdog)
- Отправка данных по DMA для регулярных преобразований
- Одиночное и непрерывное преобразование
- Режим сканирования каналов по заданному списку
- Самокалибровка
- Выравнивание результата по выбранному краю
- Время преобразования –12.5 цикла, время захвата – программируемое
Режим регулярных преобразований.
В этом режиме задаётся группа от 1 до 16 каналов, обработка которых производится последовательно, а результат помещается в один-единственный 12-разрядный регистр, подразумевается, что данные будут сохраняться с помощью DMA. Ещё раз хотелось бы подчеркнуть, что нельзя просто выбрать один канал, надо задать группу, а в ней выбрать количество каналов. Преобразования могут быть циклическими и периодическими, запускаться по таймеру или внешнему прерыванию.
Режим инжектированных преобразований.
В последовательность инжектированных преобразований может входить до 4 каналов, они имеют собственные регистры для сохранения результата. Сразу после запуска инжектированных преобразований, приостанавливается оцифровка регулярных, затем по окончании инжектированных, возобновляется оцифровка регулярных. В регистры компенсации можно записать число, которое будет автоматически вычитаться из результата преобразования, если в результате вычитания получается отрицательное число, регистр инжектированного преобразования дополняется знаком.
Оконный компаратор.
В специальных регистрах ADC_HTR и ADC_LTR мы задаём верхнее и нижнее значение результата преобразования, при выходе за которые устанавливается флаг AWD.
Для работы с АЦП в STM32 выделен 1 регистр статуса — SR и два регистра настройки CR1, CR2.
SR(Status Register)
AWD(Analog watchdog flag) — флаг оконного компаратора, устанавливается в 1, когда результат преобразования пересёк ADC_HTR и ADC_LTR.
EOC (End of conversion) – флаг окончания группового преобразования, устанавливается в 1 по окончании регулярного или инжектированного преобразования.
JEOC(Injected channel end of conversion) — флаг окончания инжетированного преобразования, устанавливается в 1 по окончании инжектированого преобразования.
JSTRT(Injected channel Start flag) — флаг запуска инжектированного преобразования, устанавливается в 1 при старте инжектированного преобразования.
STRT(Regular channel Start flag) — флаг запуска регулярного преобразования, устанавливается в 1 при старте регулярного преобразования.
Описанные выше флаги выставляются аппаратно, а сбрасывать их надо программно!!!
ADC_CR1(ADC control register 1)
AWDCH[4:0] (Analog watchdog channel select bits) — выбор канала для оконного компаратора, при условии, что битAWDSGL=1.
00000: Канал № 0.
00001: Канал №1.
………
10001: Канал №17.
EOCIE(Interrupt enable for EOC) — разрешение прерывания по окончании преобразования, 1 — разрешить, 0 — запретить.
AWDIE(Analog watchdog interrupt enable) — разрешение прерывания по сигналу оконного компаратора, 1 — разрешить, 0 — запретить.
JEOCIE(Interrupt enable for injected channels) — разрешение прерывания по окончании инжектированного преобразования, 1 — разрешить, 0 — запретить.
SCAN(Scan mode) — разрешить сканирование каналов по списку указанному в регистрах ADC_SQRx, 1 — разрешить, 0 — запретить.
AWDSGL(Enable the watchdog on a single channel in scan mode) — задаёт режим сканирования оконного компаратора, 0 — все каналы, 1 — только канал указанный в AWDCH[4:0].
JAUTO(Automatic Injected Group conversion) — непрерывное преобразование инжектированных каналов, 1 — разрешить, 0 — запретить.
DISCEN(Discontinuous mode on regular channels) — дискретный(прерывистый) режим преобразования регулярных каналов, 1 — разрешить, 0 — запретить.
JDISCEN(Discontinuous mode on injected channels) — дискретный(прерывистый) режим преобразования инжектированных каналов, 1 — разрешить, 0 — запретить.
DISCNUM[2:0](Discontinuous mode channel count) — количество каналов регулярного преобразования.
000: 1 канал
001: 2 канала
…..
111: 8 каналов
DUALMOD[3:0](Dual mode selection) — определяет режим совместной работы двух АЦП.
JAWDEN(Analog watchdog enable on injected channels) — подключение оконного компаратора к инжектированным каналам, 1 — разрешить, 0 — запретить.
AWDEN(Analog watchdog enable on regular channels) — подключение оконного компаратора к регулярным каналам, 1 — разрешить, 0 — запретить.
ADC_CR2(ADC control register 2)
ADON(A/D converter ON / OFF) — управление АЦП, 1 — разрешает работу АЦП, 0 — прерывает преобразование/калибровку и переводит АЦП в режим пониженного энергопотребления.
CONT(Continuous conversion) — режим преобразования, 0 — однократный, 1 — непрерывный.
CAL(A/D Calibration) — запуск калибровки, 1 — запустить калибровку, 0 — устанавливается аппаратно по завершении калибровки. Производить до включения АЦП, каждый раз после подачи питания.
RSTCAL(Reset calibration) — сброс значений калибровки, 1 — сбросить, 0 — устанавливается по завершении сброса.
DMA(Direct memory access mode) — разрешает работу DMA, 1 – разрешает, 0 — запрещает.
ALIGN(Data alignment) — выравнивание данных, 1 — по правому краю, 0 — по левому. Здесь хорошо будет посмотреть на картинку, так как при инжектированных преобразованиях появляется ещё и знак, на картинке ячейки со знаком обозначены как SEXT.
JEXTSEL[2:0](External event select for injected group) – выбор внешнего источника запуска инжектированных каналов.
JEXTTRIG(External trigger conversion mode for injected channels) — разрешение запуска инжектированного преобразования внешним сигналом, 1 — разрешить, 0 — запретить.
EXTSEL[2:0](External event select for regular group) — выбор внешнего источника запуска регулярных каналов.
EXTTRIG(External trigger conversion mode for regular channels) — разрешение запуска регулярного преобразования внешним сигналом, 1 — разрешить, 0 — запретить.
JSWSTART(Start conversion of injected channels) — запуск преобразования инжектированных каналов, 1 — запустить преобразование, сбрасывается после запуска преобразования аппаратно. Также для запуска в JEXTSEL[2:0] источником запуска должен быть выбран JSWSTART.
SWSTART(Start conversion of regular channels) — запуск преобразования регулярных каналов, 1 — запустить преобразование, сбрасывается после запуска преобразования аппаратно. Также для запуска в EXTSEL[2:0] источником запуска должен быть выбран SWSTART.
TSVREFE(Temperature sensor and VREFINT enable) — включает измерение температуры и ИОН, 1 — включить, 0 — выключить. Есть только в ADC1.
SMPR[2:1](Channel x Sample time selection).
В этих регистрах задаётся количество тактов между выборками, отдельно для каждого канала.
В SMPR1 с 10 по 17-й канал.
В SMPR2 с 0 по 9-й канал.
Длительность преобразования составляет 12.5 цикла, для того чтобы найти период выборок надо к длительности преобразования прибавить значение SMPx[2:0].
Т = время между выборки + 12.5 цикла
Получается минимальный период выборок равен
Т = 12.5 + 1.5 = 14 тактов
Максимальная частота, с которой может тактироваться АЦП составляет 14MHz, таким образом, минимальный период выборок равен 1uS.
JOFRx(x=1..4)
Компенсационные регистры инжектированных каналов, в эти регистры можно записать значение, которое по окончании преобразования будет вычитаться из результата.
HTR и LTR
Верхний и нижний предел оконного компаратора.
SQRх[3:1] – этот регистр можно условно разделить на две части: биты L[3:0] и биты SQx[4:0].
Номер секции SQx определяет номер в группе регулярных преобразований, а число записанное в секцию определяет номер канала.
Узнать какому выводу соответствует канал можно из даташита в разделе Pinouts and pin description.
А битами L[3:0] в регистре SQR1 задаётся длина регулярной последовательности
0000: 1 преобразование
0001: 2 преобразования
….......
1111: 16 преобразований
Например
L = 0010
SQ1=00000, SQ2=00100, SQ3=00010
Означает что длина последовательности равна 3 и выполняться она будет в следующем порядке 1-й , 5-й , 3-й канал.
JSQR — в этих регистрах задаётся длина инжектированной последовательности и порядок преобразований. Битами JL[1:0] задаётся длина последовательности
00: 1 преобразование
01: 2 преобразования
10: 3 преобразования
11: 4 преобразования
Номер секции JSQx определяет номер в группе инжектированных преобразований, а число записанное в секцию определяет номер канала.
Узнать какому выводу соответствует канал можно из даташита в разделе Pinouts and pin description.
Если количество преобразований меньше 4, например 3, то порядок преобразования для записи
ADC_JSQR[21:0] = 10 00011 00011 00111 00010
Будет 7-й,3-й,3-й, а не 2-й,7-й,3-й.
JDR(x = 1...4)
Регистры данных инжектированных преобразований.
DR
Регистр данных регулярных преобразований.
Ниже пример кода для запуска АЦП.
#include "stm32f10x.h"
unsigned temp;
void ADC1_2_IRQHandler(void)
{
if(ADC1->SR & ADC_SR_EOC)
{
//записываем результат в переменную
temp =ADC1->DR;
}
//сбрасываем все флаги в регистре статуса
ADC1->SR=0;
}
int main(void)
{
//разрешаем тактирование порта А
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
//настраиваем вывод для работы АЦП в режим аналогового входа
GPIOA->CRL &= ~GPIO_CRL_CNF1;
//так как тактовая частота АЦП не должна превышать 14MHz
RCC->CFGR |= RCC_CFGR_ADCPRE_DIV8;
//разрешаем тактирование АЦП
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN ;
//в комментах подсказали, что в 17 ревизии указано, что перед калибровкоц АЦП надо включить
ADC1->CR2 = | ADC_CR2_ADON;
//запускаем калибровку и ждем пока завершится, в симуляторе это не работает, в железе делать обязательно
/* ADC1->CR2 |= ADC_CR2_CAL;
while (ADC1->CR2 & ADC_CR2_CAL)*/
//разрешаем прерывание от АЦП
NVIC->ISER[0] |= NVIC_ISER_SETENA_18;
//для первого канала между выборками 7.5 цикла
ADC1->SMPR2 = ADC_SMPR2_SMP1_0;
//разрешаем прерывания по окончанию преобразования
ADC1->CR1 = ADC_CR1_EOCIE;
//разрешаем запуск от SWSTAR, разрешаем работу АЦП, разрешаем запуск внешним сигналам, непрерывное преобразования
ADC1->CR2 = ADC_CR2_EXTSEL | ADC_CR2_EXTTRIG | ADC_CR2_CONT ;
//длина последовательности равна 1, первый канал
ADC1->SQR1 = 0x00000000;
ADC1->SQR2 = 0x00000000;
ADC1->SQR3 = 0x00000001;
//запускаем АЦП
ADC1->CR2 |= ADC_CR2_SWSTART;
while(1)
{
/*остановить проект, в командную строку записать include sine.ini
затем записать ADC1_IN1_Sine ()*/
}
}
Понятно, что проверить работает ли проект, в симуляторе не получится, так как на вход АЦП ни чего не приходит. Также возникает вопрос, что за строчки закомментированы в цикле while. Проверить проект в симуляторе можно, а закомментированые строчки напоминают как это сделать.
Для начала создаём текстовый документ, записываем в него следующий код и сохраняем его с названием sine.ini
SIGNAL void ADC1_IN1_Sine (void) {
float volts; // peak-to-peak voltage
float frequency; // output frequency in Hz
float offset; // voltage offset
float duration; // duration in Seconds
float val;
long i, end;
volts = 1.5;
offset = 1.5;
frequency = 50;
duration = 0.01;
printf ("Sine Wave Signal on AD Channel 1.\n");
end = (duration * 1000000000);
for (i = 0 ; i < end; i++) {
val = __sin (2 * 3.1415926 * frequency * (((float) STATES) / STCLK));
ADC1_IN1 = (val * volts) + offset;
swatch (0.00001); // in 10 uSec steps
}
}
DEFINE BUTTON "ADC1_IN1 Sin","ADC1_IN1_Sine()"
Перемещаем sine.ini в папку проекта, после запуска отладки выполняем то, что написано в закомментированной строчке, в итоге на входе АЦП получаем синус, теперь данные АЦП будут меняться. Картинку можно увеличить кликнув по ней.
Похожие статьи