2017-11-22 04:48 AM
Working with STM32F303K8 at the lowest level where I'm writing to the registers directly. Try to follow generic statements in STM documents to handle a high2low transition on a GPIO PB4 input pin. These are the instructions I feel I need to do for the docs.
//interrupts
//EXTI registers. Only set ones that are needed. SYSCFG_EXTICR2 |= BIT0; //select source pin PB4 for the EXTI4 external interrupt EXTI_IMR1 |= BIT4; //assumming MR4 is EXTI4. Set to not mask EXTI_EMR1 |= BIT4; //assumming MR4 is EXTI4. Unmask event EXTI_FTSR1 |= BIT4; //assumming TR4 is EXTI4. Failing edgeIf this code all I need and correct?
I also need an interrupt handler. Again from examples and online searches this is my handler.
void EXTI4_IRQHandler(void) {
if((EXTI_PR1 & BIT4) != 0) {
EXTI_PR1 |= BIT4 ; //clears interrupt} //determines if set
GPIOB_ODR |= BIT3; //toggle test points for scope GPIOB_ODR &= ~BIT3; }When running and PB4 going high2low at ~1K rate the handler does not appear to be hit. Even putting a breakpoint at the 'if(EXTI..' does not get hit.
Any suggestions or directions to get a low level GPIO handler working.
Thanks,
Randy
#gpio-interrupts-using-stdperiph_lib Note: this post was migrated and contained many threaded conversations, some content may be missing.Solved! Go to Solution.
2017-11-22 07:37 AM
In the examples it indicates these are listed in my startup file. For me this is startup_stm32f303x8.s .
In this file there is:
Default_Handler PROC
EXPORT WWDG_IRQHandler [WEAK]
EXPORT PVD_IRQHandler [WEAK] EXPORT TAMP_STAMP_IRQHandler [WEAK] EXPORT RTC_WKUP_IRQHandler [WEAK] EXPORT FLASH_IRQHandler [WEAK] EXPORT RCC_IRQHandler [WEAK] EXPORT EXTI0_IRQHandler [WEAK] EXPORT EXTI1_IRQHandler [WEAK] EXPORT EXTI2_TSC_IRQHandler [WEAK] EXPORT EXTI3_IRQHandler [WEAK] EXPORT EXTI4_IRQHandler [WEAK] <<<<<<<<<<< this is the one I've defined in my main.cRandy
2017-11-22 07:44 AM
NVIC_EnableIRQ(EXTI4_IRQn) you have?
JW
2017-11-22 07:50 AM
JW,
Am trying to find this in the reference manuals.
Randy
2017-11-24 10:23 AM
// Example in SPL
#include 'stm32f30x.h'
void GPIO_Config(void)
{ GPIO_InitTypeDef GPIO_InitStructure;/* Enable GPIOB clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);/* Configure PB3 pin as output */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_Init(GPIOB, &GPIO_InitStructure);}void EXTI4_Config(void)
{ EXTI_InitTypeDef EXTI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;/* Enable GPIOB clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);/* Configure PB4 pin as input floating */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_Init(GPIOB, &GPIO_InitStructure);/* Enable SYSCFG clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);/* Connect EXTI4 Line to PB4 pin */
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource4);/* Configure EXTI4 line */
EXTI_InitStructure.EXTI_Line = EXTI_Line4; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure);/* Enable and set EXTI4 Interrupt to the lowest priority */
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);}void EXTI4_IRQHandler(void)
{ if (EXTI_GetITStatus(EXTI_Line4) == SET) { /* Clear the EXTI line 4 pending bit */ EXTI_ClearITPendingBit(EXTI_Line4);GPIOB->ODR |= GPIO_Pin_3; // Pulse PB3
GPIOB->ODR &= ~GPIO_Pin_3; }}int main(void)
{ /* Configure PB3 as an output */ GPIO_Config();/* Configure PB4 in interrupt mode */
EXTI4_Config();/* Infinite loop */
while (1) { }}#ifdef USE_FULL_ASSERT
/** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */void assert_failed(uint8_t* file, uint32_t line){ /* User can add his own implementation to report the file name and line number, ex: printf('Wrong parameters value: file %s on line %d\r\n', file, line) *//* Infinite loop */
while (1) { }}#endif2017-11-27 08:44 AM
Clive,
Thanks you very much. Got the example included in my project and I can see the interrupt happening. Getting this code included also has helped me understand my Keil environment better (a big plus). Now that I have something working I can study how the interrupts work.
Thanks again.
Randy
2017-11-27 09:24 AM
The modular nature of the ARM designs tends to mean there are more ducks to line up when it comes to configuration compared to tighter or more integrated designs. Once done you can enable/disable at the peripheral level quite simply.
There can be a lot of similar/replicated code for initialization, this can be reduced with the use of functions or configuration tables, but that would tend to obfuscate the examples. You should also watch register level coding, the registers are treated as volatile so the compiler can't fold multiple operations, so if you write 1000 lines of RMW code you'll get 1000 LDR/STR operations.
2017-11-27 10:05 AM
the registers are treated as volatile so the compiler can't fold multiple operations, so if you write 1000 lines of RMW code you'll get 1000 LDR/STR operations.
This is IMO obvious to anybody who did some asm programming on the 8-bitters; I believe it's the kids churned out by schools teaching exclusively high level languages why we see so many of this lately.
JW