STM32L432KC LPTIM1 CNT 寄存器始终为 0 并且不启用中断

问题描述 投票:0回答:0

我正在尝试使用 LPTIM1 在 STM32L432KC 微控制器上创建中断。这是作业,我不能使用 STM32CUBEMX 生成的代码。我创建了函数 init_lptim1() 来初始化定时器,但是定时器不会创建中断并且 CNT 寄存器保持在 0.

我还将使用 TIM16 进行 pwm 输出,理想情况下我希望这两个定时器都使用 LSI 时钟源(以降低功耗)。这没什么大不了的,但是因为我还没有决定我的时钟源,所以 ARR 和 PSC 值是占位符。

我当前的 lptim1 初始化代码:

void init_lptim1(void){
    RCC-> CSR |= 0x1UL; //Enable LSI
    while (!(RCC->CSR & 0x2UL)){}
    RCC->CCIPR |= 0x1UL << 18;//set clock source as LSI

    RCC -> APB1ENR1 |= 0x1UL << 31; //Enable LPTIM1
    LPTIM1->CR &= ~0x1UL; // disable LPtimer
    LPTIM1 -> CFGR |= 0x6UL << 9; // PSC 64
    LPTIM1 -> ARR = 25 -1; // FOR 20HZ (PSC 64)
    LPTIM1 -> IER |= 0x2UL;   // enable interuppts on arr match


    LPTIM1->CR |= 0x1UL; // enable LPtimer
        LPTIM1->CR |= 0x2UL; // enable single mode LPtimer

    while (LPTIM1 -> CNT < 4){ // this while loop to test if CNT is correct
    }

    GPIOB -> ODR |= 0x2UL; //this is an led that is not used for anything else.


    NVIC_SetPriority(LPTIM1_IRQn, 0x03); //SET PRIORITY TO MINIMUM
    NVIC_EnableIRQ(LPTIM1_IRQn);
}

pb1 上的 LED 不亮。

代码没有任何错误,在调试模式下所有寄存器似乎都是正确的。也许我错过了什么。我承认我不是 100% 确定单一/连续模式的作用以及我是否需要它们。我只会用定时器中断,不用于任何输出。

板子的配置是,红色LED-PB1,黄色LED PB5,绿色LED PA11,橙色LED PA8,PWM PA6,红色按键PA9,橙色按键PB4,绿色按键PB7

完整代码为:

#include <stm32l432xx.h>
#include <stdio.h>
#include <stdlib.h>
#include<stdint.h>
#include<time.h>

void init_gpio(void);
void init_tim16(void);
void init_lptim1(void);
static inline void reset(void);
static inline void set(void);
void EXTI9_5_IRQHandler(void); // green button exti handler
void LPTIM1_IRQHandler(void);
void EXTI4_IRQHandler(void);
static inline void green_pressed(void);
static inline void blinking_yellow(void);
static inline void post_T1(void);
static inline void post_T2_fail(void);
void orange_pressed(void);
void celebrate(void);
void init_lptim1(void);


// configuring AS PB7 green button and pb4 orange button !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

//configure LSI as clock source!! hopefully for both lptim1 or choose another for both.



uint8_t T1;
volatile uint8_t T2;
uint8_t T3;
volatile uint8_t win_counter=0;
volatile uint32_t lp_counter = 0; //timer for lptim
volatile uint8_t LP_mode = 0;



int main (void){
    srand(time(NULL));
    T1 = ((rand() % (26))+1);
    T2 = ((rand() % (10))+ 1);
    T3 = 6;

    init_gpio();
    init_lptim1();
    init_tim16();


    while(1)
    {
    }
}

void init_gpio(void){
    RCC -> AHB2ENR |= 0x3UL;    //Enable the clock for GPIO port A and port B
    RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // for interrupts on green button - exti

    //configure input/output mode
    GPIOA -> MODER &= ~0x33CCUL << 10;
    GPIOA -> MODER |= 0x412UL << 12; //set gren org led and pwm
    //Pull down
    GPIOA -> PUPDR &= ~0x33CCUL << 10;
    GPIOA -> PUPDR |= 0x2UL << 18;//set red button
    GPIOA -> OSPEEDR &= ~0xC3UL << 16; //LED PIN 8 AND 11 LOW SPEED
    GPIOA -> OTYPER &= ~0x9UL << 8; //LED PUSH PULL

    GPIOA -> AFR[0] &= ~0xFUL << 24;
    GPIOA -> AFR[0] |= (0xEUL <<24);// In the GPIOx_AFR register, set the pin PA_6 to alternate function mode

    GPIOB -> MODER &= ~0xAF0AUL;
    GPIOB -> MODER |= 0x404UL;  //set red yellow led            // configuring AS PB7 green button and pb4 orange button !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    GPIOB -> PUPDR &= ~0xAF0AUL;
    GPIOB -> PUPDR |= 0x82UL<<8; // GREEEN org button
GPIOB -> OSPEEDR &= ~0x30CUL;//LOW SPEED red yellow led
GPIOB -> OTYPER &= ~0x22UL;//PUSH PULL LED


    //green button exti interrupts
    SYSCFG->EXTICR[1] &= ~(0xEUL << 12);
    SYSCFG->EXTICR[1] |= (0x1 << 12); // connect green button to exti interrupts
    EXTI->IMR1 |= (1 << 7);// Setup EXTI interrupts for falling input on the button pin.
    EXTI->FTSR1 &= ~(0x1UL << 7);// Disable the falling edge' trigger (button release)
    EXTI->RTSR1 |= (0x1UL << 7);// Enable the 'rising edge' trigger (button press).

    //red button exti interrupts
    SYSCFG->EXTICR[2] &= ~(0xEUL << 4);// connect green button to exti interrupts
    EXTI->IMR1 |= (1 << 9);// Setup EXTI interrupts for falling input on the button pin.
    EXTI->FTSR1 &= ~(1 << 9);// Disable the falling edge' trigger (button release)
    EXTI->RTSR1 |= (1 << 9);// Enable the 'rising edge' trigger (button press).

    NVIC_SetPriority(EXTI9_5_IRQn, 0x01);// Enable the NVIC interrupt at HIGH priority value.
    NVIC_EnableIRQ(EXTI9_5_IRQn);

    //orange button interrupts
    SYSCFG->EXTICR[1] &= ~(0x7UL);
    SYSCFG->EXTICR[1] |= (0x1); // connect green button to exti interrupts
    EXTI->IMR1 |= (1 << 4);// Setup EXTI interrupts for falling input on the button pin.
    EXTI->FTSR1 &= ~(1 << 4);// Disable the falling edge' trigger (button release)
    EXTI->RTSR1 |= (1 << 4);// Enable the 'rising edge' trigger (button press).

    NVIC_SetPriority(EXTI4_IRQn, 0x02);// Enable the NVIC interrupt at medium priority value.
    NVIC_DisableIRQ(EXTI4_IRQn); //disable orange interrupts
}

void init_lptim1(void){
    RCC-> CSR |= 0x1UL; //Enable LSI
    while (!(RCC->CSR & 0x2UL)){}
    RCC->CCIPR |= 0x1UL << 18;//set clock source as LSI

    RCC -> APB1ENR1 |= 0x1UL << 31; //Enable LPTIM1
    LPTIM1->CR &= ~0x1UL; // disable LPtimer
    LPTIM1 -> CFGR |= 0x6UL << 9; // PSC 64
    LPTIM1 -> ARR = 25 -1; // FOR 20HZ (PSC 64)
    LPTIM1 -> IER |= 0x2UL;   // enable interuppts on arr match


    LPTIM1->CR |= 0x1UL; // enable LPtimer
    LPTIM1->CR |= 0x2UL; // enable single mode LPtimer

    while (!(LPTIM1 -> CNT & 0x4)){
    }

    GPIOB -> ODR |= 0x2UL;


    NVIC_SetPriority(LPTIM1_IRQn, 0x03); //SET PRIORITY TO MINIMUM
    NVIC_EnableIRQ(LPTIM1_IRQn);
}

void init_tim16(void){
    RCC -> APB2ENR |= RCC_APB2ENR_TIM16EN; // Enable tim16
    // RCC->CCIPR |= (0x1 << RCC_CCIPR_TIM16SEL_Pos); // Set TIM16 clock source = LSCO this wanted 14th bit // can solve in ioc

    TIM16 -> PSC = 4000 - 1;
    TIM16 -> ARR = 20 - 1; //need to change this THIS RESULTS IN 4hz - which is needed for 2hz blink
    TIM16 -> CNT = 0; //count starts on zero

    //capture control
    TIM16 -> CCMR1 &= ~0x7FUL;
    TIM16 -> CCMR1 |= (0x6UL << 4);
    TIM16 -> BDTR |= (0x1UL << 15); //manual output mode
    TIM16 -> CCR1 = 1;

    TIM16 -> DIER |= 0x1UL; //update interupt enable.... !!!!!!!mayvbe capcompare interuppt?????
}



static inline void set() { // need to fix this
    GPIOA -> ODR |= 0x900UL; // binary number leds on
    GPIOB -> ODR |= 0x20UL;
    lp_counter = 0;
}

static inline void reset() {
    GPIOA -> ODR &= ~(0x900UL); // all leds off
    GPIOB -> ODR &= ~(0x22UL);
}


void EXTI9_5_IRQHandler(void) {
    if (EXTI->PR1 & (0x1UL << 7)) { //exti routine for green button
            EXTI -> PR1 |= 0x1UL << 7;
            green_pressed();
        }

    if (EXTI->PR1 & (0x1UL << 9)) { //exti routine for red button
        EXTI -> PR1 |= 0x1UL << 9;
        LPTIM1->CR &= ~0x1UL; // disable LPtimer
        EXTI->RTSR1 |= (1 << 7);// Enable the green button 'rising edge' trigger (button press).
        reset();
    }
}


void green_pressed(void){
    set();
    LP_mode = 1;
    LPTIM1->CR |= 0x1UL; // enable LPtimer
}


void LPTIM1_IRQHandler(void) { //20Hz  // ordered in use amount
    if (LPTIM1->ISR & 0x2UL) {
        LPTIM1->ICR |= 0x2UL;// Clear the interrupt flag


        lp_counter++;

        if (LP_mode == 1){//T1 section waiting
            if (lp_counter == (T1*4)){
                post_T1();
            }
            return;
        }else if (LP_mode == 2){//bink yellow led
            if (lp_counter == (T2*20)){
                post_T2_fail();
            }
            blinking_yellow();
            return;
        }else if (LP_mode == 3){//wait T3
            if (lp_counter == (T3*4)){
                set();
                LP_mode = 1; //wait T1 again
                TIM16 -> CR1 &= ~0x1UL;//disable timer 16 for pwm
            }
            return;
        }else if (LP_mode == 4){//win, blink all
            if ((lp_counter % 5) != 0){return;} //this means a pulse of 4Hz beyond this

            if (lp_counter == (3*4)){
                reset();
                LPTIM1->CR &= ~0x1UL; // disable LPtimer
            }
            GPIOA -> ODR ^= 0x900UL; // all leds blink
            GPIOB -> ODR ^= 0x22UL;
            return;
        }else{
            lp_counter = 0;
        }
    }
}


static inline void post_T1(void){
    lp_counter = 0;
    LP_mode = 2; // flashing mode
    reset();
    NVIC_EnableIRQ(EXTI4_IRQn); //enable orange interrupts
}


static inline void blinking_yellow(void){
    GPIOB -> ODR ^= 0x1UL << 5; //blink yellow led
}


void EXTI4_IRQHandler(void) {//orange button only
    if (EXTI->PR1 & (0x1UL << 4)) { //exti routine for orange button
        EXTI -> PR1 |= 0x1UL << 4;
        orange_pressed();
    }
}

void orange_pressed(void){
    static uint8_t win = 0; //win initialised at 0 and keeps after function completed


    NVIC_DisableIRQ(EXTI4_IRQn); //disable orange interrupts

    if (win == 2){ //This saves wim++ from being run again
        LP_mode = 4; //flash all
        return;
    }

    win++; //win increases

    TIM16 -> CR1 |= 0x1UL;//enable timer 16 for pwm
    T2 = T2 * 0.75; //shorten T2
    LP_mode = 3; //to wait T3 while TIM16 raises and lowers pwm
}


static inline void post_T2_fail(void){
    LP_mode = 1; // go back to wait T1
    set();
 //maybe i need to turn off yellow
    NVIC_DisableIRQ(EXTI4_IRQn); //disable orange interrupts
}

lptim1 的启用和禁用还有其他地方,虽然不应该到这里。由于这个问题,其余代码还没有经过测试。我的大问题是:

如何正确初始化 LPTIM1?

如何将TIM16和LPTIM1时钟源设置为LSI? (这是否会禁用它正在使用的默认时钟源)

c timer microcontroller stm32cubeide
© www.soinside.com 2019 - 2024. All rights reserved.