STM Урок 199. LL. STM32F1. ADC. Injected Once Scan. Запуск по таймеру
Продолжаем работать с АЦП (ADC) контроллера STM32F1 с использованием библиотеки LL. Также работать мы продолжим с инжектированной группой каналов и использовать будем режим сканирования последовательности каналов инжектированной группы. Запускать мы будем также наш АЦП на данном уроке автоматически, хотя вернёмся мы в режим однократного преобразования. Как же такое возможно и для чего это нужно?
В режиме кольцевого запуска (continuous) АЦП не может запускаться реже чем через 252 цикла (12,5 + 239,5). Порой бывает нужно запускать АЦП автоматически гораздо реже. Для этого существует у контроллера STM32F1 а АЦП запуск от таймера. Причём запустить наш АЦП мы можем, используя различные события таймера, такие как захват, сравнение и переполнение счётчика.
По таймеру мы ADC уже запускали в других уроках, поэтому справимся и сейчас.
Схема также осталась прежней
Проект был сделан из проекта урока 196 с именем LL_ADC_INJ_ONCE_SCAN и назван LL_ADC_INJ_ONCE_SCAN_TIM.
Откроем проект в Cobe MX и включим глобальные прерывания в ADC1

Включим таймер 4

Настроим его на период в 1 милисекунду и выберем событие обновления

В свойствах ADC1 выберем срабатывание от данного таймера

Также не забываем выбрать библиотеку LL здесь
Сгенерируем проект и откроем его в Keil, настроим автоперезагрузку после прошивки, отключим оптимизацию, подключим к дереву проекта файлы lcd.c и i2c_user.c, откроем main.c и добавим глобальный массив для хранения сырых значений регистров каналов АЦП
|
1 2 |
/* USER CODE BEGIN PV */ __IO uint16_t ADC_Data[4]; |
В функции main() объявление подобного массива удалим
__IO uint32_t wait_loop_index = 0;
__IO uint16_t ADC_Data[4];
Здесь изменим триггер на таймерный
LL_ADC_INJ_SetTriggerSource(ADC1, LL_ADC_INJ_TRIG_EXT_TIM4_TRGO);
Включим локальные прерывания по событию окончания преобразования
|
1 2 |
LCD_ini(); LL_ADC_EnableIT_JEOS(ADC1); |
Включим бит JEXTTRIG в регистре CR2 при помощи специальной функции
|
1 2 |
LL_ADC_EnableIT_JEOS(ADC1); LL_ADC_INJ_StartConversionExtTrig(ADC1,LL_ADC_INJ_TRIG_EXT_RISING); |
Надпись в нижнюю строку на дисплее перенесём в верхнюю
LCD_String("Jnjected Once Scan");
А нижняя строка теперь будет с такой надписью
LCD_String("Timer Ext Trigger");
Запустим таймер и немного подождём
|
1 2 3 |
LCD_String("Timer Ext Trigger"); LL_TIM_EnableCounter(TIM4); LL_mDelay(100); |
Добавим функцию, которую будем вызвать из обработчика прерываний от АЦП, в которой считаем значения из регистров каналов АЦП в элементы массива
|
1 2 3 4 5 6 7 8 |
/* USER CODE BEGIN 4 */ void ADC_ConvCpltCallback(void) { ADC_Data[0] = LL_ADC_INJ_ReadConversionData12(ADC1, LL_ADC_INJ_RANK_1); ADC_Data[1] = LL_ADC_INJ_ReadConversionData12(ADC1, LL_ADC_INJ_RANK_2); ADC_Data[2] = LL_ADC_INJ_ReadConversionData12(ADC1, LL_ADC_INJ_RANK_3); ADC_Data[3] = LL_ADC_INJ_ReadConversionData12(ADC1, LL_ADC_INJ_RANK_4); } |
В файле stm32f1xx_it.c добавим для данной функции прототип
|
1 2 |
/* USER CODE BEGIN PFP */ void ADC_ConvCpltCallback(void); |
Вызовем данную функцию и сбросим флаг в функции-обработчике ADC1_2_IRQHandler
|
1 2 3 4 5 6 7 8 |
void ADC1_2_IRQHandler(void) { /* USER CODE BEGIN ADC1_2_IRQn 0 */ if(LL_ADC_IsActiveFlag_JEOS(ADC1) != 0) { LL_ADC_ClearFlag_JEOS(ADC1); ADC_ConvCpltCallback(); } |
В функции main() файла main.c в бесконечном цикле вот это всё мы можем вполне удалить
LL_ADC_INJ_StartConversionSWStart(ADC1);
while (!LL_ADC_IsActiveFlag_JEOS(ADC1)) {}
LL_ADC_ClearFlag_JEOS(ADC1);
ADC_Data[0] = LL_ADC_INJ_ReadConversionData12(ADC1, LL_ADC_INJ_RANK_1);
ADC_Data[1] = LL_ADC_INJ_ReadConversionData12(ADC1, LL_ADC_INJ_RANK_2);
ADC_Data[2] = LL_ADC_INJ_ReadConversionData12(ADC1, LL_ADC_INJ_RANK_3);
ADC_Data[3] = LL_ADC_INJ_ReadConversionData12(ADC1, LL_ADC_INJ_RANK_4);
Соберём код, прошьём контроллер и посмотрим, как работает наш код




Всё отлично работает!
Таким образом, на данном занятии мы научились запускать преобразование инжектированной группы каналов АЦП контроллера STM32F1 от таймера, что позволило нам теперь более гибко и более в широких пределах настраивать период автоматического запуска преобразования.
Всем спасибо за внимание!
Отладочную плату STM32F103C8T6 можно приобрести здесь STM32F103C8T6
Программатор недорогой можно купить здесь ST-Link V2
Переходник I2C to LCD можно приобрести здесьI2C to LCD1602 2004
Логический анализатор 16 каналов можно приобрести здесь
Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)
Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)





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