|
|
  |
STM32F4, Input capture, нет захвата сигнала |
|
|
|
Aug 23 2012, 08:01
|

Знающий
   
Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121

|
допустим на вход PA0 подается пульс шириной 1.5мс, и повторяется каждые 15мс. но ширина пульса конечно может менятся, и ее я хочу измерять. я сконфигурировал порт PA0 как входной захват, а на него подаю пульс который генерируется пином PB4, с PB4 поступает пульс описанный выше, это я проверил. но на входе па0 почемуто не могу захватить сигнал, т.е. не считает счетчик. полярность входного сигнала высокая стоит, как и по умолчанию, по идее настроив его на вход, проставив значение фильтра, и включив он уже должен работать, и я должен суметь считать значение счетчика равное времени входного пульса с TIM2_CCR1, но почемуто читается только 0. вот код настройки: Код // configure TIM2_CH1 for input capture //////////////////////////////////
TIM2->CCMR1 |= TIM_CCMR1_CC1S_0 | // set TIM2_CH1 for input mode TIM_CCMR1_IC1F_1; // set the input filter to 4 samples
// select edge of the active transition
//enable input capture TIM2->CCER |= TIM_CCER_CC1E;
while (1) { //cnt = TIM3->CNT; capture = TIM2->CCR1;
} что еще я мог упустить?
--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
|
|
|
|
|
Aug 23 2012, 08:12
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(BlackOps @ Aug 23 2012, 12:01)  с TIM2_CCR1, но почемуто читается только 0. Дык таймер-то никто не запустил. Вообще в STM32F очень навороченные таймеры: легко делается анти-ШИМ (на двух каналах, которые подключаются к одному пину) - в одном из каналов будет период, а в другом - длительность импульса. Суть такова: - по фронту импульса таймер сбрасывается и генерится прерывание, но предварительно сохраняется текущее значение таймера в первый (не путать с CCR1) регистр захвата; - по спаду импульса копируется текущее значение таймера во второй регистр захвата; - в прерывании имеем период и длительность импульса; - можно настроить прерывание по переполнению и иметь информацию об отсутствии импульсов. Например, так: Код //------------------------------------------------------------- // init_TIMER2(void) //------------------------------------------------------------- // Инициализация таймера 2 захват параметров ШИМ-сигнала на // линии 2 //------------------------------------------------------------- void __inline init_TIMER2(void) { TIM2->CR1=0; // счетчик выключен TIM2->PSC=720; // максимальное разрешение
TIM2->CCMR1= (2<<TIM_CCMR1_CC1S) |(1<<TIM_CCMR1_CC2S);
TIM2->CCER= (1<<TIM_CCER_CC1E) |(1<<TIM_CCER_CC1P) |(1<<TIM_CCER_CC2E) |(0<<TIM_CCER_CC2P);
TIM2->SMCR= (4<<TIM_SMCR_SMS) |(6<<TIM_SMCR_TS);
TIM2->DIER=6;
TIM2->CR1=1;
} //------------------------------------------------------------- // void TIM2_IRQHandler(void) //------------------------------------------------------------- // Прерывание от T2 //------------------------------------------------------------- void TIM2_IRQHandler() { if(TIM2->SR&2) { ir_pulse=TIM2->CCR1;
} if(TIM2->SR&4) { ir_period=TIM2->CCR2; ir_get(ir_pulse,ir_period); } TIM2->SR=0; }
|
|
|
|
|
Aug 23 2012, 10:22
|

Знающий
   
Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121

|
для начала тогда решил сделать как Вашем примере, вот такой же код: Код // enable TIM3 clock RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
TIM2->CR1 = 0; TIM2->PSC = 720;
TIM2->CCMR1 |= TIM_CCMR1_CC1S_1 | TIM_CCMR1_CC2S_0;
TIM2->CCER |= TIM_CCER_CC1E | TIM_CCER_CC1P | TIM_CCER_CC2E;
TIM2->SMCR |= TIM_SMCR_TS_2 | TIM_SMCR_TS_1 | TIM_SMCR_SMS_2;
TIM2->DIER |= TIM_DIER_CC1IE | TIM_DIER_CC2IE;
TIM2->CR1 |= TIM_CR1_CEN;
while (1) {
} вот функция прерывания: Код void TIM2_IRQHandler() { uint32_t ir_pulse = 0, ir_period = 0;
if(TIM2->SR&2) // breakpoint here * { ir_pulse=TIM2->CCR1;
} if(TIM2->SR&4) { ir_period=TIM2->CCR2; // ir_get(ir_pulse,ir_period); } TIM2->SR=0; } а вот настройка порта: Код //============================================================================= // GPIOA configuration //=============================================================================
// enable GPIOA clock RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
// Alternate Function GPIOA->MODER |= (GPIO_MODER_MODER0_1 | // AF, TIM2_CH1 GPIO_MODER_MODER1_1 // AF, TIM2_CH2 );
// Output type GPIOA->OTYPER |= 0; // push-pull if 0
// Speed type GPIOA->OSPEEDR |= (GPIO_OSPEEDER_OSPEEDR0_1 | // TIM2_CH1, 50MHz GPIO_OSPEEDER_OSPEEDR1_1 // TIM2_CH2, 50MHz );
// Push/Pull GPIOA->PUPDR |= ( GPIO_PUPDR_PUPDR0_0 | // Pull-Up, TIM2_CH1, GPIO_PUPDR_PUPDR1_0 // Pull-Up, TIM2_CH2, );
// Alternate Function pins GPIOA->AFR[0] |= ((1 << ((0 - 0) << 2)) | // TIM2_CH1, AF1 (1 << ((1 - 0) << 2)) // TIM2_CH2, AF1 ); подключил к ножке PA1 пульс (1.5мс ширина, период 15мс), поставил брейкпоинт внутри функции прерывания, и оно не происходит. что там еще может быть? и еще вопрос, как именно понимать это максимальное разрешение? т.е. это количество клоков которое учавствует в сэмплингер входного сигнала? на Рис. 133, стр. 373 Мануала, устанавливая PSC=720 мы контролируем CK_INT который на входе мультиплексора? или как?
--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
|
|
|
|
|
Aug 23 2012, 10:40
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(BlackOps @ Aug 23 2012, 14:22)  подключил к ножке PA1 пульс (1.5мс ширина, период 15мс), поставил брейкпоинт внутри функции прерывания, и оно не происходит. что там еще может быть? и еще вопрос, как именно понимать это максимальное разрешение? т.е. это количество клоков которое учавствует в сэмплингер входного сигнала? на Рис. 133, стр. 373 Мануала, устанавливая PSC=720 мы контролируем CK_INT который на входе мультиплексора? или как? Не вижу настройки NVIC. "Максимальное разрешение" - множитель задающий масштаб в регистрах захвата. В примере при тактовой 72МГц, получается масштаб "единица на 10мкс".
|
|
|
|
|
Aug 24 2012, 07:58
|

Знающий
   
Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121

|
да, NVIC не настроил. Но тем не менее, прежде чем активировать прерывания, я решил подправить немного код, и посмотреть работает ли захват вообще, подправил только PSC = 840, чтобы получить 1 счет в 10мкс. Затем тот код что в прерывании запихнул в непрерывный цикл, и вижу в дебаггере: ширина пульса = 149 период = 1498 ну а т.к. шаг = 10мкс, то 149*10мкс ~ 1.5мс, и 1298*10мкс ~ 15мс, т.е. измерил правильно. Ну а вот теперь убедившись что захват уже работает, решил проверить прерывание, вписываю одну строку только: Код // enable TIM2 interrupt NVIC->ISER[0] |= 1 << TIM2_IRQn; и возобновляю предыдущий код в обработчике прерывания, в дебаггере вижу что прерывание действительно происходит, однако значения ширины пульса и периода абсолютно неверные, слишком большие, вот они: ir_pulse = 4294967295 ir_period = 4294967295 не могу понять почему так? пробовал объявлять эти переменные в других местах кода итд, тоже самое почти что. почему в обработчике прерывания не могу считать верные значения, как я это делал в беспрерывном цикле без прерываний?
--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
|
|
|
|
|
Aug 26 2012, 02:38
|

Знающий
   
Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121

|
не помогает чтото, пробовал также с/без статика, тоже самое, неверные значения. вот мой код обработчика прерывания: Код void TIM2_IRQHandler() { volatile static uint32_t ir_pulse = 0, ir_period = 0;
if(TIM2->SR&2) { ir_pulse=TIM2->CCR1; } if(TIM2->SR&4) { ir_period=TIM2->CCR2; // ir_get(ir_pulse,ir_period); } TIM2->SR=0; } пробовал эти переменные вообще глобально объявлять, изменять их в обработчике, а потом в основной функции из них читать в другие переменные, тоже самое, получаю нереальные испорченные значения. что еще может быть не так? можно на ваш ir_get посмотреть? хочу увидеть как вы сохраняете данные и где именно объявляете переменные?
--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
|
|
|
|
|
Aug 26 2012, 08:38
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(BlackOps @ Aug 26 2012, 06:38)  пробовал эти переменные вообще глобально объявлять, изменять их в обработчике, а потом в основной функции из них читать в другие переменные, тоже самое, получаю нереальные испорченные значения. что еще может быть не так? можно на ваш ir_get посмотреть? хочу увидеть как вы сохраняете данные и где именно объявляете переменные? переменные объявлены так: Код volatile int ir_pulse; volatile int ir_period; В ir_get нет ничего специфичного. Переменные у Вас равны 0xFFFFFFFF. Правильно ли Вы смотрите их отладчиком? Дошагиваете отладчиком до места присваивания из регистров? В каждом ли прерывании переменные равны 0xFFFFFFFF (в первом, в последующих)?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|