Перейти к содержанию

STM32F103 ШИМ, АЦП, таймер


strifonoff

Рекомендуемые сообщения

Запутался в инициализациях. Прошу помощи.

Стоит задача: измерить реакцию объекта на меандр. 
Процесс №1: запустить ШИМ, запустить АЦП и максимально быстро опросить вход, получив 1000 значений - записать их в массив, выключить ШИМ и АЦП.

Процесс №2: запускать процесс №1 каждые 250 миллисекунд 100 раз. Получаем 100 массивов по 1000 значений.

Процесс №3: запускать процесс №2 каждый час, после выполнения процесса №2 произвести какие-то вычисления, скинуть всё по УАРТ и уснуть до следующего выполнения.

Накидал рыбу (посмотрите инициализации). 

Запутался с тем, как запускать и отключать ШИМ и АЦП.

main.c

В симуляторе IAR зависает на инициализации АЦП. Конкретно в строке while(ADC_GetResetCalibrationStatus(ADC1)){};

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Во-первых, избавься от мусора и использую только CMSIS. Тогда отладить код будет в разы проще, т.к. можно будет отслеживать код по даташиту.

 

1 час назад, strifonoff сказал:

запустить АЦП и максимально быстро опросить вход, получив 1000 значений

DMA в помощь. Запускаешь АЦП, запускаешь DMA, включаешь прерывание по окончанию записи.

 

1 час назад, strifonoff сказал:

запускать процесс №1 каждые 250 миллисекунд 100 раз

Таймер в помощь.

 

1 час назад, strifonoff сказал:

запускать процесс №2 каждый час,

Аналогично таймер или RTC.

 

1 час назад, strifonoff сказал:

Получаем 100 массивов по 1000 значений.

А в память оно влезет вообще?

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

так я вроде cmsis и использую, не?

Про DMA, точнее про прерывание можно поподробнее?

с таймерами я вроде разобрался.

Вопрос в запуске и останове ШИМ и АЦП. Если делать по прерыванию, то выглядит просто и понятно, осталось только понять как вызвать прерывание.

Если в память не влезет, то впихну какую-то математику в 250мсекундное окно.

В гугле не забанили, но там либо совсем непонятно, либо мигание светодиодом.

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

1 час назад, strifonoff сказал:

так я вроде cmsis и использую, не?

3 часа назад, strifonoff сказал:

while(ADC_GetResetCalibrationStatus(ADC1)){};

Нет

 

1 час назад, strifonoff сказал:

Про DMA, точнее про прерывание можно поподробнее?

В инете полно примеров.

 

1 час назад, strifonoff сказал:

Вопрос в запуске и останове ШИМ и АЦП.

АЦП тормозить не надо. DMA сам остановится и перестанет складывать отсчеты в буфер.

 

1 час назад, strifonoff сказал:

Если в память не влезет,

Это надо считать на этапе выбора МК.

Ссылка на комментарий
Поделиться на другие сайты

В инете полно примеров... Только эти примеры поймёт только тот кто их писал.

DMA сам остановится и перестанет складывать отсчеты в буфер. А как это сделать? Скиньтие плз хоть ссылку на пример какой-нибудь.

Ссылка на комментарий
Поделиться на другие сайты

Если это ваш первый проект с STM32 или с МК вообще, вы бы с чего-то попроще начали бы что ли.

Я, например, независимо оттипа  МК всегда начинаю с того, что мигаю светодиодом каждые 0.5с. По завершению этого этапа появляется уверенность в том, что

  1. Тактовый генератор запустился и работает правильно.
  2. Порты конфигурируются правильно.
  3. Таймер настроен правильно.
  4. Прерывания по этому таймеру (1 мс) настроены правильно и работают.

Все остальное настраивается после этой подготовительно-ознакомительной процедуры. Когда на том же МК делаю еще что-то, у меня на руках уже имеется готовый костяк, на который навешивается все остальное.

Изменено пользователем Zhuk72
Ссылка на комментарий
Поделиться на другие сайты

17 часов назад, strifonoff сказал:

Только эти примеры поймёт только тот кто их писал.

Поймет тот, кто внимательно читает даташиты и статьи, а не тупо смотрит код. Вся настройка DMA буквально 5 строк кода.

 

void DMA1_Channel1_IRQHandler(void){
	if(DMA1->ISR & DMA_ISR_HTIF1){
		DMA1->IFCR |= DMA_IFCR_CHTIF1;
	}
}

void ADC_DMA_Init(void){
	RCC->AHBENR |= RCC_AHBENR_DMA1EN;
	
	DMA1_Channel1->CCR &= ~DMA_CCR1_EN;
	
	DMA1_Channel1->CCR = 0;

	DMA1_Channel1->CPAR = (uint32_t) &ADC1->DR; 
	DMA1_Channel1->CMAR = (uint32_t) &ADC_Buf;
	DMA1_Channel1->CNDTR = FFT_SIZE*2;

	DMA1_Channel1->CNDTR = 2048;
	DMA1_Channel1->CCR |= DMA_CCR1_MINC | DMA_CCR1_MSIZE_1 | DMA_CCR1_PSIZE_1 | DMA_CCR1_TCIE;
	
	NVIC_EnableIRQ (DMA1_Channel1_IRQn);
  
  	DMA1_Channel1->CCR |= DMA_CCR1_EN;
}

void Init_ADC(void){

	GPIOC->CRL   &= ~GPIO_CRL_MODE5 & ~GPIO_CRL_MODE4;     
	GPIOC->CRL   &= ~GPIO_CRL_CNF5 & ~GPIO_CRL_CNF4;	

	RCC->APB2ENR |=  RCC_APB2ENR_ADC1EN;   
	RCC->CFGR    |=  RCC_CFGR_ADCPRE_DIV8;  

	ADC_DMA_Init();	

	ADC1->SQR3 |= 14;
	ADC1->CR2 &= ~ADC_CR2_EXTSEL;
	ADC1->CR2 = ADC_CR2_EXTSEL_2 | ADC_CR2_ADON | ADC_CR2_EXTTRIG | ADC_CR2_DMA; 
	ADC1->CR1 |= ADC_CR1_DUALMOD_1;

	ADC1->CR2 |= ADC_CR2_CAL;
	while (!(ADC1->CR2 & ADC_CR2_CAL)){};
		
	RCC->APB2ENR |=  RCC_APB2ENR_ADC2EN; 

	ADC2->SQR3 |= 15;
	ADC2->CR2 &= ~ADC_CR2_EXTSEL;
	ADC2->CR2 = ADC_CR2_EXTSEL | ADC_CR2_ADON | ADC_CR2_EXTTRIG;

	ADC2->CR2 |= ADC_CR2_CAL;
	while (!(ADC2->CR2 & ADC_CR2_CAL)){};
		
	/*---------------------ADC Sampling------------------------*/
   RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;     
	 
   TIM3->PSC = 36 - 1; // 100KHz or 0.00001s
   TIM3->ARR  = 36; // period = 18us
   
   TIM3->CR2 |= TIM_CR2_MMS_1; // разрешаем генерацию TRGO

   TIM3->CR1 |= TIM_CR1_CEN; 
}

Вот тебе код который запускает 2 канала АЦП на параллельную работу и складывает данные через DMA в буфер. Работа идет в циклическом режиме, частота выборок задается таймером. По заполнению буфера вызывается прерывание. Разбирайся, открывай даташит и читай, что значит каждая строка кода. Потом перенастраивай под себя.

2 часа назад, strifonoff сказал:

не было сказано, что нужно включать глобальные прерывания.

Потому что когда человек дошел до DMA и т.п., про прерывания он уже знает.

Ссылка на комментарий
Поделиться на другие сайты

Железки самой к меня пока нет, поэтому приходится доверять симулятору IAR.

Но в нём прерывания не срабатывают. Выкинул вообще всё, оставил тупо:

#include "stm32f10x.h"
#include "stm32f10x_conf.h"

unsigned char _timer;
void TIM4_Init(void);

int main()
{
  _timer = 0;
  SystemInit();
  TIM4_Init();
  while(1){}
}

void TIM4_Init(void)
{
  TIM_TimeBaseInitTypeDef TIMER_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

  TIM_TimeBaseStructInit(&TIMER_InitStructure);
  TIMER_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIMER_InitStructure.TIM_Prescaler = 8000;
  TIMER_InitStructure.TIM_Period = 500;
  TIM_TimeBaseInit(TIM4, &TIMER_InitStructure);
  TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
  TIM_Cmd(TIM4, ENABLE);

  NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

void TIM4_IRQHandler(void)
{
  if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
    {
      _timer = (250-_timer) ? _timer+1 : 0;
      TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
    }
}

И нет прерываний... Это глюки самого IAR или что?

Изменено пользователем strifonoff
Ссылка на комментарий
Поделиться на другие сайты

49 минут назад, strifonoff сказал:

приходится доверять симулятору IAR

Напрасно.

 

51 минуту назад, strifonoff сказал:

Выкинул вообще всё, оставил тупо:

Вот именно, что тупо. Разрешения прерываний так и нет. И я же уже говорил, избавься от этих либ и используй только CMSIS. То, что пишется одной строкой, ты растянул на простыню кода. Вот вся настройка таймера:

RCC->APB1ENR |= RCC_APB1ENR_TIM8EN;    

TIM4->PSC = 36000-1;         
TIM4->ARR = 500; // 250ms
TIM4->DIER |= TIM_DIER_UIE;   
TIM4->CR1 |= TIM_CR1_CEN;

NVIC_EnableIRQ(TIM4_IRQn);

И обработчик прерывания:

void TIM4_IRQHandler(void){
  if(TIM4->SR & TIM_SR_UIF){
    TIM4->SR &= ~TIM_SR_UIF;
    
    
  }
}

Ну и разрешение прерываний:

__enable_irq();

 

Ссылка на комментарий
Поделиться на другие сайты

Вопрос по АЦП.
Если у меня цепочка из 5-ти АЦП каналов (регистры SQR1..3), каждый тратит 14 циклов на преобразование, это получается, что, например, 1-ый канал будет измеряться не каждые 14 циклов как мне надо, а 14*5?

Ссылка на комментарий
Поделиться на другие сайты

34 минуты назад, strifonoff сказал:

а 14*5?

Вообще то еще больше. 14 тактов - это чистое преобразование. Еще нужно время на захват сигнала. Конденсатор УВХ не может зарядиться мгновенно.

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

Ну, т.е., я оказался прав. И если нужна максимальная частота измерений, нужен только один канал.

Придется в перерывах между измерениями переключать АЦП на другой канал..

 

Ссылка на комментарий
Поделиться на другие сайты

У F103 два независимых АЦП, которые могут работать параллельно. А это уже два канала. У 303 серии 4 независимых АЦП.

 

24.09.2020 в 13:00, strifonoff сказал:

максимально быстро опросить вход

Нет такой физической величины. Что за сигнал на входе и каковы его параметры? Так то у 103 минимальное время преобразования 1мкс  Правда, не на максимальной частоте ядра. На максимальной 1,17мкс. Т.е., даже теоретически нельзя захватить без потерь частоту выше 500КГц. В реальности еще меньше.

Ссылка на комментарий
Поделиться на другие сайты

мне нужно получить реакцию объекта на меандр 40 кГц. чем больше будет частота дискретизации, тем лучше.

про ADC2 я что-то и забыл, но уже вспомнил.

Ссылка на комментарий
Поделиться на другие сайты

Вот тот код, что я давал, как раз таки и запускает два АЦП на параллельную работу. Результат складывается в массив 32-битных чисел, где старшие 16 бит один АЦП, младшая - другой. Убери запуск от таймера и будет максимальная частота преобразования.

Ссылка на комментарий
Поделиться на другие сайты

Да, спасибо. Вот только я не понял зачем там таймер? ДМА сам же должен перекладывать из перефирии в память или нет, зачем там таймер?
 

Ссылка на комментарий
Поделиться на другие сайты

3 минуты назад, strifonoff сказал:

зачем там таймер?

Это выборки для БПФ и идти они должны на известной частоте дискретизации. В данном случае это чуть больше 50КГц.

Ссылка на комментарий
Поделиться на другие сайты

Т.е. получается так:
АЦП работает и записывает результат в ADC1->DR, DMA это контролирует и перекидывает в мой массив, как только перекинул заданное количество - срабатывает прерывание? И таймер тут не нужен?

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
  • Сообщения

    • Все предложенные к рассмотрению источники питания работают примерно по одному принципу: сетевое напряжение выпрямляется, фильтруется (получаем чуть больше 300 вольт постоянного), затем преобразуется снова в переменное, но уже на частотах в несколько десятков килогерц, понижается на трансформаторе и снова выпрямляется. За счёт высокой частоты преобразования используется трансформатор на ферритовом, а не на стальном, сердечнике, гораздо меньших габаритов и стоимости. Минусы: значительное усложнение схемы блока и вероятность возникновения различных помех от него. Модули управления (кроме первого) также являются импульными преобразователями, с теми же достоинствами и недостатками. Если нужно по быстрому собрать некое подобие ЛБП, то уж лучше брать модуль вроде этого. Ну и блок питания к нему соответствующий. Но не очень понятно, какой практический опыт можно получить от соединения готовых модулей парой проводов.  
    • У меня больше всего вопросов вызвала необычная схема обеспечения отрицательного питания. Автор этой обстоятельной заметки пишет: For this supply to work correctly, the transformer must have a secondary voltage of at least 18V RMS.  Почему? Что будет не так с отрицательным питанием, если напряжение на трансформаторе будет меньше 18В?   https://tinyurl.com/23mlwxtt - я в простейшей эмуляции ставлю 12В пикового напряжения для трансформатора и на стабилитроне все как положено: -5.6В.
    • Согласен, очень криво объяснил. Это работа трёх вольтовой линии, просто на диод шотки сдвоенный, на один анод приходит сигнал напрямую с трансформатора, а на второй через дроссель. Вольт/деление 5 вольт в клетке, тайминг по моему 10 МС. Третья фотография это сигнал на катодах уровень земли ровно по центру экрана. Но все линии по итогу в порядке 3.3 в, 5, в, 12 в и -12 в. Нагрузить все линии не могу сразу ,так как тут же выгорают транзисторы (имеется нагрузка 250 ватт по 10 ампер на каждую линию за исключением-12в), поэтому нагружаю 3.3 вольтовую линию на 10 ампер,  подключаю переменный резистор 50 ватт на 15 ом на 5 вольтовую линию и постепенно довожу до той той картины с перекосом (это гдето  50 ватт общее). По поводу микросхемы, вверху имеется скрин где между импульсами проскакивает мини импульс, если так можно сказать, он проскакивает и на одной  и на второй ноге (7,8). Микросхема не tl 494, а lw4933/abx942.1/c9421646. Далее они приходят на базы транзисторов 945g  коллекторы этих транзисторов соединены с  выводами трансформатора. Просто схема типовая, легче мне кажется просто привести фото самого блока, для тех кто разбирается будет гораздо информативне.  Диод шотки по 12 вольтовой линии был подгоревший, заменил на донора. Приводить скрины не буду что бы не захламлять тему. В итоге, пока все так же, при достижении определенной нагрузки суммарно где-то 50 ватт, появляется этот "выброс и перекос". По этому имеются мысли на два варианта, это микросхема , этот мини импульс между периодами, на низкой нагрузке особо не влияет, но при достижении определенной приводит с самовозбуждению входной цепи и непроизвольному открытию транзистора нижнего плеча. Либо дело в "горячей части", плавающий дефект в обвязке силовых ключей.  Спасибо за ответ.
    • @Gomerchik а вы контролировали как меняется уровень сигнала на А1 ардуины?
    • Спасибо за совет. Автором данного проекта я не являюсь, мне нужно было воссоздать уличный датчик для метеостанции взамен пропавшего(( Из разного найденного в интернете этот проект работает с моей станцией Орегон (спасибо автору). В понедельник попробую последовать Вашему совету. Но все равно куча непоняток  как блин это работает)) Если дело в неправильной отправки команды, то как на это влияет подключение датчика температуры? Если совсем не подключать таймер, то передача идет один раз (как и прописано в программе), станция принимает и отображает, но минут через сколько-то естественно станция уже ни чего не показывает, но с таймером питание полностью не пропадает с ардуинки, но передача сигнала каким-то образом работает по таймеру.  В моем понимании данная команда подается один раз потому, что таймер должен отключать питание МК после передачи сигнала и каждые 43 сек снова подавать питание (так того требует станция).  Ардуино передает показания температуры отключается полностью и 43 секунды мк не работает.  Сейчас у меня питание пока сделано на подпитке от солнечной батареи, но пару пасмурных дней и аккумулятор съедается до отключения(
    • thickman Так и сделаю. Вытащу из бу БП.  Буду знать, как отличить. Благодарю. Заменил транзисторы на IRFB20N50K. Картина стала, совсем другой.  Похоже трудность не в драйвере, на момент подвозбуда, переходные процессы, в нем, завершены. Увеличил затворные резисторы до 50ом, стало немного лучше.  Не понятно, почему верхний ключ греется несколько сильнее. Возможно, стоит посмотреть ток в коллекторе.  Снабберные емкости временно удалил, изменений не произошло.  Замена ТГР на другой, на кольце MSTN-16A-TH, так же, результата не принесла.   irfb20n50k.pdf
×
×
  • Создать...