Проблема с измерением очень коротких импульсов

Концзакп
Пт 21 апреля 2017 г., 18:14
Ребята,

У меня есть проблема, как в предмете. У меня есть эта функция на одном Maple Mini:
#include // -----------------gps TinyGPSPlus gps; #define ss3 Serial3 static const uint32_t GPSBaud = 9600; // -----------------gps void setup() { Serial.begin(9600); ss3.begin(GPSBaud); } uint32_t time; void loop() { if ( (millis()-time)<1000 ) { if (ss3.available()) gps.encode(ss3.read()); } time = millis(); Serial.println("TEST"); Serial.println(gps.location.lat(),6); Serial.println("_____"); }

Стивестронг
Пт 21 апреля 2017 г., 19:08
Я бы пошел с AttactInterrupt ().
Некоторые подсказки:
- Сделайте ISR как можно более коротким - время выполнения ISR должно составлять менее 10 микросекунд, так как ваш самый короткий импульс составляет 12 микросекунд в длину
- Отключите прерывание Systick, в противном случае он заблокирует некоторые IRQ ваших импульсов.
С другой стороны, если вы отключите Systick IRQ, вы не сможете вызовать функции, связанные с задержкой...
Хм

Концзакп
SAT 22 апреля 2017 г. 12:11
Это полный код для моего отправителя (на этот раз я использовал Arduino для тестирования, но это действительно не имеет значения):
#include

Даниэфф
SAT 22 апреля 2017 12:54
Я попробовал ваш код (Maple Mini -> Общий F103), и я получаю около 61 импульса, здесь после 2 передач (кроме void loop () {Delay (1000); Calldomofon (61, 0);} в отправителе):
#include

Пито
Сб 22 апреля 2017 г. 14:58
Ваш сериал буферирован, таким образом, когда вы делаете сериал.Print ("Hello World"), а затем немедленно проведя измерение, на измерение может повлиять серийную отправку данных. Итак, после сериала.print () немного подождите, т.е. 10 мс (если применимо, я не точно знаю, чего вы хотите достичь - чтобы измерить длину каждого импульса или период, или вы хотите подсчитать импульсы), пока сериал не отправит данные, а затем запустите измерение, когда буфер с сериалом будет пустой.
Также не возражают, есть другой процесс, работающий на заднем плане.
Если бы я был тобой, я бы установил прерывание на растущем краю - я получу 1 прерывание за импульс, тогда..

ZMEMW16
Сб 22 апреля 2017 г., 21:08
В ISR сначала тест на наиболее распространенное состояние. я.эн. Предположим, что часы уже работают.эн. timer_start не равен нулю.
Инициализация его до нуля будет происходить только один раз.
Стивен

Концзакп
Солнце 23 апреля 2017 г. 10:23
Вот чего я хочу достичь. У меня есть телефон / вход в мою квартиру, с которой я хочу интегрировать. Он отправляет импульсы, как отправитель в моем примере. Сначала он отправляет сигнал сброса и после этого плоского числа (61 импульсы для плоского нет. 61) и после этого начинается звонить (последовательность более длинных и более коротких импульсов). Мне нужно сначала подсчитать, если звонок в точности для моей квартиры, и после этого, если Intercom звонит или нет, или, может быть, он просто дает сигнал, который кто -то использовал код для входа в здание. Поэтому мне нужно посчитать импульсы и их ширину каждый раз, чтобы знать, когда он отправляет плоское число, а когда он звонит и т. Д.

Стивестронг
Солнце 23 апреля 2017 г. 10:50 утра
Вам нужны как высокие, так и низкие периоды? Или просто высокий период? Или всего лишь общий период?

Концзакп
Солнце 23 апреля 2017 г., 17:10
Я думаю, мне понадобится оба. Мне нужно декодировать последовательность для всего звонка. Сначала сбросить, затем плоский номер, затем введено код или код и повесить трубку. Самое главное, чтобы узнать, когда началась и закончена фиксированная численная последовательность, и это отмечено более длительным периодом в начале и в конце.

Пито
Солнце 23 апреля 2017 г., 17:57
Использует ли кольцо период пульса?
Только периоды измерения могут быть проще..

ZMEMW16
Солнце 23 апреля 2017 г., 19:23
Любой другой, который видит файл LEX для синтаксиса последовательности импульсов, включая начало в середине такого?
Стивен

Ddrown
Пн 24 апреля 2017 г. 3:36 утра
Один из способов сделать это - использовать только штифт мисо из порта SPI:
#define ss3 Serial2

Концзакп
Пн 24 апреля 2017 г. 20:13
Что -то странное происходит. Я копию ваш пример, и я не знаю, почему я получаю другой вывод, чем ваш:/ Можете ли вы вставить код передатчика ?
#define ss3 Serial2

victor_pv
Пн 24 апреля 2017 г. 20:37
Я думаю, что вам следует использовать режим захвата ввода таймера для этого.

Концзакп
Вт 25 апреля 2017 г. 8:22
victor_pv написал:Я думаю, что вам следует использовать режим захвата ввода таймера для этого.

victor_pv
Вт 25 апреля 2017 г. 14:24
Концзакп написал:victor_pv написал:Я думаю, что вам следует использовать режим захвата ввода таймера для этого.

Концзакп
Ср 26 апреля 2017 г. 12:25
[РЕДАКТИРОВАТЬ]: Я исправил данный набросок. Теперь он работает и подсчитывает время между 2 растущими краями

Вот что я сделал:

Под -> Stm32f1 \ cores \ maple \ libmaple -> в таймере.в

после функции -> static void output_compare_mode (timer_dev *dev, uint8 канал);
Я добавил: uint32_t time; void loop() { if ( (millis()-time)<1000 ) { if (ss3.available()) { char c = ss3.read(); Serial.write(c); // monitor the data from GPS on PC gps.encode(c); } } time = millis(); Serial.println("TEST"); Serial.println(gps.location.lat(),6); Serial.println("_____"); }

victor_pv
Ср 26 апреля 2017 г. 18:58
Концзакп написал:Вот что я сделал:

Под -> Stm32f1 \ cores \ maple \ libmaple -> в таймере.в

после функции -> static void output_compare_mode (timer_dev *dev, uint8 канал);
Я добавил: 1TEST 0.000000 _____ 9TEST 0.000000 _____ PTEST 0.000000 _____ .TEST 0.000000 _____ 1TEST 0.000000 _____ 9TEST 0.000000 _____ STEST 0.000000 _____ 2TEST 0.000000

Концзакп
Чт 27 апреля 2017 12:49
Я получил эту работу. Я исправил свой предыдущий пост в рабочее пример. Теперь я должен выяснить, как изменить полярность между количествами, чтобы измерить одну длину импульса. Теперь он стреляет на восходящем краю, и мне нужно падать :)

Стивестронг
Чт 27 апреля 2017 г. 13:40
Вы проверили режим ввода ШИМ (глава 14.3.7 из RM0008)? Он специально разработан для измерения высоких и общих периодов.
Несколько таймеров могут быть каскадированы в течение периодов времени дольше ~ 65.5 мс.

victor_pv
Чт 27 апреля 2017 г., 17:47
Концзакп написал:Я получил эту работу. Я исправил свой предыдущий пост в рабочее пример. Теперь я должен выяснить, как изменить полярность между количествами, чтобы измерить одну длину импульса. Теперь он стреляет на восходящем краю, и мне нужно падать :)

Концзакп
Вт 20 июня 2017 г. 10:24
Прошло много времени с момента моего последнего поста, потому что меня отвлекали другие вещи, но это не значит, что мне не нужно больше помощи :) Вот чего я достиг до сих пор. Я стараюсь с режимом ввода ШИМ, как предложил Стевестронг. Я пытаюсь настроить все, как в примере ввода ШИМ в начале, чтобы измерить короткие импульсы (следующим шагом будут длинные импульсы). Но все еще не может получить хороший результат измерения.

Вот мой код для получения измерений с объяснением, как я пытаюсь установить необходимые регистры (в конце кода).
void loop() { if (ss3.available()) { char c = ss3.read(); Serial.write(c); // monitor only the data from GPS on PC } }

Стивестронг
Вт 20 июня 2017 г. 11:33
Вы пытались искать в Интернете "STM32F103 PWM -режим ввода"?
Первый результат: https: // github.com/bjornfor/stm32-test/ ... /Pwm_input
Это пример на основе HAL (не либмапл), но он содержит необходимые настройки регистра и поток.

Концзакп
Вт 20 июня 2017 г., 17:35
Да, я видел несколько примеров, но они не приближают меня, чтобы решить мою проблему, и это потому, что у меня недостаточно знаний. Я не могу найти, например, где определение, подобное TIM_ICPSC_DIV1 или TIM_ICPolarity_Rising. В Libmaple-Core также нет определения, как в примере. Итак, я начал с изменения реестра, как это: Timer2->регс.генерал->CCMR2 = 0B0; Если вы сможете помочь мне понять эту штуку, то, возможно, я смогу сделать это в среде Arduino.

Стивестронг
Вт 20 июня 2017 г., 19:09
[Концзакп - Вт 20 июня 2017 г., 17:35] - Если вы сможете помочь мне понять эту штуку, то, возможно, я смогу сделать это в среде Arduino.
Извините, я не могу, поэтому я все еще придерживаюсь кода Libmaple :?
Но прямое настройка регистра неплохо, просто что вы должны знать, что вы делаете 8-)

Концзакп
Ср 21 июня 2017 г. 9:56 утра
Это нормально. Может быть

Олли
Чт 22 июня 2017 г. 10:33
Самый простой способ - использовать постоянный счетчик отладки. Это дает время в разрешении часов, например, 72 МГц. Вам нужно сначала включить счетчик, затем прочитать счет в начале, а затем в конце.

Концзакп
Чт 22 июня 2017 г. 14:01
Вы можете показать, как это сделать ?
Я нашел что -то подобное, но я не знаю, правильно ли это для Arduino Ide static const uint32_t GPSBaud = 4800;

Стивестронг
Чт 22 июня 2017 14:14
Я предполагаю, что вы уже прочитали оригинальные документы Libmaple о том, как использовать таймеры:
http: // docs.Leaflabs.com/static.Leaflab ... Дваретимер

Концзакп
Чт 22 июня 2017 г. 15:29
Да, у меня есть. Но я ничего не вижу там, что мог бы использовать в своем случае. Нет реализации ввода входного ввода PWM или этого счетчика отладки. Вы указали на документацию из -за какого -то конкретного элемента?

РЕДАКТИРОВАТЬ: Мой пример счетчика отладки как -то работает (он что -то измеряет), так что теперь я постараюсь заставить его работать с захватом ввода

Концзакп
Солнце 25 июня 2017 г. 18:26
Я сделал это! :) Сначала некоторое заключение после прочтения документации и экспериментов. Теперь я могу установить каждый режим с настройками реестра. Я не смог получить режим ввода PWM, работающий правильно для моего сценария. Это не дало мне надлежащие измерения, несмотря на правильные настройки реестра. Обычно это используется для других вещей. Я также не смог сбросить счетчик, потому что для этого вы должны установить Timx_SMCR, который имеет настройки только для повышения края, и в моем сценарии мне нужно обнаружить падение и измерить его, потому что нормальное состояние в моем случае высокое, а импульсы отправляются добраться до низкого. Итак, лучший способ для меня - установить входной режим и менять обнаружение краев каждый раз, когда было поднято прерывание. При измерении лишь нескольких импульсов реестр CCR1 полезен для измерения разницы между краями. Таким образом, Prescaler может быть использован (до 65536), например,. 72, чтобы получить Micro SEC и TIMX_ARR можно установить на желаемый номер, после чего счетчик переполнен и начинается с 0. Но когда есть много коротких импульсов один за другим, как в моем случае лучше использовать счетчик отладки. Это более точное, а ошибка измерения- только +/- 1US! Я также обнаружил, что счетчик с отладанием чтения быстрее, чем чтение CCR1. Счетчик отладки также может быть обнужден, что очень полезно. Также очень важно сохранить код прерывания как можно более коротким. Это влияет на время, поэтому, если мы хотим измерить очень короткие импульсы, он должен быть очень коротким и быстрым. Очень интересно, что использовать строку быстрее, чем int. Я имею в виду, когда я использовал какое -то число, которое было увеличено (x ++), потребовалось больше времени, чтобы увеличить его, чтобы добавить значение измерения в строку (out+=). Когда я попытался с увеличением числа, тогда я не смог поймать каждый импульс, поэтому я решил попробовать по строке и оставил все вычисления для цикла. Я всегда думал, что увеличение быстрее. Теперь я могу измерить от 2уса до 10 мс!!!. Это очень хороший результат, я думаю. Для меня этого достаточно, но в некоторых случаях также может быть установлен бит CCXG в реестре TIMX_EGR для создания другого прерывания (в обновлении: переполнение счетчика/нижняя часть, инициализация счетчика) или синхронизацию таймера (Глава 15.3.15) Можно сделать (например, для запуска второго счетчика или считать с разным значением). Я не проверял это, потому что мне это не нужно. Также я не мог найти в документах, как проверить переполнение счетчика. Я надеялся прочитать какой -то реестр, в котором хранится количество переполнений, а затем сравнить их в начале и в конце. Но, к сожалению, я не смог найти его, и было бы очень полезно измерять импульсы дольше 10 мс. Если кто -то захочет измерить подобные импульсы, то вот мой код (с дополнительной информацией внутри) void loop() { if (ss3.available()) { char c = ss3.read(); Serial.write(c); // monitor only the data from GPS on PC } }

Неровная