Продолжаем работать с АЦП (ADC) контроллера STM32F1 с использованием библиотеки LL. Также работать мы продолжим с одним инжектированным каналом и отслеживать окончание процесса преобразования мы также будем при помощи механизма прерываний от АЦП, только в данном уроке мы попробуем уже поработать не с однократным преобразованием, которое нужно каждый раз в каждой итерации заново запускать, а применим автоматический механизм запуска.
С данным режимом мы работали, используя регулярный канал, в уроке 187, поэтому нам разобраться с данной темой будет несложно, так как с инжектированным всё аналогично.
Схема урока у нас также не изменилась
Проект мы сделаем из проекта прошлого урока с именем LL_ADC_INJ_ONCE_INT и назовём его LL_ADC_INJ_CONT_INT.
Откроем наш проект в Cube MX и в свойствах ADC1 включим кольцевой (автоматический) режим преобразования сигнала
Также для того, чтобы преобразования запускались не слишком часто, установим наибольший интервал между выборками
С какой частотой будут происходить теперь преобразования в кольцевом режиме, мы уже считали, поэтому сгенерируем проект и откроем его в Keil, настроим автоперезагрузку после прошивки, отключим оптимизацию, подключим к дереву проекта файлы lcd.c и i2c_user.c, откроем main.c и удалим объявление глобального флага
__IO uint8_t fl_adc;
Вместо него добавим переменную для сырого значения ADC
1 2 |
/* USER CODE BEGIN PV */ __IO uint16_t ADC_Data; |
А в функции main() мы такую же, но локальную, переменную удалим
__IO uint32_t wait_loop_index = 0;
__IO uint16_t ADC_Data;
Из тела функции, играющей роль обработчика прерываний по флагу окончания преобразования ADC_ConvCpltCallback удалим установку пользовательского флага
fl_adc = 1;
Вместо этого мы здесь считаем значение из регистра 1 канала ADC1
1 2 3 |
void ADC_ConvCpltCallback(void) { ADC_Data = LL_ADC_INJ_ReadConversionData12(ADC1, LL_ADC_INJ_RANK_1); |
В функции main() включим режим Continuous
1 2 |
//Configure Injected Channel LL_ADC_REG_SetContinuousMode(ADC1, LL_ADC_REG_CONV_CONTINUOUS); |
А здесь исправим количество циклов между выборками
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_1, LL_ADC_SAMPLINGTIME_239CYCLES_5);
Вызовем функцию, которая включит автоматический запуск инжектированной группы после регулярной. Хотя у нас регулярная группа не задействована, но без этого почему-то не работает. Данная функция установит бит JAUTO в регистре CR1
1 2 |
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_1, LL_ADC_SAMPLINGTIME_239CYCLES_5); LL_ADC_INJ_SetTrigAuto(ADC1, LL_ADC_INJ_TRIG_FROM_GRP_REGULAR); |
Исправим надпись на дисплее здесь
LCD_String("Jnjected Continuous");
А здесь добавим букву, пропущенную в прошлом уроке
LCD_String("Intеrrupt");
Стартуем наш АЦП до бесконечного цикла и тут можно подождать немного, так как мы процесс окончания преобразования теперь не отслеживаем и в первой итерации рискуем поэтому получить какое-то случайное значение, которое ещё не записалось в нашу переменную
1 2 3 |
LCD_String("Intеrrupt"); LL_ADC_INJ_StartConversionSWStart(ADC1); LL_mDelay(100); |
Всё вот это хозяйство теперь удаляем из бесконечного цикла
LL_ADC_INJ_StartConversionSWStart(ADC1);
while (!fl_adc) {}
fl_adc = 0;
ADC_Data = LL_ADC_INJ_ReadConversionData12(ADC1, LL_ADC_INJ_RANK_1);
Собираем код, прошиваем контроллер и смотрим как у нас всё работает
Работает всё отлично!
Итак, на данном занятии мы освоили механизм автоматического запуска преобразований инжекторного канала АЦП, что позволило нам ещё более разгрузить основной код.
Всем спасибо за внимание!
Предыдущий урок Программирование МК STM32 Следующий урок
Отладочную плату STM32F103C8T6 можно приобрести здесь STM32F103C8T6
Программатор недорогой можно купить здесь ST-Link V2
Переходник I2C to LCD можно приобрести здесьI2C to LCD1602 2004
Логический анализатор 16 каналов можно приобрести здесь
Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)
Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)
Добавить комментарий