BlackOps 0 23 августа, 2012 Опубликовано 23 августа, 2012 · Жалоба допустим на вход 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; } что еще я мог упустить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 23 августа, 2012 Опубликовано 23 августа, 2012 · Жалоба с 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; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BlackOps 0 23 августа, 2012 Опубликовано 23 августа, 2012 · Жалоба для начала тогда решил сделать как Вашем примере, вот такой же код: // 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 который на входе мультиплексора? или как? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 23 августа, 2012 Опубликовано 23 августа, 2012 · Жалоба подключил к ножке PA1 пульс (1.5мс ширина, период 15мс), поставил брейкпоинт внутри функции прерывания, и оно не происходит. что там еще может быть? и еще вопрос, как именно понимать это максимальное разрешение? т.е. это количество клоков которое учавствует в сэмплингер входного сигнала? на Рис. 133, стр. 373 Мануала, устанавливая PSC=720 мы контролируем CK_INT который на входе мультиплексора? или как? Не вижу настройки NVIC. "Максимальное разрешение" - множитель задающий масштаб в регистрах захвата. В примере при тактовой 72МГц, получается масштаб "единица на 10мкс". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BlackOps 0 24 августа, 2012 Опубликовано 24 августа, 2012 · Жалоба да, 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 не могу понять почему так? пробовал объявлять эти переменные в других местах кода итд, тоже самое почти что. почему в обработчике прерывания не могу считать верные значения, как я это делал в беспрерывном цикле без прерываний? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 24 августа, 2012 Опубликовано 24 августа, 2012 · Жалоба не могу понять почему так? пробовал объявлять эти переменные в других местах кода итд, тоже самое почти что. почему в обработчике прерывания не могу считать верные значения, как я это делал в беспрерывном цикле без прерываний? Может, "volatile" добавить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BlackOps 0 26 августа, 2012 Опубликовано 26 августа, 2012 · Жалоба не помогает чтото, пробовал также с/без статика, тоже самое, неверные значения. вот мой код обработчика прерывания: 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 посмотреть? хочу увидеть как вы сохраняете данные и где именно объявляете переменные? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 26 августа, 2012 Опубликовано 26 августа, 2012 · Жалоба пробовал эти переменные вообще глобально объявлять, изменять их в обработчике, а потом в основной функции из них читать в другие переменные, тоже самое, получаю нереальные испорченные значения. что еще может быть не так? можно на ваш ir_get посмотреть? хочу увидеть как вы сохраняете данные и где именно объявляете переменные? переменные объявлены так: volatile int ir_pulse; volatile int ir_period; В ir_get нет ничего специфичного. Переменные у Вас равны 0xFFFFFFFF. Правильно ли Вы смотрите их отладчиком? Дошагиваете отладчиком до места присваивания из регистров? В каждом ли прерывании переменные равны 0xFFFFFFFF (в первом, в последующих)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BlackOps 0 7 сентября, 2012 Опубликовано 7 сентября, 2012 · Жалоба забыл тогда ответить. да проблема была в том что не так смотрел отладчиком. когда начал идти пошагово, то смотрю все работает, и переменные принимают значения верно! спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться