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

Здравствуйте всем. Пытаю входной захват. Делаю по прерыванию. На вход подаю свой же ШИМ. Как сделать одиночное считывание? Или это делается не по прерыванию?

Поделиться сообщением


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

И что то как то пляшет значение. младшие 2 цифры от 40 до 80 пляшет. А так значение 2780. Давно, как то на Атмеге16 делал захват. Там как то все понятно было. Вроде 4 буферных регистра. Считывал , вычитал . Все очень точно работало. Я даже сдвиг фазы резольвера считывал на нем с точностью 1000 имп. на оборот.

Поделиться сообщением


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

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

Здравствуйте всем. Пытаю входной захват. Делаю по прерыванию. На вход подаю свой же ШИМ. Как сделать одиночное считывание? Или это делается не по прерыванию?

Код в студию! Нужно настроить по какому фронту будет захват и в прерывании (или в DMA) вычитывать захваченное значение. Можно сделать сброс счетчика по обратному фронту. Если источник сам МК, то захват в принципе будет такт в такт.

 

Поделиться сообщением


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

У меня по переднему краю. Я сбрасываю счетчик в прерывании. Но не по заднему фронту. Это надо ввести режим захват по переднему и по заднему фронтам?

void TIM2_IRQHandler(void)
{
  /* USER CODE BEGIN TIM2_IRQn 0 */
	static uint16_t count;
	static uint8_t sw;

	if(LL_TIM_IsActiveFlag_CC4(TIM2)) {
		//LL_TIM_DisableIT_TRIG(TIM2);
		//LL_TIM_ClearFlag_UPDATE(TIM2);
		LL_TIM_ClearFlag_CC4OVR(TIM2);
		LL_TIM_ClearFlag_CC4(TIM2);
		Meas4 = LL_TIM_IC_GetCaptureCH4(TIM2);
		LL_TIM_SetCounter(TIM2, 0);

		if(++count > 1000) {
			count = 0;
			OUT_PC13(sw = !sw);
		}
	}

Это прерывание.

И еще. Если частоту увеличиваю , то в какой то момент он просто не успевает. Поэтому хотел, чтобы считал значение потом запустил.  

Я почему то понял, что прерывание происходит по 2 фронту. Т.е. первый фронт начинается отчет, второй фронт фиксируется регистр значения и происходит прерывание.

Поделиться сообщением


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

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

Я почему то понял, что прерывание происходит по 2 фронту. Т.е. первый фронт начинается отчет, второй фронт фиксируется регистр значения и происходит прерывание.

Обычно по фронту он только копирует текущее значение счетчика в регистр захвата.

Но можно определить слейв-режим, в котором, например, обнулять текущее значение по фронту (см. регистр SMCR, биты SMS и TS )

Поделиться сообщением


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

13.02.2022 в 02:04, adnega сказал:

Обычно по фронту он только копирует текущее значение счетчика в регистр захвата.

Но можно определить слейв-режим, в котором, например, обнулять текущее значение по фронту (см. регистр SMCR, биты SMS и TS )

В общем то работает по прерыванию. Хочу попробовать с DMA. С прерываниями я так и не понял, можно ли одиночный режим сделать. Считал, потом когда надо опять запустил считал и т.д.

Поделиться сообщением


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

С DMA тоже работает. Предделитель счетчика ставлю 72, значит заполнение 1 МГц . На выходе шим настроил на 1 кГц , замерял осциллографом и прибором, точно 1 кГц. Блин, входной захват показывает 984 мксек. Неужели такой большой разброс кварца? ( 

Поделиться сообщением


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

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

Предделитель счетчика ставлю 72, значит заполнение 1 МГц .

Попробуйте 71 поставить ;)

Поделиться сообщением


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

А, ну да, там же надо минус 1 делать.) Я ставил 71, тогда 998-999. Ну, в общем то приемлемо. Спасибо. 

Поделиться сообщением


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

Не знаю как сделать, что бы DMA последовательно считывал в массив (допустим из двух элементов ICbuff[2]) в ICbuff[0] по одному переходу, в ICbuff[1] по следующему. Так он пишет значение счетчика в оба элемента по переходу. 

Поделиться сообщением


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

О, не заметил ответ. Спасибо, сейчас попробую.)

Инкремент мемори я делаю. поэтому он и пишет и в первую ячейку памяти и во вторую. Сразу, по первому фронту сигнала. 

Поделиться сообщением


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

В общем решил эту задачу. Надо в регистре TIMx DMA control register (TIMx_DCR) в DBL[4:0]: DMA burst length длину передачи делать 1. А ставил 2 передачи. Все, теперь период Т равен buff[0] - buff[1]. Так точнее получается нежели если каждый раз сбрасываешь счетчик. Теперь на 1 кГц у меня показывает 1000мкс изредка 999.

Но когда счетчик достигает например 50000, то я его сбрасываю. Чтобы не было перехода.

Поделиться сообщением


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

15 часов назад, khlenar сказал:

Но когда счетчик достигает например 50000, то я его сбрасываю. Чтобы не было перехода.

А зачем? беззнаковая арифметика с этим замечательно справляется ( 2-0xFFFF = 3 - если все переменные размером 16 бит)

Поделиться сообщением


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

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

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

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

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

×
×
  • Создать...