Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.53/40: Рейтинг темы: голосов - 40, средняя оценка - 4.53
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511

Работа АЦП по таймеру во FREERTOS stm32

15.09.2020, 07:33. Показов 9565. Ответов 31

Студворк — интернет-сервис помощи студентам
Столкнулся с такой проблемой: не работает АЦП по таймеру во FREERTOS. Есть проект, сгенерированный в CubeMX, там настроено: FREERTOS, LWIP, АЦП, таймер и USART. Если запускать АЦП вручную, т.е. в одной из задач использую задержку osDelay(1000), то все работает отлично, АЦП раз в секунду оцифровывает несколько каналов, DMA забирает данные, потом в прерывании от DMA вызывается семафор, который сигнализирует о том, что данные готовы и их можно передавать, следом идет передача данных по LWIP и USART, цикл повторяется. Таймер тоже в это время настроен и работает.
Дальше я хочу запускать АЦП не каждый раз, когда запускается задача FREERTOS, а по таймеру. И тут накрывается все, что есть. LWIP и USART перестают работать, АЦП вроде тоже. Не могу понять в чем проблема, какие настройки не так заданы, или может какой-то конфликт с ОС.
Задача ОС для АЦП:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
void StartAdcTask(void const * argument)
{
  /* USER CODE BEGIN StartAdcTask */
  /* Infinite loop */
  //-------------------------------------------------------
  volatile uint16_t adcDataBuf[4] = {0,0,0,0};
  uint16_t timeout = 1;
 
  // Запускаю АЦП, ДМА и таймер
  HAL_ADC_Start_DMA(&hadc3, (uint16_t*)&adcDataBuf, 4);
  HAL_TIM_OC_Start(&htim3, TIM_CHANNEL_4);
 
  for(;;)
  {
      for (uint8_t num = 0; num < 4; num++)
      {
          adcDataBuf[num] = 0;
      }
 
          // Сюда попадаем из функции прерывания, когда DMA закончит передачу данных
      if (xSemaphoreTake(binary_semaphore_2, portMAX_DELAY) == pdPASS)
      {
          HAL_ADC_Stop_DMA(&hadc3);
          struct struct_adc_t AdcDataStruct;
          for (uint8_t i = 0; i < 4; i++)
          {
              AdcDataStruct.adc_str[i] = adcDataBuf[i];
          }
          NumCount++;
 
                  // Две очереди для передачи данных АЦП в сокет и в USART
          if (QueueTcpState == 0)
          {
              xQueueSend(adc_Queue, &AdcDataStruct, pdMS_TO_TICKS(timeout));
          }
          xQueueSend(send_data, &adcDataBuf, pdMS_TO_TICKS(timeout));
      }
      osDelay(100);
  }
  //-------------------------------------------------------
  /* USER CODE END StartAdcTask */
}
Прерывание от DMA:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
    portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
    if(hadc->Instance == ADC3)
    {
        // Семафор, который сигнализирует о том, что данные готовы и их можно передавать
        xSemaphoreGiveFromISR(binary_semaphore_2,&xHigherPriorityTaskWoken);
        portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_7);
    }
    else
    {
        __NOP();
    }
}
Скрины с настройкой АЦП и таймера прикладываю. Буду благодарен любой помощи, уже довольно долго не могу понять в чем ошибка
Миниатюры
Работа АЦП по таймеру во FREERTOS stm32   Работа АЦП по таймеру во FREERTOS stm32  
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
15.09.2020, 07:33
Ответы с готовыми решениями:

FreeRTOS для STM32
Здравствуйте ! Учу FreeRTOS. В таски вставил функции vTaskSuspend() и, соответственно, vTaskResume(). Так вот. Первая функция в...

Семафоры в FreeRTOS на STM32
Добрый день! Столкнулся с непонятной проблемой при работе из бинарными семафорами в FriiRTOS. Если коротко - после создания семафора он...

FreeRTOS проблема при передаче данных с АЦП
На stm32f746 discovery настроена FreeRTOS, есть несколько задач, одна из которых это оцифровка нескольких каналов АЦП, извлечение...

31
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,874
22.09.2020, 08:01
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от DmitryDDDD Посмотреть сообщение
но одна не используется, там просто osDelay(1)
а зачем osDelay(1)??? каждую милисекунду задача будет выполнятся и ничего не делать
поставь хотя бы osDelay(1000)

Добавлено через 1 минуту
Цитата Сообщение от DmitryDDDD Посмотреть сообщение
А там я выше выложил архив с проектом,
только забыл сказать какая IDE и какой камень
1
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
22.09.2020, 08:07  [ТС]
ValeryS,
Цитата Сообщение от ValeryS Посмотреть сообщение
только забыл сказать какая IDE и какой камень
, да, пардон, f746, IDE STM32CubeMX.
Цитата Сообщение от ValeryS Посмотреть сообщение
а зачем osDelay(1)???
Моя ошибка, хотел чтобы та задача выполняла некоторые функции, но потом не стал туда их добавлять а задачу не удалил.
Я открыл ваш проект, запустил, как минимум в колбэк теперь попадаю, там прописывал светодиодом моргать, моргает. Правда передача по сокету и USART перестали работать. Тут пока не знаю в чем причина может быть.
А какие изменения вы внесли в проект? Я так пробежался взглядом по таймеру и ацп, вроде ничего не заметил
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,874
22.09.2020, 08:20
Цитата Сообщение от DmitryDDDD Посмотреть сообщение
А какие изменения вы внесли в проект?
я ничего не вносил вносил _SayHello,
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
22.09.2020, 09:59  [ТС]
_SayHello, ValeryS,
Цитата Сообщение от ValeryS Посмотреть сообщение
я ничего не вносил вносил _SayHello,
ага, пардон, я просто торопился, когда писал ответ)

Добавлено через 5 минут
ValeryS,
Цитата Сообщение от ValeryS Посмотреть сообщение
не знаю как твой отладчик, не работал, а кеиловский сходит с ума от большого количества точек останова
Я раньше тоже пользовался кейлом, и SPL, потом как пришлось перейти на HAL, из-за камней 7й серии, стал использовать STM32Cube IDE, тем более, что все равно приходится проект в CubeMX генерировать, да и за допустимые бесплатные 32 кБ кейла код вылез. Если в отладчике кейла еще ориентировался, то этим отладчиком первый раз пользуюсь, пока ньюансов не знаю, но пробовал как с несколькими брекпоинтами, там и с двумя, все одно, кручусь в прерывании таймера ОС. Сейчас попробую разобраться
0
 Аватар для _SayHello
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
22.09.2020, 11:59
DmitryDDDD, я же еще в начале треда написал . У вас таймер используется в качестве триггера для АЦП по событию Capture Compare CH4. Однако таймер в этот режим не настроен был.
1
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
22.09.2020, 13:33  [ТС]
_SayHello, я просто выставил Trigger Event Sekection TRGO в Output Compare (OC4REF), не знал, что еще надо настраивать канал 4 дополнительно. Просто сколько не смотрел примеров настройки АЦП по таймеру в Cube, во всех просто настраивали таймер и в АЦП указывали источник запуска таймер, и все. Спасибо за помощь, теперь вроде разобрался с запуском АЦП. Почему-то правда сокет и USART теперь не запускаются

Добавлено через 1 час 22 минуты
_SayHello, Рано я обрадовался, я думал, что попадаю в колбэк, т.к. там было настроено мигание светодиодом, оказалось он мигал из другой задачи, я там его забыл отключить. Поэтому пока все так же как и раньше, в колбэк не попадаю
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
25.09.2020, 05:53  [ТС]
ValeryS, _SayHello, может кому будет полезно или интересно, но АЦП с DMA по таймеру запустилось только когда указал в настройках таймера:
Mode: Toggle on match
Clock source: disable
Channel4: Output COmpare No Output
Причем, насколько успел потестить, от настроек Trigger Event Selection и auto-reload preload ничего не меняется, включены они или нет, хотя одна указывает событие по которому должно срабатывать прерывание, а другая указывает, что при переполнении таймер надо перезапустить заново. Казалось бы важные настройки, да и во всех уроках, которые встречал они использовались, но потом нашел другой урок и взял некоторые настройки оттуда и там они были отключены
0
 Аватар для _SayHello
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
25.09.2020, 12:21
DmitryDDDD, проверьте только одну штуку: по какаому событию у вас будет АЦП срабаотывать по rising/falling edge или both. Так как при режиме Toggle on match и rising/falling edge, частота оцифровки скорее всего будет в два раза меньше частоты таймера.
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
25.09.2020, 13:22  [ТС]
_SayHello, ну да, есть такое, спасибо, не мог понять почему при частоте 100 МГц (APB2 timers), делители 10 000, и счетчике до 10 000, я получаю оцифровку каждые две секунды, а не раз в секунду. Сейчас поставил срабатывание АЦП по both, стало нормально срабатывать

Добавлено через 20 минут
_SayHello, А еще можете подсказать, наткнулся на форуме на ваши темы относительно измерения выходного сигнала температурных датчиков при помощи АЦП, в целом то же самое делаю сейчас. И там вы писали про самонагрев датчика в процессе работы, т.е. если постоянно гнать ток через него, то он будет нагревать сам себя, поэтому вы включали источник тока только на период измерения АЦП, остальное время ток через датчик не проходил.
Вот я думаю сделать аналогично, только я не использую источник тока, у меня датчик температуры подключен как один из резисторов делителя напряжения, на который я подаю 3.3 вольта. Но суть та же, напряжение подается постоянно. Поэтому я хочу напряжение подавать не постоянно, а с пина МК (датчиков несколько, поэтому по пину на датчик).
Реализовать я думаю это можно если подключить второй таймер, который будет запускать первым таймером, запускающим АЦП. Но при этом у первого таймера выставить настройку Master/Slave Mode в Enable для синхронизации, а так же Pulse порядка 1000 тиков (это будет 10 микросек при частоте тактирования 100 МГц) для задержки, чтобы второй таймер в это время подал напряжение на все пины, с которых подается напряжение на делитель. Напряжение подается на время равное 40,5 тиков (28 тиков на заряд кондера АЦП и 12,5 на оцифровку) умноженое на количество датчиков, там выходит чуть больше 10 мк сек в итоге.
Т.е. первый таймер при срабатывании запускает АЦП с задержкой, а второй таймер устанавливает напряжение на используемые пины на время чуть больше времени работы АЦП. Так будет работать?

Добавлено через 17 минут
_SayHello, Но тут по-моему только такой вариант: при вызове второго таймера установить уровни пинов, разово досчитать до нужного количества тиков, вызвать прерывание в котором сбросить все пины и ждать следующего вызова первым таймером. Функцию прерывания таймера я вроде знаю
C
1
2
3
4
5
6
7
8
9
10
void TIM1_UP_TIM10_IRQHandler(void)
{
  /* USER CODE BEGIN TIM1_UP_TIM10_IRQn 0 */
 
  /* USER CODE END TIM1_UP_TIM10_IRQn 0 */
  HAL_TIM_IRQHandler(&htim1);
  /* USER CODE BEGIN TIM1_UP_TIM10_IRQn 1 */
 
  /* USER CODE END TIM1_UP_TIM10_IRQn 1 */
}
А какая функция будет вызываться при непосредтвенно вызове одного таймера другим?
0
 Аватар для _SayHello
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
25.09.2020, 13:53
DmitryDDDD, в HAL Я вам не подскажу, так как не особо силен. Что по датчикам: для платиновых датчиков постоянный ток, который можно использовать, насколько я помню, 1 мА. Если использовать такой ток, то можно ничего не выключать. Но с таким током разрашение для PT100 будет 0.385 * 0.001 = 0.385 мВ на градус, я поднимал ток до 10 мА, чтобы разрешение стало 3.85 мВ на градус.
Пусть у вас АЦП запускается раз в секунду по событию от канала CH4 таймера 3. Вы можете использовать CH2 для включения питания и CH3 для выключения. Настраиваете CH2 и CH3 в режим Output Compare. Пусть ваш таймер запускает АЦП при сравнении CH4 скажем с 30000, тогда вы можете CH2 поставить на сравнение с 29000, и в прерывании этого канала выставлять питание (разницу 1000 тиков оставим на переходный процесс установки питания), а CH3 на сравнение скажем 35000 и по прерыванию от CH3 выключать питание. Таким образом у вас будет 5000 тиков на измерение, тут уж сами посчитает хватит вам этого времени или нет, может и раньше можно будет отключить. Таким образом, питание будет подано на датчик только в течение 6000 тиков. Опять же посчитаете скважность, какую вам нужно.
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
25.09.2020, 14:14  [ТС]
_SayHello, ValeryS, , там pt1000, ну я делителем делал, у меня получись по напряжению не помню, а по отсчетам АЦП от 1263 до 1910 это на измерение от -50 до 150 град. Т.е. 3,235 значения АЦП на градус. Десятые градуса не вывожу, поэтому хватает вроде. Еще второй датчик есть, там уже на градус 6,74 значения АЦП получается. По току там примерно выходит так, что допустимый 1 mA и как раз через делитель проходит 1mA, вот греет он его или нет не помню, надо еще раз будет посчитать схему. Но у вас был фиксированный ток, менялось напряжение и сопротивление. У меня схема другая, тут напряжение фиксированное, меняется ток и сопротивление. Я думаю пока оставлю так как есть.
Я как-то даже не подумал, что можно обойтись одним таймером, надо попробовать.
Еще такой вопрос по прерываниям таймеров, может знаете, есть файл stm32f7xx_it.c там есть функции прерывания наподобие такой
C
1
2
3
4
5
6
7
8
9
10
void TIM3_IRQHandler(void)
{
  /* USER CODE BEGIN TIM3_IRQn 0 */
 
  /* USER CODE END TIM3_IRQn 0 */
  HAL_TIM_IRQHandler(&htim3);
  /* USER CODE BEGIN TIM3_IRQn 1 */
 
  /* USER CODE END TIM3_IRQn 1 */
}
А есть еще вызов коллбека уже в main.c
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* USER CODE BEGIN Callback 0 */
 
  /* USER CODE END Callback 0 */
  if (htim->Instance == TIM1) {
    HAL_IncTick();
  }
  /* USER CODE BEGIN Callback 1 */
  //--------------------------------------------------------
 
  //--------------------------------------------------------
  /* USER CODE END Callback 1 */
}
В основном пишут, что прерывание от таймера можно обработать в коллбеке, но у меня там уже вызывается первый таймер, который управляет хендлером FreeRTOS, будет ли правильно делать такой вызов:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* USER CODE BEGIN Callback 0 */
 
  /* USER CODE END Callback 0 */
  if (htim->Instance == TIM1) {
    HAL_IncTick();
  }
  /* USER CODE BEGIN Callback 1 */
  //--------------------------------------------------------
  if (htim->Instance == TIM3) {
    // Обрабатываем прерывание таймера 3
  }
  //--------------------------------------------------------
  /* USER CODE END Callback 1 */
}
Или в этот коллбек лучше не лезть, чтобы не отразилось на работе FreeRTOS?
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
29.09.2020, 12:44  [ТС]
Если вдруг кому-то понадобится, помог вызов колбека:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == TIM4)
    {
        if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
        {
            //
        }
        else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)
        {
            //
        }
        else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4)
        {
            //
        }
    }
}
Из документации:
C
1
2
3
4
5
6
7
8
9
10
        /* Output compare event */
        else
        {
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
          htim->OC_DelayElapsedCallback(htim);
          htim->PWM_PulseFinishedCallback(htim);
#else
          HAL_TIM_OC_DelayElapsedCallback(htim);
          HAL_TIM_PWM_PulseFinishedCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
29.09.2020, 12:44
Помогаю со студенческими работами здесь

FreeRTOS + STM32 VL Discovery + CoIDE
Пытаюсь запустить простенькую программу с FriiRTOS... Системно-зависимую часть брал из каталога portable/GCC/ARM_CM3. Распределение...

STM32 Sleep\Stop with FreeRTOS
И снова всем доброго времени суток, Продолжая ознакомление и изучение возможностей использования FriiRTOS на STM32ках, добрался до...

Stm32 не работает I2C в FreeRTOS
День добрый. Подключаю модуль с EEPROM памятью к STM32F401. Если пытаюсь записать и прочитать данные без использования FreeRTOS в отдельном...

STM32 + ENC28J60 + LwIP + FreeRTOS
Всем привет! Собственно, есть необходимость запустить сабж. Знаю, что глупо, но STM32F107 и физика где-то далеко, а дискавери и ENC лежат...

Stm32, FREERtos и загрузка программы в ОЗУ
Доброго времени суток!!! Решил себе добавить всяких болезней :). Хочу сдеалать плату на STM32 с внешней памятью, AT45, fram, может еще...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
32
Ответ Создать тему
Новые блоги и статьи
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер. Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром. возможно получится прикрутить интерпретатор питон для кастомизации игровой логики. что есть на текущий момент:. . .
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2. Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
Благородство как наказание
Maks 24.04.2026
У хорошего человека отношения с женщинами всегда складываются трудно. А я человек хороший. Заявляю без тени смущения, потому что гордиться тут нечем. От хорошего человека ждут соответствующего. . .
Валидация и контроль данных табличной части документа перед записью
Maks 22.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в КА2. Задача: контроль и валидация данных табличной части документа перед записью с учетом регламента компании. . .
Отчёт о затраченных материалах за определенный период с макетом печатной формы
Maks 21.04.2026
Отчёт из решения ниже размещён в конфигурации КА2. Задача: разработка отчёта по затраченным материалам за определённый период, с возможностью вывода печатной формы отчёта с шапкой и подвалом. В. . .
Отчёт о спецтехнике находящейся в ремонте
Maks 20.04.2026
Отчёт из решения ниже размещен в конфигурации КА2. Задача: отобразить спецтехнику, которая на данный момент находится в ремонте. Есть нетиповой документ "Заявка на ремонт спецтехники" который. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru