Jump to content

    
Sign in to follow this  
AHTOXA

STM32 TIM4 Output Compare 4

Recommended Posts

Здрасьте всем.

Что-то я застрял, прошу помощи:)

Выдавал ШИМ на TIM2_CH2. Потом стало надо выдавать на TIM4_CH4. Переделал инициализацию, а оно не работает. Вот код:

void init_t4_ch4()
{
    // enable port B and AFIO peripherals
    RCC->APB2ENR |= RCC_APB2ENR_IOPBEN | RCC_APB2ENR_AFIOEN;
    // enable TIM4 peripheral
    RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
    // configure B9 to alternative output mode
    GPIOB->CRH = (GPIOB->CRH & ~(0x0F<<4)) | (0x0B<<4);

    // set up timer
    TIM4->CR1 = TIM_CR1_ARPE;    // count up to ARR, no divisor, auto reload
    TIM4->ARR = 36;            // period
    TIM4->PSC = 0;                // prescaler
    TIM4->EGR = TIM_EGR_UG;        // generate an update event to reload the prescaler value immediately
    TIM4->CR2 = 0;

    // set up compare (ch4)
    TIM4->CCER &= ~(TIM_CCER_CC4E | TIM_CCER_CC4P);    // disable cc4 output, clear polarity
    TIM4->CCR2 = 18;            // cc4 period
    TIM4->CCMR2 &= 0x00FF;
    TIM4->CCMR2 |=
        TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1         // PWM 1 (0x6000)
        | TIM_CCMR2_OC4PE                            //  enable preload;
;
    TIM4->CCER |= TIM_CCER_CC4E;    // enable cc4 output

    TIM4->CR1 |= TIM_CR1_CEN;        // run timer
}

 

А вот для сравнения рабочий код с TIM2_CH2:

void init_t2_ch2()
{
    // enable port A and AFIO peripherals
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN;
    // enable TIM4 peripheral
    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
    // configure A1 to alternative output mode
    GPIOA->CRL = (GPIOA->CRL & ~(0x0F<<4)) | (0x0B<<4);

    // set up timer
    TIM2->CR1 = TIM_CR1_ARPE;    // count up to ARR, no divisor, auto reload
    TIM2->ARR = 36;            // period
    TIM2->PSC = 0;                // prescaler
    TIM2->EGR = TIM_EGR_UG;        // generate an update event to reload the prescaler value immediately
    TIM2->CR2 = 0;

    // set up compare (ch4)
    TIM2->CCER &= ~(TIM_CCER_CC2E | TIM_CCER_CC2P);    // disable cc4 output, clear polarity
    TIM2->CCR2 = 18;            // cc4 period
    TIM2->CCMR1 &= 0x00FF;
    TIM2->CCMR1 |=
        TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1         // PWM 1 (0x6000)
        | TIM_CCMR1_OC2PE                            //  enable preload;
;
    TIM2->CCER |= TIM_CCER_CC2E;    // enable cc4 output

    TIM2->CR1 |= TIM_CR1_CEN;        // run timer
}

 

Первый не работает, второй - работает. Где я что забыл?

Share this post


Link to post
Share on other sites

GPIOB->CRH = (GPIOB->CRH & ~(0x0F<<4)) | (0x0B<<4);

 

Может здесь.

Не знаю какой чип у вас, но четверки не ушли ли автоматом при копировании.

 

Вообще что не работает сам таймер не считает, или нет сигнала на ножке проца?

Share this post


Link to post
Share on other sites

Не, тут всё нормально. Код испытанный, да и видно, что ножка переключается на выход. Таймер вроде как щёлкает. А ножка не дрыгается. (Висит в единице, если это имеет значение).

Но самое неприятное - я не вижу отличий в коде для двух таймеров! При этом один - рабочий, другой - нет.

ЗЫ. Пробовал на MD, HD и CL - везде одинаково.

Share this post


Link to post
Share on other sites

Нет, ремапа тоже нет. Проверил.

 

Попробовал уже от отчаянья сделать с использованием FwLib:

void init_t2_ch2(void)
{
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN;
    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    TIM_TimeBaseStructure.TIM_Period = 36;
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 18;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

    TIM_OC2Init(TIM2, &TIM_OCInitStructure);
    TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);

    TIM_ARRPreloadConfig(TIM2, ENABLE);

    TIM_Cmd(TIM2, ENABLE);
}

void init_4(void)
{
    RCC->APB2ENR |= RCC_APB2ENR_IOPBEN | RCC_APB2ENR_AFIOEN;
    RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    TIM_TimeBaseStructure.TIM_Period = 36;
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 18;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

    TIM_OC4Init(TIM4, &TIM_OCInitStructure);
    TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);

    TIM_ARRPreloadConfig(TIM4, ENABLE);

    TIM_Cmd(TIM4, ENABLE);
}

 

Результат тот же! Первая функция работает, вторая - нет.

Share this post


Link to post
Share on other sites

Уф, победа :biggrin:

 

Я ж не тот CCR инициализирую.

     TIM4->CCR2 = 18;            // cc4 period

 

Нужно-то - CCR4!

 

Да уж. В отпуск вроде ещё рановато... Выспаться наверное надо:)

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this