Урок 17
HAL. ADC. Regular Channel. Interrupt
Проект создаём из ADC_REGULAR, называем его ADC_REGULAR_INT.
Запускаем Cube, проверим на всякий случай прерывания, что они включены.
Генерируем и запускаем наш проект. Добавим также в него lcd.c. Соберем его.
Там же на 108 странице даташита HAL_User_Manual можно посмотреть, как пишется код для АЦП с использованием прерываний. Добавим функцию старта до бесконечного цикла.
LCD_String(str);
HAL_ADC_Start_IT(&hadc1);
/* USER CODE END 2 */
А в бесконечном цикле пока можно всё закомментировать.
В начале главного модуля добавим переменную для хранения результата преобразования
ADC_HandleTypeDef hadc1;
/* USER CODE BEGIN PV */
/* Private variables ———————————————————*/
uint16_t ADC_Data = 0;
/* USER CODE END PV */
Ближе к концу главного модуля добавим функцию
/* USER CODE BEGIN 4 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc1)
{
ADC_Data = HAL_ADC_GetValue(hadc1);
}
/* USER CODE END 4 */
Можно конечно это воткнуть и в обработчик прерывания, но лучше этого не делать. Разработчики библиотеки советуют нам именно такую функцию. Она выполняется не при любом прерывании, а именно тогда, когда закончились преобразования.
Также нужно повторно в этой же функции запустить преобразование, у нас же не автоматический режим.
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc1)
{
ADC_Data = HAL_ADC_GetValue(hadc1);
HAL_ADC_Start_IT(hadc1);//запустим аналогово-цифровое преобразование
}
Ну и давайте ещё отобразим опять же наши данные на дисплее
while (1)
{
// sprintf(str,»%.2fv»,u);//преобразуем результат в строку
sprintf(str,»%04d»,ADC_Data);//преобразуем результат в строку
LCD_SetPos(0,3);//покажем результат на ЖКИ-дисплее
LCD_String(str);
HAL_Delay(200);//задержка перед следующим циклом
/* USER CODE END WHILE */
Соберем проект, прошьем контроллер и посмотрим.
У нас преобразования происходят только 1 раз, при старте либо вообще не работает ничего.
Может показаться, что мы что-то не доделали, но дело не в этом. В обработчике прерывания от АЦП вызывается функция
/* USER CODE END ADC_IRQn 0 */
HAL_ADC_IRQHandler(&hadc1);
/* USER CODE BEGIN ADC_IRQn 1 */
Давайте в нее зайдем и посмотрим ее код. Там очень много кода и он просто на частоте, настроенной нами, физически не может выполниться, вот и не идут у нас преобразования.
Давайте настроим делитель в кубе. Вместо 2 поставим 8.
Соберем проект, прошьем контроллер и видим, что всё заработало. Давайте теперь немного убавим делитель.
Сделаем 4.
Опять все соберем и прошьем
Вроде тоже работает. Таким образом, нужно просто поиграть с частотой и понять, какая будет работать.
Теперь давайте превратим показания на дисплее в удобочитаемый вид по подобию как на прошлом занятии
while (1)
{
u=((float)ADC_Data)*3/4096;
sprintf(str,»%.2fv»,u);//преобразуем результат в строку
Вот теперь дело другое.
Зайдём в Configuration и включим там Continuous Conversion Mode
Опять сгенерируем проект и соберем код
Теперь строчку в обработчике надо удалить
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc1)
{
ADC_Data = HAL_ADC_GetValue(hadc1);
HAL_ADC_Start_IT(hadc1);//запустим аналогово-цифровое преобразование
}
Соберем, Прошьем и посмотрим
Все работает.
Предыдущий урок Программирование МК STM32 Следующий урок
Отладочную плату можно приобрести здесь STM32F4-DISCOVERY
Смотреть ВИДЕОУРОК
Здравствуйте. Пишу сказать большое спасибо за эти уроки, очень полезные и доступные. Увы, на моей stm32f103 код не хочет работать, выводит число 0.38, а если включить Continuous Conversion Mode, то выводит 0.56, эти числа не меняются никак. Уже поигрался с делителем частоты для АЦП, ни в какую. Прошу у Вас совет, заранее спасибо
Ответ вроде как сам вырисовался) Вообщем, если у кого будет такая проблема на stm32f103c8t6, то у меня при системном такте 72Мгц, таком же такте на самой шине APB2 и делителе АЦП 6 (получается на АЦП 12Мгц) — все работает. Пока бьюсь со связкой АЦП и ДМА, но это уже другая история. Короче говоря, приколы с тактированием на 103й плате еще похуже, чем на 407й)
Конечно, это можно назвать приколом, но это задокументированный прикол. В даташите написано, что максимальная частота, на которой может работать АЦП — 14 МГц. Её можно достичь при делителе АЦП 4 и тактовой частоте 56 МГц.