STM32 ||无法初始化中断||核-F746zg

发布于 2025-02-06 04:47:32 字数 13910 浏览 2 评论 0原文

我是STM32 MCU世界的新手,所以请忍受我。

我正在遵循有关Udemy的教程,并试图从头开始编写GPIO中断代码。我已经完成了所有寄存器配置,并且配置在调试模式下通过SFR View可以看到,但是当我运行代码时,似乎未启用中断。 代码永远不会出现在处理程序功能中。

            /*
             * 003button_interrupt.c
             */
            
            #include <string.h>
            #include "stm32f746xx.h"
            
            void delay(void){
                for(uint32_t i=0; i<100000; i++);
            }
            
            int main(){
            
                GPIO_PeriClockControl(GPIOC,ENABLE);
                GPIO_PeriClockControl(GPIOB,ENABLE);
            
                GPIO_Handle_t LED, BTN;
                memset(&LED, 0, sizeof(LED));
                memset(&BTN, 0, sizeof(BTN));
            
                LED.pGPIOx = GPIOB;
                LED.GPIO_PinConfig.GPIO_PinNumber = GPIO_PIN_NO_14;
                LED.GPIO_PinConfig.GPIO_PinMode = GPIO_MODE_OUT;
                LED.GPIO_PinConfig.GPIO_PinOPType = GPIO_OP_TYPE_PP;
                LED.GPIO_PinConfig.GPIO_PinSpeed = GPIO_SPEED_VERY_HIGH;
                LED.GPIO_PinConfig.GPIO_PinPuPdControl = GPIO_NO_PUPD;
            
                GPIO_Init(&LED);
            
                LED.pGPIOx = GPIOB;
                LED.GPIO_PinConfig.GPIO_PinNumber = GPIO_PIN_NO_7;
                LED.GPIO_PinConfig.GPIO_PinMode = GPIO_MODE_OUT;
                LED.GPIO_PinConfig.GPIO_PinOPType = GPIO_OP_TYPE_PP;
                LED.GPIO_PinConfig.GPIO_PinSpeed = GPIO_SPEED_VERY_HIGH;
                LED.GPIO_PinConfig.GPIO_PinPuPdControl = GPIO_NO_PUPD;
            
                GPIO_Init(&LED);
            
                BTN.pGPIOx = GPIOC;
                BTN.GPIO_PinConfig.GPIO_PinNumber = GPIO_PIN_NO_13;
                BTN.GPIO_PinConfig.GPIO_PinMode = GPIO_MODE_IT_FT;
                BTN.GPIO_PinConfig.GPIO_PinSpeed = GPIO_SPEED_VERY_HIGH;
                BTN.GPIO_PinConfig.GPIO_PinPuPdControl = GPIO_PIN_PU;
            
                GPIO_Init(&BTN);
            
                //IRQ interrupt and priority configuration
                GPIO_IRQPriorityConfig(IRQ_NO_EXTI10_15,NVIC_IRQ_PRIO_15);
                GPIO_IRQIntConfig(IRQ_NO_EXTI10_15,ENABLE);
            
                while(1);
            }
            
            void EXTI15_10_IRQHandler(void){
                delay();
                GPIO_IRQHandling(GPIO_PIN_NO_13);
                GPIO_ToggleOutputPin(GPIOB,GPIO_PIN_NO_14);
                GPIO_ToggleOutputPin(GPIOB,GPIO_PIN_NO_7);
            }

            /*
             * stm32f746xx_gpio_driver.c
             */
            
            #include "stm32f746xx_gpio_driver.h"
            
            /*
             * peripheral clock setup
             */
            void GPIO_PeriClockControl(GPIO_RegDef_t *pGPIOx, uint8_t EnOrDis){
                if(EnOrDis == ENABLE){
                    if(pGPIOx == GPIOA){
                        GPIOA_PCLK_EN();
                    }else if(pGPIOx == GPIOB){
                        GPIOB_PCLK_EN();
                    }else if(pGPIOx == GPIOC){
                        GPIOC_PCLK_EN();
                    }else if(pGPIOx == GPIOD){
                        GPIOD_PCLK_EN();
                    }else if(pGPIOx == GPIOE){
                        GPIOE_PCLK_EN();
                    }else if(pGPIOx == GPIOF){
                        GPIOF_PCLK_EN();
                    }else if(pGPIOx == GPIOG){
                        GPIOG_PCLK_EN();
                    }else if(pGPIOx == GPIOH){
                        GPIOH_PCLK_EN();
                    }else if(pGPIOx == GPIOI){
                        GPIOI_PCLK_EN();
                    }else if(pGPIOx == GPIOJ){
                        GPIOJ_PCLK_EN();
                    }else if(pGPIOx == GPIOK){
                        GPIOK_PCLK_EN();
                    }
                } else {
                    if(pGPIOx == GPIOA){
                        GPIOA_PCLK_DIS();
                    }else if(pGPIOx == GPIOB){
                        GPIOB_PCLK_DIS();
                    }else if(pGPIOx == GPIOC){
                        GPIOC_PCLK_DIS();
                    }else if(pGPIOx == GPIOD){
                        GPIOD_PCLK_DIS();
                    }else if(pGPIOx == GPIOE){
                        GPIOE_PCLK_DIS();
                    }else if(pGPIOx == GPIOF){
                        GPIOF_PCLK_DIS();
                    }else if(pGPIOx == GPIOG){
                        GPIOG_PCLK_DIS();
                    }else if(pGPIOx == GPIOH){
                        GPIOH_PCLK_DIS();
                    }else if(pGPIOx == GPIOI){
                        GPIOI_PCLK_DIS();
                    }else if(pGPIOx == GPIOJ){
                        GPIOJ_PCLK_DIS();
                    }else if(pGPIOx == GPIOK){
                        GPIOK_PCLK_DIS();
                    }
                }
            }
            
            /*
             * init and deInit
             */
            void GPIO_Init(GPIO_Handle_t *pGPIOHandle){
                uint32_t temp = 0;
                if(pGPIOHandle->GPIO_PinConfig.GPIO_PinMode <= GPIO_MODE_ANALOG){
                    temp = (pGPIOHandle->GPIO_PinConfig.GPIO_PinMode << (2* pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
                    pGPIOHandle->pGPIOx->MODER &= ~(0x03 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber); // clearing ; always clear before setting
                    pGPIOHandle->pGPIOx->MODER |= temp; // setting
                } else {
            
                    // 1. configure RTSR / FTSR
                    if(pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_IT_FT){
                        (*EXTI).FTSR |= (1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
                        (*EXTI).RTSR &= ~(1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber); // coz we only want FT, clear the corresponding RTSR bit; just to be safe if it is not already cleared for some reason
                    } else if(pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_IT_RT){
                        (*EXTI).RTSR |= (1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
                        (*EXTI).FTSR &= ~(1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
                    } else if(pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_IT_RFT){
                        (*EXTI).RTSR |= (1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
                        (*EXTI).FTSR |= (1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
                    }
            
                    // 2. config the gpio port selection in SYSCFG_EXTICR
                    uint8_t temp1 = pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber / 4;
                    uint8_t temp2 = pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber % 4;
                    uint8_t portcode = GPIO_BASEADDR_TO_CODE(pGPIOHandle->pGPIOx);
                    SYSCFG_PCLK_EN();
                    (*SYSCFG).EXTICR[temp1] = portcode << (temp2 * 4);
            
                    // 3. enable the exti interrupt delivery using IMR
                    (*EXTI).IMR |= (1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
                }
                temp = 0;
            
                temp = (pGPIOHandle->GPIO_PinConfig.GPIO_PinSpeed << (2* pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
                pGPIOHandle->pGPIOx->OSPEEDR &= ~(0x03 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber); // clearing
                pGPIOHandle->pGPIOx->OSPEEDR |= temp; // setting
                temp = 0;
            
                temp = (pGPIOHandle->GPIO_PinConfig.GPIO_PinPuPdControl << (2* pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
                pGPIOHandle->pGPIOx->PUPDR &= ~(0x03 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber); // clearing
                pGPIOHandle->pGPIOx->PUPDR |= temp; // setting
                temp = 0;
            
                temp = (pGPIOHandle->GPIO_PinConfig.GPIO_PinOPType << (pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
                pGPIOHandle->pGPIOx->OTYPER &= ~(0x01 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber); // clearing
                pGPIOHandle->pGPIOx->OTYPER |= temp; // setting
                temp = 0;
            
                if(pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_ALTFN){
                    uint8_t temp1 = pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber / 8;
                    uint8_t temp2 = pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber % 8;
                    pGPIOHandle->pGPIOx->AFR[temp1] &= ~(0x0f << (4* temp2)); // clearing
                    pGPIOHandle->pGPIOx->AFR[temp1] |= pGPIOHandle->GPIO_PinConfig.GPIO_PinAltFunMode << (4* temp2); // setting
                }
            }
            
            void GPIO_DeInit (GPIO_RegDef_t *pGPIOx){
                if(pGPIOx == GPIOA){
                    GPIOA_REG_RESET();
                }else if(pGPIOx == GPIOB){
                    GPIOB_REG_RESET();
                }else if(pGPIOx == GPIOC){
                    GPIOC_REG_RESET();
                }else if(pGPIOx == GPIOD){
                    GPIOD_REG_RESET();
                }else if(pGPIOx == GPIOE){
                    GPIOE_REG_RESET();
                }else if(pGPIOx == GPIOF){
                    GPIOF_REG_RESET();
                }else if(pGPIOx == GPIOG){
                    GPIOG_REG_RESET();
                }else if(pGPIOx == GPIOH){
                    GPIOH_REG_RESET();
                }else if(pGPIOx == GPIOI){
                    GPIOI_REG_RESET();
                }else if(pGPIOx == GPIOJ){
                    GPIOJ_REG_RESET();
                }else if(pGPIOx == GPIOK){
                    GPIOK_REG_RESET();
                }
            }
            
            
            /*
             * data read and write
             */
            uint8_t GPIO_ReadFromInputPin(GPIO_RegDef_t *pGPIOx, uint8_t PinNumber){
                uint8_t value;
                value = (uint8_t)((pGPIOx->IDR >> PinNumber) & 0x00000001);
                return value;
            }
            
            uint16_t GPIO_ReadFromInputPort(GPIO_RegDef_t *pGPIOx){
                uint16_t value;
                value = pGPIOx->IDR;
                return value;
            }
            
            void GPIO_WriteToOutputPin(GPIO_RegDef_t *pGPIOx, uint8_t PinNumber, uint8_t value){
                if(value == GPIO_PIN_SET){
                    pGPIOx->ODR |= (1 << PinNumber);
                } else if(value == GPIO_PIN_CLEAR || value == GPIO_PIN_RESET){
                    pGPIOx->ODR &= ~(1 << PinNumber);
                }
            }
            
            void GPIO_WriteToOutputPort(GPIO_RegDef_t *pGPIOx, uint16_t value){
                pGPIOx->ODR = value;
            }
            
            void GPIO_ToggleOutputPin(GPIO_RegDef_t *pGPIOx, uint8_t PinNumber){
                pGPIOx->ODR ^= (1 << PinNumber);
            }
            
            /*
             * IRQ configuration and ISR handling
             */
            
            // IRQConfig is for config in processor side
            void GPIO_IRQIntConfig(uint16_t IRQNumber, uint8_t EnOrDis){
                if(EnOrDis == ENABLE){
            //      *(NVIC_ISER0 + (((uint32_t)(int32_t)IRQNumber) >> 5UL)) = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQNumber) & 0x1FUL));
                    if(IRQNumber <= 31){
                        (*NVIC_ISER0) |= (1<<IRQNumber);
                    } else if((IRQNumber > 31) && (IRQNumber <= 63)){
                         (*NVIC_ISER1) |= (1<<(IRQNumber%32));
                    } else if((IRQNumber > 63) && (IRQNumber <= 95)){
                        (*NVIC_ISER2) |= (1<<(IRQNumber%64));
                    } else if(IRQNumber > 95){
                        (*NVIC_ISER3) |= (1<<(IRQNumber%96));
                    }
                } else if (EnOrDis == DISABLE){
                    if(IRQNumber <= 31){
                        (*NVIC_ICER0) |= (1<<IRQNumber);
                    } else if((IRQNumber > 31) && (IRQNumber <= 63)){
                        (*NVIC_ICER1) |= (1<<(IRQNumber%32));
                    } else if((IRQNumber > 63) && (IRQNumber <= 95)){
                        (*NVIC_ICER2) |= (1<<(IRQNumber%64));
                    } else if(IRQNumber > 95){
                        (*NVIC_ICER3) |= (1<<(IRQNumber%96));
                    }
                }
            }
            
            void GPIO_IRQPriorityConfig(uint16_t IRQNumber, uint16_t IRQPriority){
                // 1. find the ipr register and section
                uint32_t iprx = IRQNumber / 4;
                uint32_t iprx_section = IRQNumber % 4;
            
                // 2. store the value
                uint8_t shift_value = (8*iprx_section) + (8-NO_IPR_BITS_IMPLEMENTED); // need to move more by (8-NO_IPR_BITS_IMPLEMENTED) bits, since not all of 8 bits are used..
                uint16_t temp = (IRQPriority << shift_value);
                *(NVIC_IPR_BASEADDR + iprx) |= temp; // iprx is multiplied by 4 because each address jump is of 4 bytes..
            }
            
            void GPIO_IRQHandling(uint8_t PinNumber){
                // clear the exti pr register bit corresponding to the pin number
                if((*EXTI).PR & (1<<PinNumber)){
                    (*EXTI).PR |= ( 1 << PinNumber );
                }
            }

请帮助我找到问题。 谢谢!

I am new to the world of STM32 MCU's so please bear with me.

I am following a tutorial on Udemy and trying to write a GPIO interrupt code from scratch. I have done all register configurations and config is working fine as seen through SFR view in debug mode but when I run the code it seems like the interrupt is not enabled. The code never comes in the handler function.

            /*
             * 003button_interrupt.c
             */
            
            #include <string.h>
            #include "stm32f746xx.h"
            
            void delay(void){
                for(uint32_t i=0; i<100000; i++);
            }
            
            int main(){
            
                GPIO_PeriClockControl(GPIOC,ENABLE);
                GPIO_PeriClockControl(GPIOB,ENABLE);
            
                GPIO_Handle_t LED, BTN;
                memset(&LED, 0, sizeof(LED));
                memset(&BTN, 0, sizeof(BTN));
            
                LED.pGPIOx = GPIOB;
                LED.GPIO_PinConfig.GPIO_PinNumber = GPIO_PIN_NO_14;
                LED.GPIO_PinConfig.GPIO_PinMode = GPIO_MODE_OUT;
                LED.GPIO_PinConfig.GPIO_PinOPType = GPIO_OP_TYPE_PP;
                LED.GPIO_PinConfig.GPIO_PinSpeed = GPIO_SPEED_VERY_HIGH;
                LED.GPIO_PinConfig.GPIO_PinPuPdControl = GPIO_NO_PUPD;
            
                GPIO_Init(&LED);
            
                LED.pGPIOx = GPIOB;
                LED.GPIO_PinConfig.GPIO_PinNumber = GPIO_PIN_NO_7;
                LED.GPIO_PinConfig.GPIO_PinMode = GPIO_MODE_OUT;
                LED.GPIO_PinConfig.GPIO_PinOPType = GPIO_OP_TYPE_PP;
                LED.GPIO_PinConfig.GPIO_PinSpeed = GPIO_SPEED_VERY_HIGH;
                LED.GPIO_PinConfig.GPIO_PinPuPdControl = GPIO_NO_PUPD;
            
                GPIO_Init(&LED);
            
                BTN.pGPIOx = GPIOC;
                BTN.GPIO_PinConfig.GPIO_PinNumber = GPIO_PIN_NO_13;
                BTN.GPIO_PinConfig.GPIO_PinMode = GPIO_MODE_IT_FT;
                BTN.GPIO_PinConfig.GPIO_PinSpeed = GPIO_SPEED_VERY_HIGH;
                BTN.GPIO_PinConfig.GPIO_PinPuPdControl = GPIO_PIN_PU;
            
                GPIO_Init(&BTN);
            
                //IRQ interrupt and priority configuration
                GPIO_IRQPriorityConfig(IRQ_NO_EXTI10_15,NVIC_IRQ_PRIO_15);
                GPIO_IRQIntConfig(IRQ_NO_EXTI10_15,ENABLE);
            
                while(1);
            }
            
            void EXTI15_10_IRQHandler(void){
                delay();
                GPIO_IRQHandling(GPIO_PIN_NO_13);
                GPIO_ToggleOutputPin(GPIOB,GPIO_PIN_NO_14);
                GPIO_ToggleOutputPin(GPIOB,GPIO_PIN_NO_7);
            }

            /*
             * stm32f746xx_gpio_driver.c
             */
            
            #include "stm32f746xx_gpio_driver.h"
            
            /*
             * peripheral clock setup
             */
            void GPIO_PeriClockControl(GPIO_RegDef_t *pGPIOx, uint8_t EnOrDis){
                if(EnOrDis == ENABLE){
                    if(pGPIOx == GPIOA){
                        GPIOA_PCLK_EN();
                    }else if(pGPIOx == GPIOB){
                        GPIOB_PCLK_EN();
                    }else if(pGPIOx == GPIOC){
                        GPIOC_PCLK_EN();
                    }else if(pGPIOx == GPIOD){
                        GPIOD_PCLK_EN();
                    }else if(pGPIOx == GPIOE){
                        GPIOE_PCLK_EN();
                    }else if(pGPIOx == GPIOF){
                        GPIOF_PCLK_EN();
                    }else if(pGPIOx == GPIOG){
                        GPIOG_PCLK_EN();
                    }else if(pGPIOx == GPIOH){
                        GPIOH_PCLK_EN();
                    }else if(pGPIOx == GPIOI){
                        GPIOI_PCLK_EN();
                    }else if(pGPIOx == GPIOJ){
                        GPIOJ_PCLK_EN();
                    }else if(pGPIOx == GPIOK){
                        GPIOK_PCLK_EN();
                    }
                } else {
                    if(pGPIOx == GPIOA){
                        GPIOA_PCLK_DIS();
                    }else if(pGPIOx == GPIOB){
                        GPIOB_PCLK_DIS();
                    }else if(pGPIOx == GPIOC){
                        GPIOC_PCLK_DIS();
                    }else if(pGPIOx == GPIOD){
                        GPIOD_PCLK_DIS();
                    }else if(pGPIOx == GPIOE){
                        GPIOE_PCLK_DIS();
                    }else if(pGPIOx == GPIOF){
                        GPIOF_PCLK_DIS();
                    }else if(pGPIOx == GPIOG){
                        GPIOG_PCLK_DIS();
                    }else if(pGPIOx == GPIOH){
                        GPIOH_PCLK_DIS();
                    }else if(pGPIOx == GPIOI){
                        GPIOI_PCLK_DIS();
                    }else if(pGPIOx == GPIOJ){
                        GPIOJ_PCLK_DIS();
                    }else if(pGPIOx == GPIOK){
                        GPIOK_PCLK_DIS();
                    }
                }
            }
            
            /*
             * init and deInit
             */
            void GPIO_Init(GPIO_Handle_t *pGPIOHandle){
                uint32_t temp = 0;
                if(pGPIOHandle->GPIO_PinConfig.GPIO_PinMode <= GPIO_MODE_ANALOG){
                    temp = (pGPIOHandle->GPIO_PinConfig.GPIO_PinMode << (2* pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
                    pGPIOHandle->pGPIOx->MODER &= ~(0x03 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber); // clearing ; always clear before setting
                    pGPIOHandle->pGPIOx->MODER |= temp; // setting
                } else {
            
                    // 1. configure RTSR / FTSR
                    if(pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_IT_FT){
                        (*EXTI).FTSR |= (1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
                        (*EXTI).RTSR &= ~(1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber); // coz we only want FT, clear the corresponding RTSR bit; just to be safe if it is not already cleared for some reason
                    } else if(pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_IT_RT){
                        (*EXTI).RTSR |= (1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
                        (*EXTI).FTSR &= ~(1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
                    } else if(pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_IT_RFT){
                        (*EXTI).RTSR |= (1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
                        (*EXTI).FTSR |= (1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
                    }
            
                    // 2. config the gpio port selection in SYSCFG_EXTICR
                    uint8_t temp1 = pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber / 4;
                    uint8_t temp2 = pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber % 4;
                    uint8_t portcode = GPIO_BASEADDR_TO_CODE(pGPIOHandle->pGPIOx);
                    SYSCFG_PCLK_EN();
                    (*SYSCFG).EXTICR[temp1] = portcode << (temp2 * 4);
            
                    // 3. enable the exti interrupt delivery using IMR
                    (*EXTI).IMR |= (1<<pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber);
                }
                temp = 0;
            
                temp = (pGPIOHandle->GPIO_PinConfig.GPIO_PinSpeed << (2* pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
                pGPIOHandle->pGPIOx->OSPEEDR &= ~(0x03 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber); // clearing
                pGPIOHandle->pGPIOx->OSPEEDR |= temp; // setting
                temp = 0;
            
                temp = (pGPIOHandle->GPIO_PinConfig.GPIO_PinPuPdControl << (2* pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
                pGPIOHandle->pGPIOx->PUPDR &= ~(0x03 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber); // clearing
                pGPIOHandle->pGPIOx->PUPDR |= temp; // setting
                temp = 0;
            
                temp = (pGPIOHandle->GPIO_PinConfig.GPIO_PinOPType << (pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber));
                pGPIOHandle->pGPIOx->OTYPER &= ~(0x01 << pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber); // clearing
                pGPIOHandle->pGPIOx->OTYPER |= temp; // setting
                temp = 0;
            
                if(pGPIOHandle->GPIO_PinConfig.GPIO_PinMode == GPIO_MODE_ALTFN){
                    uint8_t temp1 = pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber / 8;
                    uint8_t temp2 = pGPIOHandle->GPIO_PinConfig.GPIO_PinNumber % 8;
                    pGPIOHandle->pGPIOx->AFR[temp1] &= ~(0x0f << (4* temp2)); // clearing
                    pGPIOHandle->pGPIOx->AFR[temp1] |= pGPIOHandle->GPIO_PinConfig.GPIO_PinAltFunMode << (4* temp2); // setting
                }
            }
            
            void GPIO_DeInit (GPIO_RegDef_t *pGPIOx){
                if(pGPIOx == GPIOA){
                    GPIOA_REG_RESET();
                }else if(pGPIOx == GPIOB){
                    GPIOB_REG_RESET();
                }else if(pGPIOx == GPIOC){
                    GPIOC_REG_RESET();
                }else if(pGPIOx == GPIOD){
                    GPIOD_REG_RESET();
                }else if(pGPIOx == GPIOE){
                    GPIOE_REG_RESET();
                }else if(pGPIOx == GPIOF){
                    GPIOF_REG_RESET();
                }else if(pGPIOx == GPIOG){
                    GPIOG_REG_RESET();
                }else if(pGPIOx == GPIOH){
                    GPIOH_REG_RESET();
                }else if(pGPIOx == GPIOI){
                    GPIOI_REG_RESET();
                }else if(pGPIOx == GPIOJ){
                    GPIOJ_REG_RESET();
                }else if(pGPIOx == GPIOK){
                    GPIOK_REG_RESET();
                }
            }
            
            
            /*
             * data read and write
             */
            uint8_t GPIO_ReadFromInputPin(GPIO_RegDef_t *pGPIOx, uint8_t PinNumber){
                uint8_t value;
                value = (uint8_t)((pGPIOx->IDR >> PinNumber) & 0x00000001);
                return value;
            }
            
            uint16_t GPIO_ReadFromInputPort(GPIO_RegDef_t *pGPIOx){
                uint16_t value;
                value = pGPIOx->IDR;
                return value;
            }
            
            void GPIO_WriteToOutputPin(GPIO_RegDef_t *pGPIOx, uint8_t PinNumber, uint8_t value){
                if(value == GPIO_PIN_SET){
                    pGPIOx->ODR |= (1 << PinNumber);
                } else if(value == GPIO_PIN_CLEAR || value == GPIO_PIN_RESET){
                    pGPIOx->ODR &= ~(1 << PinNumber);
                }
            }
            
            void GPIO_WriteToOutputPort(GPIO_RegDef_t *pGPIOx, uint16_t value){
                pGPIOx->ODR = value;
            }
            
            void GPIO_ToggleOutputPin(GPIO_RegDef_t *pGPIOx, uint8_t PinNumber){
                pGPIOx->ODR ^= (1 << PinNumber);
            }
            
            /*
             * IRQ configuration and ISR handling
             */
            
            // IRQConfig is for config in processor side
            void GPIO_IRQIntConfig(uint16_t IRQNumber, uint8_t EnOrDis){
                if(EnOrDis == ENABLE){
            //      *(NVIC_ISER0 + (((uint32_t)(int32_t)IRQNumber) >> 5UL)) = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQNumber) & 0x1FUL));
                    if(IRQNumber <= 31){
                        (*NVIC_ISER0) |= (1<<IRQNumber);
                    } else if((IRQNumber > 31) && (IRQNumber <= 63)){
                         (*NVIC_ISER1) |= (1<<(IRQNumber%32));
                    } else if((IRQNumber > 63) && (IRQNumber <= 95)){
                        (*NVIC_ISER2) |= (1<<(IRQNumber%64));
                    } else if(IRQNumber > 95){
                        (*NVIC_ISER3) |= (1<<(IRQNumber%96));
                    }
                } else if (EnOrDis == DISABLE){
                    if(IRQNumber <= 31){
                        (*NVIC_ICER0) |= (1<<IRQNumber);
                    } else if((IRQNumber > 31) && (IRQNumber <= 63)){
                        (*NVIC_ICER1) |= (1<<(IRQNumber%32));
                    } else if((IRQNumber > 63) && (IRQNumber <= 95)){
                        (*NVIC_ICER2) |= (1<<(IRQNumber%64));
                    } else if(IRQNumber > 95){
                        (*NVIC_ICER3) |= (1<<(IRQNumber%96));
                    }
                }
            }
            
            void GPIO_IRQPriorityConfig(uint16_t IRQNumber, uint16_t IRQPriority){
                // 1. find the ipr register and section
                uint32_t iprx = IRQNumber / 4;
                uint32_t iprx_section = IRQNumber % 4;
            
                // 2. store the value
                uint8_t shift_value = (8*iprx_section) + (8-NO_IPR_BITS_IMPLEMENTED); // need to move more by (8-NO_IPR_BITS_IMPLEMENTED) bits, since not all of 8 bits are used..
                uint16_t temp = (IRQPriority << shift_value);
                *(NVIC_IPR_BASEADDR + iprx) |= temp; // iprx is multiplied by 4 because each address jump is of 4 bytes..
            }
            
            void GPIO_IRQHandling(uint8_t PinNumber){
                // clear the exti pr register bit corresponding to the pin number
                if((*EXTI).PR & (1<<PinNumber)){
                    (*EXTI).PR |= ( 1 << PinNumber );
                }
            }

Please help me find the issue.
Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花开雨落又逢春i 2025-02-13 04:47:32

该代码几乎不可读取。它为初学者使用了一些非常野性的东西。老实说,我不认为这是一个很好的课程,因为成为介绍的过程中,这是不可或缺的。我不愿承认这一点,但是我也使用一门课程来获得基本的事情,然后才弄清楚如何使用文档来弄清楚事情 - 最重要的技能(课程对此有所帮助;这也是Udemy课程 - 但是,嘿,信息是信息,无论信息来自何处)。


回到主题。很难将代码的头或尾巴制成,尤其是在详细范围内错误的情况下。请清楚地指出您刚刚从某个来源复制的代码以及您自己的创建代码。如果有复制的代码,则问题更有可能在您自己的代码中,因为您可能不是第一个使用该代码的人。乍一看,代码提到了所有部分:

  1. 您设置了GPIO属性。
  2. 您设置了Exti外围设置,在其中选择要触发中断的引脚。
  3. 您设置了SYSCFG,在其中告诉Exti Pin指的是哪个端口(该引脚14表示GPIOB 14,而不是GPIOC 14)。
  4. 您可以启用NVIC,

如果您的中断没有射击,那么看SFR绝对必须显示一些东西。由于您已经知道如何操作调试模式,因此一定是您在那里忽略的东西。

我已经注意到您没有激活SYSCFG的时钟,SYSCFG将GPIO端口绑定到Exti中断引脚。您可以检查SYSCFG是否使用两件事运行:

  1. 在调试模式下打开SFR。如果SYSCFG的所有寄存器均为0x00,则为SUS。可能的时钟可能没有运行。
  2. 在调试模式下打开SFR。打开RCC-&GT;必须设置APB2ENR,位SYSCFGEN。

为了设置该位,请执行rcc-&gt; apb2enr | = rcc_apb2enr_syscfgen;在gpio clock activation旁边激活(或查找如何使用所拥有的库来设置该位)

The code is barely readable. And it uses some really wild stuff for a beginner. Honestly, I don't think this is a good course as a starting point, it feels unnesessarily complicated for being an intro. I hate to admit it, but I also used one course to get basic general feeling of things before I figured out how to figure things out using documentation - the most important skill (and the course helped with just that; it was also a Udemy course - but hey, information is information, no matter where it comes from).


Back to the topic. It's hard to make head or tails of your code, especially if an error is in some detail. Please, indicate clearly what code you just copy-pasted from some source and what code is your own creation. If there is copied code, the problem is more likely to be in your own code, since you're probably not the first person to use that code. At first glance, the code mentions all parts there are to mention:

  1. You set up GPIO properties.
  2. You set up EXTI peripheral, where you select what pins you want to trigger interrupts.
  3. You set up SYSCFG, where you tell what port that EXTI pin refers to (that pin 14 means GPIOB 14 and not GPIOC 14).
  4. You enable NVIC

If your interrupt is not firing, then looking at SFR absolutely MUST show something. Since you already know how to operate debug mode, it must be something you overlooked there.

I have noticed you're not activating clock for SYSCFG, which binds GPIO ports to EXTI interrupt pins. You can check if SYSCFG is running using two things:

  1. Open SFR in debug mode. If all registers of SYSCFG are 0x00, it's sus. Probably its clock is not running.
  2. Open SFR in debug mode. Open RCC -> APB2ENR, bit SYSCFGEN must be set.

In order to set that bit, do RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; next to GPIO clock activation (or find how to set that bit with the library you have)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文