简体   繁体   English

NVIC中断不适用于STM32F103

[英]NVIC Interrupt not working on STM32F103

I have written the following code to control an LED with a switch connected at B3 configured as AFIO, But it seems there is a problem with the NVIC functions, please how should they be used. 我已经编写了以下代码,以通过配置为AFIO的B3处连接的开关来控制LED,但是似乎NVIC功能存在问题,请如何使用它们。

#include "stm32f10x.h"

void EXTI3_IRQHandler(void)
{

    //Check if EXTI_Line0 is asserted
    if(EXTI_GetITStatus(EXTI_Line3) != RESET)
    {
        GPIOA -> ODR=0X00F0;
    }
    //we need to clear line pending bit manually
    EXTI_ClearITPendingBit(EXTI_Line3);
}

int main()
{
    // ENABLING CORRESPONDING CLOCKS
    RCC->APB2ENR |= 0X000D;
    RCC->APB1ENR |= 0X0001;

    //CONFIGURING GPIO PORTS -- PIN 3 CONFIGURED AS AFIO PUSH/PULL AND PIN4 SET UP AS GPIO OUTPUT
    GPIOA->CRL = 0X00B3B000; 
    GPIOB->CRL = 0X0000B000;

    //PA6 IS SET AS EVENT OUTPUT PORT
    AFIO->EVCR |= 0X0086;

    //PB3 SET AS INPUT PORT AFIO_EXTICR1
    AFIO->EXTICR[1] |= 0X1000 ;

    //SELECTING RISING TRIGGERS
    EXTI->RTSR = 0X0008 ;

    // UNMASKING INTERRUPT SIGNAL AT EXTI3
    EXTI->IMR |= 0X0008 ;   

    // UNMASKING EVENT SIGNAL AT EXTI6
    EXTI->EMR |= 0X0040 ;   

    GPIOA -> ODR=0X0010;

    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; 
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
    NVIC_Init(&NVIC_InitStructure);  
}

Below is a complete no library example that uses hardware interrupts, it is the timer not gpio but you should get the idea. 下面是一个使用硬件中断的完整no库示例,它不是gpio计时器,但您应该了解一下。 Some folks are going to flame/bash this maybe even see how many downvotes they can recruit. 有些人可能会大发雷霆,甚至可能会看到他们可以招募多少票。 They are not interested in how things work just want to have someone else make them work for them and move on. 他们对事物的运行方式不感兴趣,只是想让其他人为他们工作并继续前进。 I can appreciate you wanting to understand and see this stuff. 感谢您希望了解并看到这些内容。 (can you find the error in the ST documentation? or perhaps it is an error in the arm documentation cut and pasted by ST into their documentation? it is not related to your problem) (您可以在ST文档中找到该错误吗?或者可能是ST剪切并粘贴到其文档中的arm文档中的一个错误?与您的问题无关)

I will have to dig through your question some more to see if anything jumps out. 我将不得不进一步研究您的问题,看看是否有任何问题。 I HIGHLY recommend as shown below you take a one step at a time approach. 我强烈建议您如下图所示,一次采取一个步骤。 Before enabling interrupts, using polling can you see the perpheral show an interrupt? 在启用中断之前,使用轮询可以看到外围设备显示中断吗? Then can you see that interrupt pending in the NVIC (without processor interrupts enabled) and then finally if you enable the interrupt to the processor you know know that it is making it to the nvic, you can clear it, etc so the last step is your function being called. 然后,您是否可以看到NVIC中有待处理的中断(未启用处理器中断),最后,如果对处理器启用了该中断,您就知道它正在向nvic发送中断,您可以清除它,依此类推,所以最后一步是您的函数被调用。 Much harder to debug if you try to do all of these things in one experiment. 如果您尝试在一个实验中完成所有这些操作,则调试起来会更加困难。

flash.s 闪存

.cpu cortex-m0
.thumb

.thumb_func
.global _start
_start:
.word 0x20005000
.word reset
.word hang @ NMI
.word hang @ Hard Fault
.word hang @ MMU Fault
.word hang @ Bus Fault
.word hang @ Usage Fault
.word hang
.word hang
.word hang
.word hang
.word hang @ svcall
.word hang
.word hang
.word hang @ pendsv
.word hang @ systick

.word hang @ irq  0
.word hang @ irq  1
.word hang @ irq  2
.word hang @ irq  3
.word hang @ irq  4
.word hang @ irq  5
.word hang @ irq  6
.word hang @ irq  7
.word hang @ irq  8
.word hang @ irq  9
.word hang @ irq 10
.word hang @ irq 11
.word hang @ irq 12
.word hang @ irq 13
.word hang @ irq 14
.word hang @ irq 15
.word hang @ irq 16
.word hang @ irq 17
.word hang @ irq 18
.word hang @ irq 19
.word hang @ irq 20
.word hang @ irq 21
.word hang @ irq 22
.word hang @ irq 23
.word hang @ irq 24
.word tim1_handler @ irq 25
.word hang @ irq 26
.word hang @ irq 27
.word hang @ irq 28
.word hang @ irq 29

.thumb_func
reset:
    bl notmain
    b hang
.thumb_func
hang:   b .

.end

putget.s 推杆

.cpu cortex-m0
.thumb

.thumb_func
.globl PUT16
PUT16:
    strh r1,[r0]
    bx lr

.thumb_func
.globl PUT32
PUT32:
    str r1,[r0]
    bx lr

.thumb_func
.globl GET32
GET32:
    ldr r0,[r0]
    bx lr

.thumb_func
.globl dummy
dummy:
    bx lr

.end

flash.ld flash.ld

MEMORY
{
    rom : ORIGIN = 0x08000000, LENGTH = 0x1000
    ram : ORIGIN = 0x20000000, LENGTH = 0x5000
}

SECTIONS
{
    .text : { *(.text*) } > rom
    .rodata : { *(.rodata*) } > rom
    .bss : { *(.bss*) } > ram
}

notmain.c notmain.c

//PA9  TX
//PA10 RX

void PUT32 ( unsigned int, unsigned int );
unsigned int GET32 ( unsigned int );
unsigned int GET16 ( unsigned int );
void dummy ( unsigned int );

#define USART1_BASE 0x40013800
#define USART1_SR   (USART1_BASE+0x00)
#define USART1_DR   (USART1_BASE+0x04)
#define USART1_BRR  (USART1_BASE+0x08)
#define USART1_CR1  (USART1_BASE+0x0C)
#define USART1_CR2  (USART1_BASE+0x10)
#define USART1_CR3  (USART1_BASE+0x14)
#define USART1_GTPR (USART1_BASE+0x18)

#define GPIOA_BASE 0x40010800
#define GPIOA_CRL  (GPIOA_BASE+0x00)
#define GPIOA_CRH  (GPIOA_BASE+0x04)
#define GPIOA_IDR  (GPIOA_BASE+0x08)
#define GPIOA_ODR  (GPIOA_BASE+0x0C)
#define GPIOA_BSRR (GPIOA_BASE+0x10)
#define GPIOA_BRR  (GPIOA_BASE+0x14)
#define GPIOA_LCKR (GPIOA_BASE+0x18)

#define RCC_BASE 0x40021000
#define RCC_APB2ENR (RCC_BASE+0x18)
#define RCC_CR      (RCC_BASE+0x00)
#define RCC_CFGR    (RCC_BASE+0x04)

#define GPIOBBASE 0x40010C00
#define RCCBASE 0x40021000

#define STK_CSR 0xE000E010
#define STK_RVR 0xE000E014
#define STK_CVR 0xE000E018
#define STK_MASK 0x00FFFFFF

#define PERIPH_BB_BASE 0x42000000

#define TIM1BASE    0x40012C00
#define TIM1_CR1    (TIM1BASE+0x00)
#define TIM1_DIER   (TIM1BASE+0x0C)
#define TIM1_SR     (TIM1BASE+0x10)

#define NVIC_BASE   0xE000E100
#define NVIC_ISER0  (NVIC_BASE+0x000)
#define NVIC_ISER1  (NVIC_BASE+0x004)
//...
#define NVIC_IPR18  (NVIC_BASE+0x348)
#define NVIC_IPR19  (NVIC_BASE+0x34C)
#define NVIC_IPR20  (NVIC_BASE+0x350)

#define NVIC_STIR   (NVIC_BASE+0xE00)

static void clock_init ( void )
{
    unsigned int ra;

    //enable the external clock
    ra=GET32(RCC_CR);
    ra=ra|1<<16; //HSEON
    PUT32(RCC_CR,ra);

    //wait for HSE to settle
    while(1) if(GET32(RCC_CR)&(1<<17)) break; //HSERDY



    //select HSE clock
    ra=GET32(RCC_CFGR);
    ra&=~(0x3<<0);
    ra|= (0x1<<0);
    PUT32(RCC_CFGR,ra);
    //wait for it
    while(1) if((GET32(RCC_CFGR)&0xF)==0x5) break;
    return;
}


static void uart_init ( void )
{
    //assuming 8MHz clock, 115200 8N1
    unsigned int ra;

    ra=GET32(RCC_APB2ENR);
    ra|=1<<2;   //GPIOA
    ra|=1<<14;  //USART1
    PUT32(RCC_APB2ENR,ra);

    //pa9 TX  alternate function output push-pull
    //pa10 RX configure as input floating
    ra=GET32(GPIOA_CRH);
    ra&=~(0xFF0);
    ra|=0x490;
    PUT32(GPIOA_CRH,ra);

    PUT32(USART1_CR1,0x2000);
    PUT32(USART1_CR2,0x0000);
    PUT32(USART1_CR3,0x0000);
    //8000000/16 = 500000
    //500000/115200 = 4.34
    //4 and 5/16 = 4.3125
    //4.3125 * 16 * 115200 = 7948800
    PUT32(USART1_BRR,0x0045);
    PUT32(USART1_CR1,0x200C);
}
static void uart_putc ( unsigned int c )
{
    while(1)
    {
        if(GET32(USART1_SR)&0x80) break;
    }
    PUT32(USART1_DR,c);
}
static void hexstrings ( unsigned int d )
{
    unsigned int rb;
    unsigned int rc;

    rb=32;
    while(1)
    {
        rb-=4;
        rc=(d>>rb)&0xF;
        if(rc>9) rc+=0x37; else rc+=0x30;
        uart_putc(rc);
        if(rb==0) break;
    }
    uart_putc(0x20);
}
static void hexstring ( unsigned int d )
{
    hexstrings(d);
    uart_putc(0x0D);
    uart_putc(0x0A);
}

volatile unsigned int counter;
void tim1_handler ( void )
{
    counter++;
    //uart_putc(0x55);
    PUT32(TIM1_SR,0);
}

int notmain ( void )
{
    unsigned int ra;
    unsigned int rb;
    unsigned int rc;

    clock_init();
    uart_init();
    hexstring(0x12345678);

    ra=GET32(RCC_APB2ENR);
    ra|=1<<11;  //TIM1
    PUT32(RCC_APB2ENR,ra);

if(0)
{
    PUT32(TIM1_CR1,0x00001);
    for(rc=0;;rc++)
    {
        hexstring(rc);
        for(ra=0;ra<1221;ra++)
        {
            while(1)
            {
                rb=GET32(TIM1_SR);
                if(rb) break;
            }
            PUT32(TIM1_SR,0);
        }
    }
}

if(0)
{
    PUT32(TIM1_CR1,0x00001);
    PUT32(TIM1_DIER,0x00001);
    while(1)
    {
        rb=GET32(TIM1_SR);
        if(rb) break;
    }
    hexstring(rb);
    hexstring(GET32(NVIC_ICPR0));
    hexstring(GET32(NVIC_ICPR1));
    hexstring(GET32(NVIC_ICPR2));
}

if(1)
{
    counter=0;
    PUT32(TIM1_CR1,0x00001);
    PUT32(TIM1_DIER,0x00001);
    PUT32(NVIC_ISER0,0x02000000);
    for(rc=0;rc<10;)
    {
        if(counter>=1221)
        {
            counter=0;
            hexstring(rc++);
        }
    }
    PUT32(TIM1_CR1,0x00000);
    PUT32(TIM1_DIER,0x00000);
}

    return(0);
}

build, you can change the cortex-m0s to m3s if you want, m3 code is not the problem you are having 构建时,您可以根据需要将cortex-m0s更改为m3s,m3代码不是您遇到的问题

arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m0 flash.s -o flash.o
arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m0 putget.s -o putget.o
arm-none-eabi-gcc -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding -mcpu=cortex-m0 -march=armv6-m -mthumb -mcpu=cortex-m0 -march=armv6-m -c notmain.c -o notmain.o
arm-none-eabi-ld -T flash.ld flash.o putget.o notmain.o -o notmain.elf
arm-none-eabi-objdump -D notmain.elf > notmain.list
arm-none-eabi-objcopy notmain.elf notmain.bin -O binary

EDIT 编辑

This uses pb8 as the input and pb9 as an output, instead of a switch that can bounce, I am driving pb9 to simulate (and control) state changes on pb8. 这将pb8用作输入,将pb9用作输出,而不是会跳动的开关,我正在驱动pb9来模拟(并控制)pb8的状态变化。 Couldnt get pb3 to work as a generic input, just make a loop looking for pb3 to change light your led directly or use the uart to print something, and sort pb3 to ground and/or 3.3 and see if you get GPIOB IDR to show changes, I couldnt. 无法使pb3用作通用输入,只需循环查找pb3即可直接改变您的led的光或使用uart进行打印,然后将pb3接地和/或3.3排序,看看是否获得GPIOB IDR来显示更改,我无法。 So switched to pb8. 因此切换到pb8。

notmain.c notmain.c

//PA9  TX
//PA10 RX

void PUT32 ( unsigned int, unsigned int );
unsigned int GET32 ( unsigned int );
unsigned int GET16 ( unsigned int );
void dummy ( unsigned int );

#define USART1_BASE 0x40013800
#define USART1_SR   (USART1_BASE+0x00)
#define USART1_DR   (USART1_BASE+0x04)
#define USART1_BRR  (USART1_BASE+0x08)
#define USART1_CR1  (USART1_BASE+0x0C)
#define USART1_CR2  (USART1_BASE+0x10)
#define USART1_CR3  (USART1_BASE+0x14)
#define USART1_GTPR (USART1_BASE+0x18)

#define GPIOA_BASE 0x40010800
#define GPIOA_CRL  (GPIOA_BASE+0x00)
#define GPIOA_CRH  (GPIOA_BASE+0x04)
#define GPIOA_IDR  (GPIOA_BASE+0x08)
#define GPIOA_ODR  (GPIOA_BASE+0x0C)
#define GPIOA_BSRR (GPIOA_BASE+0x10)
#define GPIOA_BRR  (GPIOA_BASE+0x14)
#define GPIOA_LCKR (GPIOA_BASE+0x18)

#define GPIOB_BASE 0x40010C00
#define GPIOB_CRL  (GPIOB_BASE+0x00)
#define GPIOB_CRH  (GPIOB_BASE+0x04)
#define GPIOB_IDR  (GPIOB_BASE+0x08)
#define GPIOB_ODR  (GPIOB_BASE+0x0C)
#define GPIOB_BSRR (GPIOB_BASE+0x10)
#define GPIOB_BRR  (GPIOB_BASE+0x14)
#define GPIOB_LCKR (GPIOB_BASE+0x18)

#define RCC_BASE 0x40021000
#define RCC_APB2ENR (RCC_BASE+0x18)
#define RCC_CR      (RCC_BASE+0x00)
#define RCC_CFGR    (RCC_BASE+0x04)

#define GPIOBBASE 0x40010C00
#define RCCBASE 0x40021000

#define STK_CSR 0xE000E010
#define STK_RVR 0xE000E014
#define STK_CVR 0xE000E018
#define STK_MASK 0x00FFFFFF

#define PERIPH_BB_BASE 0x42000000

#define TIM1BASE    0x40012C00
#define TIM1_CR1    (TIM1BASE+0x00)
#define TIM1_DIER   (TIM1BASE+0x0C)
#define TIM1_SR     (TIM1BASE+0x10)

#define NVIC_BASE   0xE000E100
#define NVIC_ISER0  (NVIC_BASE+0x000)
#define NVIC_ISER1  (NVIC_BASE+0x004)
#define NVIC_ISER2  (NVIC_BASE+0x008)
#define NVIC_ICER0  (NVIC_BASE+0x080)
#define NVIC_ICER1  (NVIC_BASE+0x084)
#define NVIC_ICER2  (NVIC_BASE+0x088)
#define NVIC_ISPR0  (NVIC_BASE+0x100)
#define NVIC_ISPR1  (NVIC_BASE+0x104)
#define NVIC_ISPR2  (NVIC_BASE+0x108)
#define NVIC_ICPR0  (NVIC_BASE+0x180)
#define NVIC_ICPR1  (NVIC_BASE+0x184)
#define NVIC_ICPR2  (NVIC_BASE+0x188)
#define NVIC_IABR0  (NVIC_BASE+0x200)
#define NVIC_IABR1  (NVIC_BASE+0x204)
#define NVIC_IABR2  (NVIC_BASE+0x208)
#define NVIC_IPR00  (NVIC_BASE+0x300)
#define NVIC_IPR01  (NVIC_BASE+0x304)
#define NVIC_IPR02  (NVIC_BASE+0x308)
#define NVIC_IPR03  (NVIC_BASE+0x30C)
#define NVIC_IPR04  (NVIC_BASE+0x310)
#define NVIC_IPR05  (NVIC_BASE+0x314)
#define NVIC_IPR06  (NVIC_BASE+0x318)
#define NVIC_IPR07  (NVIC_BASE+0x31C)
#define NVIC_IPR08  (NVIC_BASE+0x320)
#define NVIC_IPR09  (NVIC_BASE+0x324)
#define NVIC_IPR10  (NVIC_BASE+0x328)
#define NVIC_IPR11  (NVIC_BASE+0x32C)
#define NVIC_IPR12  (NVIC_BASE+0x330)
#define NVIC_IPR13  (NVIC_BASE+0x334)
#define NVIC_IPR14  (NVIC_BASE+0x338)
#define NVIC_IPR15  (NVIC_BASE+0x33C)
#define NVIC_IPR16  (NVIC_BASE+0x340)
#define NVIC_IPR17  (NVIC_BASE+0x344)
#define NVIC_IPR18  (NVIC_BASE+0x348)
#define NVIC_IPR19  (NVIC_BASE+0x34C)
#define NVIC_IPR20  (NVIC_BASE+0x350)

#define NVIC_STIR   (NVIC_BASE+0xE00)


#define EXTI_BASE   0x40010400
#define EXTI_IMR    (EXTI_BASE+0x00)
#define EXTI_EMR    (EXTI_BASE+0x04)
#define EXTI_RTSR   (EXTI_BASE+0x08)
#define EXTI_FTSR   (EXTI_BASE+0x0C)
#define EXTI_SWIER  (EXTI_BASE+0x10)
#define EXTI_PR     (EXTI_BASE+0x14)


#define AFIO_BASE 0x40010000

#define AFIO_EXTICR1 (AFIO_BASE+0x08)
#define AFIO_EXTICR2 (AFIO_BASE+0x0C)
#define AFIO_EXTICR3 (AFIO_BASE+0x10)
#define AFIO_EXTICR4 (AFIO_BASE+0x14)










static void clock_init ( void )
{
    unsigned int ra;

    //enable the external clock
    ra=GET32(RCC_CR);
    ra=ra|1<<16; //HSEON
    PUT32(RCC_CR,ra);

    //wait for HSE to settle
    while(1) if(GET32(RCC_CR)&(1<<17)) break; //HSERDY



    //select HSE clock
    ra=GET32(RCC_CFGR);
    ra&=~(0x3<<0);
    ra|= (0x1<<0);
    PUT32(RCC_CFGR,ra);
    //wait for it
    while(1) if((GET32(RCC_CFGR)&0xF)==0x5) break;
    return;
}


static void uart_init ( void )
{
    //assuming 8MHz clock, 115200 8N1
    unsigned int ra;

    ra=GET32(RCC_APB2ENR);
    ra|=1<<2;   //GPIOA
    ra|=1<<14;  //USART1
    PUT32(RCC_APB2ENR,ra);

    //pa9 TX  alternate function output push-pull
    //pa10 RX configure as input floating
    ra=GET32(GPIOA_CRH);
    ra&=~(0xFF0);
    ra|=0x490;
    PUT32(GPIOA_CRH,ra);

    PUT32(USART1_CR1,0x2000);
    PUT32(USART1_CR2,0x0000);
    PUT32(USART1_CR3,0x0000);
    //8000000/16 = 500000
    //500000/115200 = 4.34
    //4 and 5/16 = 4.3125
    //4.3125 * 16 * 115200 = 7948800
    PUT32(USART1_BRR,0x0045);
    PUT32(USART1_CR1,0x200C);
}
static void uart_putc ( unsigned int c )
{
    while(1)
    {
        if(GET32(USART1_SR)&0x80) break;
    }
    PUT32(USART1_DR,c);
}
static void hexstrings ( unsigned int d )
{
    unsigned int rb;
    unsigned int rc;

    rb=32;
    while(1)
    {
        rb-=4;
        rc=(d>>rb)&0xF;
        if(rc>9) rc+=0x37; else rc+=0x30;
        uart_putc(rc);
        if(rb==0) break;
    }
    uart_putc(0x20);
}
static void hexstring ( unsigned int d )
{
    hexstrings(d);
    uart_putc(0x0D);
    uart_putc(0x0A);
}

void int_handler ( void )
{
    uart_putc(0x55);
    PUT32(EXTI_PR,1<<8);
    PUT32(NVIC_ICPR0,1<<23);
}

static int delay ( unsigned int n )
{
    unsigned int ra;

    while(n--)
    {
        while(1)
        {
            ra=GET32(STK_CSR);
            if(ra&(1<<16)) break;
        }
    }
    return(0);
}


int notmain ( void )
{
    unsigned int ra;
    //unsigned int rb;

    clock_init();
    uart_init();
    hexstring(0x11223344);

    ra=GET32(RCC_APB2ENR);
    ra|=1<<3;   //GPIOB
    ra|=1<<0;   //AFIO
    PUT32(RCC_APB2ENR,ra);
    hexstring(GET32(GPIOB_CRL));

if(0)
{
    //PB4 OUTPUT PB3 INPUT
    ra=GET32(GPIOB_CRH);
    ra&=~(0xF<<0); //PB8
    ra|= (0x4<<0); //PB8 input
    ra&=~(0xF<<4); //PB9
    ra|= (0x1<<4); //PB9 output
    PUT32(GPIOB_CRH,ra);

    hexstring(GET32(GPIOB_IDR));
    PUT32(GPIOB_BSRR,(1<<9)<< 0);
    hexstring(GET32(GPIOB_IDR));
    PUT32(GPIOB_BSRR,(1<<9)<<16);
    hexstring(GET32(GPIOB_IDR));
}
if(0)
{
    ra=GET32(GPIOB_CRH);
    ra&=~(0xF<<0); //PB8
    ra|= (0x4<<0); //PB8 input
    ra&=~(0xF<<4); //PB9
    ra|= (0x1<<4); //PB9 output
    PUT32(GPIOB_CRH,ra);

    hexstring(GET32(GPIOB_IDR)&(1<<8));
    PUT32(GPIOB_BSRR,(1<<9)<< 0);
    hexstring(GET32(GPIOB_IDR)&(1<<8));

    PUT32(AFIO_EXTICR3,1<<0);
    PUT32(EXTI_RTSR,1<<8);
    //PUT32(EXTI_FTSR,1<<8);
    //PUT32(EXTI_SWIER,1<<8);
    PUT32(EXTI_IMR,1<<8);
    //PUT32(EXTI_EMR,1<<8);

    PUT32(GPIOB_BSRR,(1<<9)<<16);
    hexstring(GET32(GPIOB_IDR)&(1<<8));
    PUT32(GPIOB_BSRR,(1<<9)<< 0);
    hexstring(GET32(GPIOB_IDR)&(1<<8));
    hexstring(0xaabbccde);
    //hexstring(GET32(EXTI_SWIER));
    hexstring(GET32(EXTI_PR));
    hexstring(GET32(NVIC_ICPR0));
    hexstring(GET32(NVIC_ICPR1));
    hexstring(GET32(NVIC_ICPR2));
    hexstring(0xaabbccdf);
    PUT32(EXTI_PR,1<<8);
    hexstring(GET32(EXTI_PR));
    hexstring(GET32(NVIC_ICPR0));
    hexstring(GET32(NVIC_ICPR1));
    hexstring(GET32(NVIC_ICPR2));
    hexstring(0xaabbccef);
    PUT32(NVIC_ICPR0,1<<23);
    hexstring(GET32(EXTI_PR));
    hexstring(GET32(NVIC_ICPR0));
    hexstring(GET32(NVIC_ICPR1));
    hexstring(GET32(NVIC_ICPR2));
}


    ra=GET32(GPIOB_CRH);
    ra&=~(0xF<<0); //PB8
    ra|= (0x4<<0); //PB8 input
    ra&=~(0xF<<4); //PB9
    ra|= (0x1<<4); //PB9 output
    PUT32(GPIOB_CRH,ra);

    //hexstring(GET32(GPIOB_IDR)&(1<<8));
    //PUT32(GPIOB_BSRR,(1<<9)<< 0);
    //hexstring(GET32(GPIOB_IDR)&(1<<8));

    PUT32(AFIO_EXTICR3,1<<0);
    PUT32(EXTI_RTSR,1<<8);
    //PUT32(EXTI_FTSR,1<<8);
    //PUT32(EXTI_SWIER,1<<8);
    PUT32(EXTI_IMR,1<<8);
    //PUT32(EXTI_EMR,1<<8);
    PUT32(NVIC_ISER0,0x00800000);

    PUT32(STK_CSR,4);
    PUT32(STK_RVR,1000000-1);
    PUT32(STK_CVR,0x00000000);
    PUT32(STK_CSR,5);

    while(1)
    {
        PUT32(GPIOB_BSRR,(1<<9)<<16);
        delay(8);
        PUT32(GPIOB_BSRR,(1<<9)<< 0);
        delay(8);
    }

    return(0);
}

I found it used interrupt 23. 我发现它使用了中断23。

 8000098:   080000bf 
 800009c:   0800014d  <- points at interrupt handler
 80000a0:   080000bf 

and that matches the documentation for EXTI lines 9 to 5 (search for EXTI9_5 and or 009C in the vector table or 0x0000_009C). 并且与EXTI第9至5行的文档相匹配(在向量表或0x0000_009C中搜索EXTI9_5和或009C)。

It does not seem to care if the pb is configured as an AFIO output (0xB) or a floating input (0x4). 似乎并不在乎将pb配置为AFIO输出(0xB)还是浮动输入(0x4)。 So I dont think that is your problem. 所以我不认为这是您的问题。

This array of volatile pointers is even worse than just using volatile pointers: 这种易失性指针数组甚至比仅使用易失性指针还要糟糕:

AFIO->EXTICR[1]

I am wondering if that really uses EXTCR2 0x4001000C instead of EXTCR1 which is what you want 0x40010008. 我想知道这是否真的使用EXTCR2 0x4001000C而不是您想要的EXTCR1 0x40010008。 I would make a one line program 我会做一个单行程序

AFIO->EXTICR[1]=7

then disassemble it and see if they are producing a store to 0x40010008, if not then there is your problem. 然后将其拆解,看看他们是否正在向0x40010008存储,否则就没有问题。

From what I saw you dont need to mess with EMR and despite the drawing (another documentation bug?) you dont need to set the SWIER in order to get the signal to pass through to the PR. 从我看到的结果来看,您不需要弄乱EMR,尽管有图纸(另一个文档错误?),也不需要设置SWIER就能使信号传递到PR。 I only needed the registers shown above to get the PR to reflect the edge detect on the input. 我只需要上面显示的寄存器就可以得到PR来反映输入上的边沿检测。 And from there then the NVIC could see it and then I could setup a handler. 然后从那里NVIC可以看到它,然后我可以设置一个处理程序。

I used the systick timer to drive my pb9 output every second, causing the interrupt every other second as I am only watching for one of the edges. 我使用systick计时器每秒钟驱动我的pb9输出,每隔一秒钟导致一次中断,因为我只在观察其中一个边沿。 If you have a switch you wont need any of that obviously. 如果您有开关,则显然不需要任何开关。

From what I can decipher, you want pin 3 as your interrupt line, but you set it as an OUTPUT Alt Function, according to the comment in the code. 据我所知,根据代码中的注释,您希望将引脚3作为中断线,但是将其设置为OUTPUT Alt Function。 To set a pin as an exti line it needs to be set as input pull-up/down and depending on how you wired the button, you need to set rising edge trigger or falling edge trigger , and also set the internal pull up/ down resistors so that there is an actual edge change. 要将引脚设置为外部线,需要将其设置为输入上拉/下拉,并根据您对按钮的接线方式进行设置,您需要设置上升沿触发或下降沿触发,还需要设置内部上拉/下拉电阻,以便有实际的边沿变化。

Example: 例:

PIN3-->Button-->Ground PIN3->按钮->地

to set Pin3 as ExtI3 set pin3 as INPUT with pull up/down (NOT AFIO) since pin3 becomes low when you press the button then set edge trigger to falling edge and ODR register must pull it high when the button is not pressed. 将Pin3设置为ExtI3,将pin3设置为带上拉/下拉输入(NOT AFIO),因为当您按下按钮时pin3变为低电平,然后将边沿触发设置为下降沿,并且当未按下按钮时ODR寄存器必须将其拉高。 So write 1 to the corresponding ODR bit. 因此,将1写入相应的ODR位。 then proceed to to the NVIC code and IRQn etc.... 然后转到NVIC代码和IRQn等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM