реклама на сайте
подробности

 
 
> STM32F429I-DISCO PWM Input Capture Mode
retterberg
сообщение Feb 29 2016, 09:33
Сообщение #1





Группа: Новичок
Сообщений: 3
Регистрация: 29-02-16
Пользователь №: 90 657



STM32F429I-DISCO (STM32F429ZIT6U) + датчик угла наклона. Осциллографом вижу, что при 0 градусов идут импульсы с периодом 1кгц, и шириной около 0,5кгц. При изменении угла наклона, ширина имульса меняется. Используя даташит накидал код, представленный ниже. Занимаюсь с этим микроконтроллером две недели, да и вообще занимаюсь с микроконтроллерами две недели, да и радиоэлектроникой... Ну вы поняли. biggrin.gif
Мне не удается получить ширину импульса в CCR2, лишь его период в CCR1. В CCR2 чаще всего период, иногда проскакивают 0 или 1.
И ещё, почему то не могу обнулить ни один бит регистра SR, соответственно вот эти условия if (TIM2_SR & 2) и if (TIM2_SR & 4) не имеют никакого смысла.
Как же получить в CCR2 ширину импульса?
Очень нужна помощь. Уже хочется выть и биться головой об стену.
Код
#include "define.h" //адреса и значения регистров (не пользуюсь cmsis, hal)

volatile int up;
volatile int down;

void main(void){
  RCC_AHB1ENR |= RCC_AHB1ENR_GPIOA; //GPIOA clocking
  RCC_APB1ENR |= RCC_APB1ENR_TIM2; //TIM2 clocking

  GPIOA_MODER |= GPIOA_MODER_AF_P0; //GPIOA0 alternate function
  GPIOA_AFRL |= GPIOA_AFRL_AF1_P0 //GPIOA0 TIM2_CH1

  TIM2_PSC = 16-1; //Prescaler 16
  
  TIM2_CCMR1 |= TIM2_CCMR1_CC1S_0_1; //Select TI1 active input for TIM2_CCR1
  TIM2_CCER &= ~TIM2_CCER_CC1P &
               ~TIM2_CCER_CC1NP; //TI1FP1 rising edge

  TIM2_CCMR1 |= TIM2_CCMR1_CC2S_1_0; //Select TI1 active input for TIM2_CCR2
  TIM2_CCER |= TIM2_CCER_CC2P &
              ~TIM2_CCER_CC2NP; //TI1FP2 falling edge
  
  TIM2_SMCR |= TIM2_SMCR_TS_1_0_1; //Select TI1FP1 valid trigger input
  TIM2_SMCR |= TIM2_SMCR_SMS_1_0_0; //Reset mode
  
  TIM2_CCER |= TIM2_CCER_CC1E; //Enable the capture CC1            
  TIM2_CCER |= TIM2_CCER_CC2E; //Enable the capture CC2
  
  TIM2_DIER |= TIM2_DIER_CC1IE; //Enable the interrupt CC1
  TIM2_DIER |= TIM2_DIER_CC2IE; //Enable the interrupt CC2

  TIM2_CR1 |= TIM2_CR1_CEN; //Counter enabled
  
  NVIC_ISER0 |= NVIC_ISER0_TIM2; //TIM2 Interrupt
  
  while(1);
}

//обработчик прерывания (startup.c)
void interrupt(void){
        if(TIM2_SR & 2) up=TIM2_CCR1;
        if(TIM2_SR & 4) down=TIM2_CCR2;
        TIM2_SR = 0;
}
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
esaulenka
сообщение Feb 29 2016, 16:44
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Извините, некогда разбираться. Но именно такую задачу решал полгода назад.
С использованием библиотек AHTOXA https://github.com/antongus/stm32tpl получилось примерно так:


Код
typedef STM32::TIM::Timer<STM32::TIM::TIM_3>        tmr;

void Init ()
{
    tmr::EnableClocks ();

// вход - PC7, TIM3_CH2

// частота таймера - 10 кГц
    tmr::TIMx->PSC = CLOCK_APB1_TIM / 10000- 1;
    tmr::TIMx->ARR = 0xFFFF;

    tmr::TIMx->CR1 = TIM_CR1_CKD_1;                            // предделитель на 4 для фильтров

    tmr::Ch2::CCMRx =    tmr::Ch1::CCMR_CCS_IC1_CROSS |        // первый канал - на второй вход
                        tmr::Ch2::CCMR_CCS_IC1 |            // второй канал - туда же
                        tmr::Ch1::CCMR_CCS_FILTER * 15 |    // фильтр - восемь сэмплов на 1/32-й частоты
                        tmr::Ch2::CCMR_CCS_FILTER * 15;        // убирает импульсы короче 57 мкс

    tmr::TIMx->CCER =    tmr::Ch1::CCER_CCxE |                // включаем оба канала
                        tmr::Ch2::CCER_CCxE |
                        tmr::Ch2::CCER_CCxP;                // второй канал - по заднему фронту

    tmr::TIMx->SMCR =    TIM_SMCR_TS_0 * 6 |                    // trigger input - filtered timer input 2
                        TIM_SMCR_SMS_0 * 4;                    // slave mode - reset mode

// прерывание по сбросу таймера
    tmr::UpdateInterrupt::Enable ();
    NVIC_EnableIRQ (tmr_irq);

    tmr::Enable();

}


void IrqProcess ()
{
    tmr::UpdateInterrupt::Clear ();


    int32_t cur_period = tmr::TIMx->CCR2;
    int32_t on_time = tmr::TIMx->CCR1;

    int32_t off_time = cur_period - on_time;

    // тут был кусочек пред-обработки

    // перезапускаем таймер - импульсы идут
    stop_tmr.Restart ();
}


И да, Сергей дело говорит - если инициализировать регистр сразу, "кучей", это и читается легче, и выполняется быстрее (хотя кому этот десяток байт нужен? :-) ), и вот таких опечаток не будет:
Код
  TIM2_CCER |= TIM2_CCER_CC2P &
              ~TIM2_CCER_CC2NP; //TI1FP2 falling edge



PS полистайте ещё раздел "PWM input mode" reference manual'а. Я по нему делал (с учётом более удобного синтаксиса библиотеки).


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 18:45
Рейтинг@Mail.ru


Страница сгенерированна за 0.01395 секунд с 7
ELECTRONIX ©2004-2016