Битовые поля сбрасывают hardfault после перезапуска

Когда я использую эту структуру сразу после перепрошивки устройства, она работает хорошо, но после перезапуска (включения / выключения питания) использование этой структуры (присваивает любой бит) вызывает 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

Решение

В файле ‘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 в момент выполнения, когда происходит это конкретное прерывание Hard-Fault, а затем сохраните все вышеуказанные данные в глобальном буфере, чтобы вы могли просматривать его после достижения while (1),

Затем обратитесь к разделу «Исключения и регистры ошибок Cortex-M» по адресу http://www.keil.com/appnotes/files/apnt209.pdf чтобы понять проблему, или опубликуйте результаты здесь, если вам нужна дополнительная помощь.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]