21.08.2012, 10:16
|
|
Гуру портала
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 919
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
|
Re: STM32 измеренние длительности импульса
Можно уровень воды в баке бесконтактным способом измерять.
|
|
|
|
21.08.2012, 11:05
|
|
Почётный гражданин KAZUS.RU
Регистрация: 19.08.2006
Адрес: Львов
Сообщений: 1,616
Сказал спасибо: 65
Сказали Спасибо 315 раз(а) в 264 сообщении(ях)
|
Re: STM32 измеренние длительности импульса
Сообщение от Easyrider83
|
Можно уровень воды в баке бесконтактным способом измерять.
|
Пальцем быстрее...
Глянул краткое описание. У него на выходе готовый импульс, пропорциональный времени от старта передачи до момента приема.
http://www.dealextreme.com/p/hc-sr04...-module-133696
Учить ТС-а применению захвата по таймеру не входит в мои жизненные планы.
__________________
С уважением,
Vic / ut1wpr
|
|
|
|
21.08.2012, 11:53
|
|
Почётный гражданин KAZUS.RU
Регистрация: 06.06.2008
Сообщений: 1,530
Сказал спасибо: 78
Сказали Спасибо 427 раз(а) в 365 сообщении(ях)
|
Re: STM32 измеренние длительности импульса
Сообщение от ut1wpr
|
Потрясен. Вы достигли совершенства и стали ясновидцами!
|
Таки да!
Сообщение от Easyrider83
|
Зачем только - не понятно. У меня пока лежат без дела.
|
Вы же, кажется, хотели создать тему о применении данных датчиков. Они и у меня валяются без дела, не пойму, что же полезное из них можно сделать. Роботы так каковые не интересуют, почти все виденные мною в сети слишком примитивны, бесполезны и требуют внушительных затрат на приводы и механику.
|
|
|
|
21.08.2012, 11:57
|
|
Прописка
Регистрация: 31.08.2008
Сообщений: 117
Сказал спасибо: 4
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
|
Re: STM32 измеренние длительности импульса
Да "тема по" HC-SR04 Ultrasonic Sensor Distance Measuring Module. Хочу сделать на его основе бесконтактный датчик уровня воды в ёмкости. Просто датчик "известный", а темы по его применению нет.
|
|
|
|
25.08.2012, 23:49
|
|
Прописка
Регистрация: 31.08.2008
Сообщений: 117
Сказал спасибо: 4
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
|
Re: STM32 измеренние длительности импульса
Пишу программу, однако упёрся в механизм измерения длительности приходящего импульса. Использую таймер 3 модуль захвата. Имею две процедуры настройки таймера на прерывания по возрастанию и убыванию уровня. Ниже код:
void TIM3_Configuration_Rising(void)
{
/* TIM3 configuration: Input Capture mode ---------------------
The external signal is connected to TIM3 CH2 pin (PA.07)
The Rising edge is used as active edge,
The TIM3 CCR2 is used to compute the frequency value
------------------------------------------------------------ */
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_ICInit(TIM3, &TIM_ICInitStructure);
/* TIM enable counter */
TIM_Cmd(TIM3, ENABLE);
/* Enable the CC2 Interrupt Request */
TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);
}
void TIM3_Configuration_Falling(void)
{
/* TIM3 configuration: Input Capture mode ---------------------
The external signal is connected to TIM3 CH2 pin (PA.07)
The Rising edge is used as active edge,
The TIM3 CCR2 is used to compute the frequency value
------------------------------------------------------------ */
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_ICInit(TIM3, &TIM_ICInitStructure);
/* TIM enable counter */
TIM_Cmd(TIM3, ENABLE);
/* Enable the CC2 Interrupt Request */
TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);
}
Процедура обработки прерывания
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3, TIM_IT_CC2) == SET)
{
/* Clear TIM3 Capture compare interrupt pending bit */
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
if(CaptureNumber == 0)
{
/* Get the Input Capture value */
IC3ReadValue1 = TIM_GetCapture2(TIM3);
CaptureNumber = 1;
TIM3_Configuration_Falling();
}
else if(CaptureNumber == 1)
{
/* Get the Input Capture value */
IC3ReadValue2 = TIM_GetCapture2(TIM3);
/* Capture computation */
if (IC3ReadValue2 › IC3ReadValue1)
{
Capture = (IC3ReadValue2 - IC3ReadValue1);
}
else
{
Capture = ((0xFFFF - IC3ReadValue1) + IC3ReadValue2);
}
/* Frequency computation */
TIM3Freq = (uint32_t) SystemCoreClock / Capture;
CaptureNumber = 0;
TIM3_Configuration_Rising();
}
}
}
Т. е. первый раз вход в прерывание по возростанию уровня.
В прерывании настраиваю таймер на прерывание по спаду уровня.
Вычисляю разницу, т. е. длительность импульса
Восстанавливаю на прерывание по возростанию уровня.
Помогите сделать правильно, а то уж очень коряво получается.
Последний раз редактировалось anton_1000; 25.08.2012 в 23:52.
|
|
|
|
26.08.2012, 00:32
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.08.2010
Адрес: Днепр
Сообщений: 8,565
Сказал спасибо: 5,041
Сказали Спасибо 10,612 раз(а) в 3,604 сообщении(ях)
|
Re: STM32 измеренние длительности импульса
Сообщение от Easyrider83
|
Мы их там тоннами скупали. Зачем только - не понятно. У меня пока лежат без дела.
|
А я покупал парковочные системы для блондинок. В комплект входит четыре ультразвуковых датчика. Их использовал в качестве датчиков расстояния. Высокой точности от них не добьешься, да мне и не требовалось. Надо было оснастить кранбалки в цеху, чтобы они не ударились друг о друга. Расстояние полметра-метр эти датчики спокойно простреливают.
Кстати, уровень воды в баке ультразвуковыми датчиками мерять - неблагодарное занятие. У воды есть нехорошее свойство - при колебаниях температуры покрывать капельками росы поверхность датчика. Это его сильно сбивает с толку, а часто и вообще парализует. Пробовали делать продувку сухим воздухом. Но даже слабый поток воздуха приводит к большим погрешностям измерения расстояния. Да и воздуха сухого не напасешься. Пробовали подогревать датчик, выше температуры росы. Результат положительный, но затраты не стоили того. Кончилось тем, что отказались от него, и поставили датчик давления.
|
|
|
|
26.08.2012, 01:51
|
|
Прописка
Регистрация: 09.02.2011
Сообщений: 164
Сказал спасибо: 1
Сказали Спасибо 27 раз(а) в 22 сообщении(ях)
|
Re: STM32 измеренние длительности импульса
Сообщение от anton_1000
|
Помогите сделать правильно, а то уж очень коряво получается.
|
Используйте gated mode. И лучше для измерения длительности подходит 2й таймер.
|
|
|
|
26.08.2012, 08:30
|
|
Почётный гражданин KAZUS.RU
Регистрация: 19.08.2006
Адрес: Львов
Сообщений: 1,616
Сказал спасибо: 65
Сказали Спасибо 315 раз(а) в 264 сообщении(ях)
|
Re: STM32 измеренние длительности импульса
Сообщение от anton_1000
|
Пишу программу, однако упёрся в механизм измерения длительности приходящего импульса. Использую таймер 3 модуль захвата. Имею две процедуры настройки таймера на прерывания по возрастанию и убыванию уровня.
Помогите сделать правильно, а то уж очень коряво получается.
|
А что такое "правильно? Кто эти правила устанавливал? Если программа, написанная "неправильно" делает все точно так же, как и написанная "правильно", то в чем же разница? Да, и уточните, что значит "коряво". Термин непонятный. "Не работает" или "некрасиво написано" или "буквы скачут"
Можно попробовать так:
Код:
|
void TIM3_IRQHandler(void)
{
static Phase = 0;
if(TIM_GetITStatus(TIM3, TIM_IT_CC2) == SET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
if( !Phase )
{
IC3ReadValue1 = TIM_GetCapture2(TIM3); // Make it volatile
Phase = 1;
TIM3_Configuration_Falling();
}
else if( Phase )
{
IC3ReadValue2 = TIM_GetCapture2(TIM3); // The same
TIM3_Configuration_Rising();
DataReadyFlag = 1;
Phase = 0;
}
}
}
// В теле программы
if( DataReadyFlag )
{
// Все ваши вычисления здесь
DataReadyFlag = 0;
} |
По тексту. Не делайте вычислений в теле обработчика прерываний. В нужной фазе (захват по спаду) поднимайте флаг готовности замеров, а в теле программы по установленному флагу делайте вычисления и сбрасывайте флаг. Надо стремится всегда и во всем обработчики прерываний делать максимально короткими.
Избегайте из обработчиков вызывать внешние функции, пусть даже очень короткие. Неизвестно, сколько дополнительно стека уйдет на ненужное сохранение контента. Да и потери времени на вызовы и возвраты тоже могут быть лишними.
Во избежание неприятностей рекомендуют переменные, модифицируемые в прерываниях, определять с квалификатором volatile. Кто его знает, на каком уровне оптимизации работает ваш компилятор.
ЗЫ Обрамлять коды лучше тегами CODE, чем Italic. Выделять фрагменты лучше тегами Bold, т.к. подчеркивание в тексте путает с ссылкой.
__________________
С уважением,
Vic / ut1wpr
Последний раз редактировалось ut1wpr; 26.08.2012 в 08:35.
|
|
|
|
26.08.2012, 10:09
|
|
Прописка
Регистрация: 31.08.2008
Сообщений: 117
Сказал спасибо: 4
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
|
Re: STM32 измеренние длительности импульса
Можно по подробнее про gated mode. А "коряво" это значит есть такое чувство, что можно написать код более оптимальнее и использовать все возможности "железа". Наверняка создатели СТМ32 продумали механизм измерения длительности импульса. Вот нашёл такое:
Код:
|
void init_timer(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseInitTypeDef timer_base;
TIM_TimeBaseStructInit(&timer_base);
timer_base.TIM_Prescaler = 24000 - 1;
TIM_TimeBaseInit(TIM3, &timer_base);
TIM_ICInitTypeDef timer_ic;
timer_ic.TIM_Channel = TIM_Channel_1;
timer_ic.TIM_ICPolarity = TIM_ICPolarity_Rising;
timer_ic.TIM_ICSelection = TIM_ICSelection_DirectTI;
timer_ic.TIM_ICPrescaler = TIM_ICPSC_DIV1;
timer_ic.TIM_ICFilter = 0;
/* Эта функция настроит канал 1 для захвата периода,
а канал 2 - для захвата заполнения. */
TIM_PWMIConfig(TIM3, &timer_ic);
/* Выбираем источник для триггера: вход 1 (PA6) */
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
/* По событию от триггера счётчик будет сбрасываться. */
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
/* Включаем события от триггера */
TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);
TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE);
TIM_Cmd(TIM3, ENABLE);
NVIC_EnableIRQ(TIM3_IRQn);
}
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);
NVIC_DisableIRQ(TIM3_IRQn);
/* А вот и параметры ШИМ, захваченные с каналов 1 и 2 */
period_capture = TIM_GetCapture1(TIM3);
duty_cycle_capture = TIM_GetCapture2(TIM3);
NVIC_EnableIRQ(TIM3_IRQn);
if (!capture_is_first)
capture_is_ready = 1;
capture_is_first = 0;
if (TIM_GetFlagStatus(TIM3, TIM_FLAG_CC1OF) != RESET)
{
TIM_ClearFlag(TIM3, TIM_FLAG_CC1OF);
// ...
}
}
} |
|
|
|
|
26.08.2012, 13:45
|
|
Почётный гражданин KAZUS.RU
Регистрация: 19.08.2006
Адрес: Львов
Сообщений: 1,616
Сказал спасибо: 65
Сказали Спасибо 315 раз(а) в 264 сообщении(ях)
|
Re: STM32 измеренние длительности импульса
Сообщение от anton_1000
|
Можно по подробнее про gated mode. А "коряво" это значит есть такое чувство, что можно написать код более оптимальнее и использовать все возможности "железа". Наверняка создатели СТМ32 продумали механизм измерения длительности импульса. Вот нашёл такое:
|
Так в чем вопрос? Там же все написано.
__________________
С уважением,
Vic / ut1wpr
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 09:55.
|
|