我正在尝试使用 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? (这是否会禁用它正在使用的默认时钟源)