重新启动后,位字段为keil hardfault

时间:2014-01-15 21:38:49

标签: c++ c bit-fields stm32 keil

当我在闪存设备之后使用此结构时它运行良好,但在使用此结构重新启动(电源开/关)(分配给任何位)后会导致HardFault irq。我使用Keil uVision和STM32F205。为什么它不起作用?我应该更改/删除/添加什么来修复它?直接使用GPIOC-> ODR不会导致Kail中的位域有什么问题?

#pragma anon_unions

typedef union {
      struct {
        __IO uint16_t Data_Bus:8; // 0-7    data bus
        __IO uint16_t Ctr_Pins:6; // 8-13   control pins
        __IO uint16_t         :2; // 14-15  unused here
    };
    struct {
        __IO uint16_t D0:1; // 0   data bus pin
        __IO uint16_t D1:1; // 1   data bus pin
        __IO uint16_t D2:1; // 2   data bus pin
        __IO uint16_t D3:1; // 3   data bus pin
        __IO uint16_t D4:1; // 4   data bus pin
        __IO uint16_t D5:1; // 5   data bus pin
        __IO uint16_t D6:1; // 6   data bus pin
        __IO uint16_t D7:1; // 7   data bus pin
        // --------------------------------
        __IO uint16_t RS:1; // 8   reset
        __IO uint16_t CS:1; // 9   chip select
        __IO uint16_t CD:1; // 10  control / data
        __IO uint16_t RD:1; // 11  read tick
        __IO uint16_t WR:1; // 12  write tick
        __IO uint16_t EN:1; // 13  enable display
        // ---------------------------------
        __IO uint16_t   :1; // 14  unused
        __IO uint16_t LD:1; // 15  led
    };
} *PC_STRUCT_PTR, PC_STRUCT;

PC_STRUCT_PTR __TMP = (PC_STRUCT_PTR)(GPIOC_BASE+0x14);
#define PINOUTS (*__TMP)

它的使用方式如下:

void Write_Reg(unsigned char command)
{
    PINOUTS.CD = 0; PINOUTS.RD = 1; PINOUTS.CS = 0; PINOUTS.WR = 0;
    PINOUTS.Data_Bus = command; wait();
    PINOUTS.WR = 1; PINOUTS.CS = 1; PINOUTS.CD = 1; wait();
}

1 个答案:

答案 0 :(得分:0)

在文件'startup_stm32f20x.s'中,确保您拥有以下代码:

EXTERN  HardFault_Handler_C        ; this declaration is probably missing

__tx_vectors                       ; this declaration is probably there
    DCD     HardFault_Handler

然后,在同一个文件中,添加以下中断处理程序(所有其他处理程序所在的位置):

    PUBWEAK HardFault_Handler
    SECTION .text:CODE:REORDER(1)
HardFault_Handler
    TST LR, #4
    ITE EQ
    MRSEQ R0, MSP
    MRSNE R0, PSP
    B HardFault_Handler_C

然后,在文件'stm32f2xx.c'中,添加以下ISR:

void HardFault_Handler_C(unsigned int* hardfault_args)
{
    printf("R0    = 0x%.8X\r\n",hardfault_args[0]);         
    printf("R1    = 0x%.8X\r\n",hardfault_args[1]);         
    printf("R2    = 0x%.8X\r\n",hardfault_args[2]);         
    printf("R3    = 0x%.8X\r\n",hardfault_args[3]);         
    printf("R12   = 0x%.8X\r\n",hardfault_args[4]);         
    printf("LR    = 0x%.8X\r\n",hardfault_args[5]);         
    printf("PC    = 0x%.8X\r\n",hardfault_args[6]);         
    printf("PSR   = 0x%.8X\r\n",hardfault_args[7]);         
    printf("BFAR  = 0x%.8X\r\n",*(unsigned int*)0xE000ED38);
    printf("CFSR  = 0x%.8X\r\n",*(unsigned int*)0xE000ED28);
    printf("HFSR  = 0x%.8X\r\n",*(unsigned int*)0xE000ED2C);
    printf("DFSR  = 0x%.8X\r\n",*(unsigned int*)0xE000ED30);
    printf("AFSR  = 0x%.8X\r\n",*(unsigned int*)0xE000ED3C);
    printf("SHCSR = 0x%.8X\r\n",SCB->SHCSR);                
    while (1);
}

如果在执行此特定硬故障中断时无法在执行时使用printf,则将所有上述数据保存在全局缓冲区中,以便在到达{后可以查看它{1}}。

然后,请参阅http://www.keil.com/appnotes/files/apnt209.pdf上的'Cortex-M故障异常和寄存器'部分以了解问题,或者如果您需要进一步的帮助,请在此处发布输出。