STM32F401RE 使用 CMSIS 库时用户 LED 不会亮起,但不使用时会亮起

问题描述 投票:0回答:1

我一直在遵循本指南,https://github.com/cpq/bare-metal-programming-guide,开始使用 STM32 MCU 进行编程,而不使用 CubeMX,只是为了了解更多信息。我已经能够运行这些示例并让它们在我的核板上运行。现在我在使用 CMSIS 库时遇到了一个问题,我似乎无法查明该问题。我能够正确地刷新电路板,没有错误,但是,我无法打开 LED。我浏览了该库并将其与我的其他项目进行了比较,以确保寄存器的地址是正确的,而且它们是正确的。

以下代码是我的main.c:

#include "mcu.h"

static volatile uint32_t s_ticks;
void SysTick_Handler(void) {
  s_ticks++;
}

uint32_t SystemCoreClock = FREQ;
void SystemInit(void) {
  RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;    // Enable SYSCFG
  SysTick_Config(SystemCoreClock / 1000);  // Tick every 1 ms
}

int main(void) {
  uint16_t led = PIN('A', 5);                 // Blue LED
  gpio_set_mode(led, GPIO_MODE_OUTPUT);       // Set blue LED to output mode
  volatile uint32_t timer = 0, period = 500;  // Declare timers
  for (;;) {
    if (timer_expired(&timer, period, s_ticks)) {
      static bool on;       // This block is executed
      gpio_write(led, on);  // Every `period` milliseconds
      on = !on;             // Toggle LED state
    }
  }
  return 0;
}

我已经在我的其他项目中对此进行了测试,这些项目没有使用 CMSIS 文件,并且它有效。 接下来是我的 mcu.h 标头:

#pragma once

#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

#include "stm32f401xe.h"

#define FREQ 16000000  // CPU frequency, 16 Mhz
#define BIT(x) (1UL << (x))
#define PIN(bank, num) ((((bank) - 'A') << 8) | (num))
#define PINNO(pin) (pin & 255)
#define PINBANK(pin) (pin >> 8)

static inline void spin(volatile uint32_t count) {
  while (count--) asm("nop");
}

#define GPIO(bank) ((GPIO_TypeDef *) (GPIOA_BASE + 0x400U * (bank)))
enum { GPIO_MODE_INPUT, GPIO_MODE_OUTPUT, GPIO_MODE_AF, GPIO_MODE_ANALOG };

static inline void gpio_set_mode(uint16_t pin, uint8_t mode) {
  GPIO_TypeDef *gpio = GPIO(PINBANK(pin));  // GPIO bank
  int n = PINNO(pin);                       // Pin number
  RCC->AHB1ENR |= BIT(PINBANK(pin));        // Enable GPIO clock
  gpio->MODER &= ~(3U << (n * 2));          // Clear existing setting
  gpio->MODER |= (mode & 3U) << (n * 2);    // Set new mode
}

static inline void gpio_set_af(uint16_t pin, uint8_t af_num) {
  GPIO_TypeDef *gpio = GPIO(PINBANK(pin));  // GPIO bank
  int n = PINNO(pin);                       // Pin number
  gpio->AFR[n >> 3] &= ~(15UL << ((n & 7) * 4));
  gpio->AFR[n >> 3] |= ((uint32_t) af_num) << ((n & 7) * 4);
}

static inline void gpio_write(uint16_t pin, bool val) {
  GPIO_TypeDef *gpio = GPIO(PINBANK(pin));
  gpio->BSRR = (1U << PINNO(pin)) << (val ? 0 : 16);
}

static inline bool timer_expired(volatile uint32_t *t, uint32_t prd,
                                 uint32_t now) {
  if (now + prd < *t) *t = 0;                    // Time wrapped? Reset timer
  if (*t == 0) *t = now + prd;                   // Firt poll? Set expiration
  if (*t > now) return false;                    // Not expired yet, return
  *t = (now - *t) > prd ? now + prd : *t + prd;  // Next expiration time
  return true;                                   // Expired, return true
}

这里的功能也与我的其他项目非常相似,唯一的区别是使用 GPIO_TypeDef 而不是以前使用的 gpio 结构体。

最后一个文件是我的Makefile:

CFLAGS  ?=  -W -Wall -Wextra -Werror -Wundef -Wshadow -Wdouble-promotion \
            -Wformat-truncation -fno-common -Wconversion \
            -g3 -Os -ffunction-sections -fdata-sections \
            -I. -Iinclude -Icmsis_core/CMSIS/Core/Include -Icmsis_f4/Include \
            -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 $(EXTRA_CFLAGS)
LDFLAGS ?= -Tlink.ld -nostartfiles -nostdlib --specs nano.specs -lc -lgcc -Wl,--gc-sections -Wl,[email protected]
SOURCES = main.c syscalls.c
SOURCES += cmsis_f4/Source/Templates/gcc/startup_stm32f401xe.s

ifeq ($(OS),Windows_NT)
  RM = cmd /C del /Q /F
else
  RM = rm -rf
endif

build: firmware.bin

firmware.elf: cmsis_core cmsis_f4 mcu.h link.ld Makefile $(SOURCES) 
    arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(CFLAGS_EXTRA) $(LDFLAGS) -o $@

firmware.bin: firmware.elf
    arm-none-eabi-objcopy -O binary $< $@

flash: firmware.bin
    st-flash --reset write $< 0x8000000

cmsis_core:
    git clone --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@

cmsis_f4:
    git clone --depth 1 -b v2.6.9 https://github.com/STMicroelectronics/cmsis_device_f4 $@

clean:
    $(RM) firmware.* cmsis_*

我还有一个startup.c和链接器文件,如下:

#include <sys/stat.h>
#include "mcu.h"

int _fstat(int fd, struct stat *st) {
  if (fd < 0) return -1;
  st->st_mode = S_IFCHR;
  return 0;
}

void *_sbrk(int incr) {
  extern char _end;
  static unsigned char *heap = NULL;
  unsigned char *prev_heap;
  if (heap == NULL) heap = (unsigned char *) &_end;
  prev_heap = heap;
  heap += incr;
  return prev_heap;
}

int _open(const char *path) {
  (void) path;
  return -1;
}

int _close(int fd) {
  (void) fd;
  return -1;
}

int _isatty(int fd) {
  (void) fd;
  return 1;
}

int _lseek(int fd, int ptr, int dir) {
  (void) fd, (void) ptr, (void) dir;
  return 0;
}

void _exit(int status) {
  (void) status;
  for (;;) asm volatile("BKPT #0");
}

void _kill(int pid, int sig) {
  (void) pid, (void) sig;
}

int _getpid(void) {
  return -1;
}

int _read(int fd, char *ptr, int len) {
  (void) fd, (void) ptr, (void) len;
  return -1;
}

int _link(const char *a, const char *b) {
  (void) a, (void) b;
  return -1;
}

int _unlink(const char *a) {
  (void) a;
  return -1;
}

int _stat(const char *path, struct stat *st) {
  (void) path, (void) st;
  return -1;
}

int mkdir(const char *path, mode_t mode) {
  (void) path, (void) mode;
  return -1;
}

void _init(void) {
}
ENTRY(Reset_Handler);
MEMORY {
    flash(rx)   : ORIGIN = 0x08000000, LENGTH = 512k
    sram(rwx)   : ORIGIN = 0x20000000, LENGTH = 96k
}
_estack     = ORIGIN(sram) + LENGTH(sram);

SECTIONS { 
    .vectors    : { KEEP(*(.vectors)) }  > flash
    .text       : { *(.text*) }          > flash
    .rodata     : { *(.rodata*) }        > flash

    .data : {
        _sdata = .;
        *(.first_data)
        *(.data SORT(.data.*))
        _edata = .;
    } > sram AT > flash
    _sidata = LOADADDR(.data);

    .bss : {
        _sbss = .;
        *(.bss SORT(.bss.*) COMMON)
        _ebss = .;
    } > sram

    . = ALIGN(8);
    _end = .;
}

这些文件与我的其他项目大部分没有变化。唯一的不同是添加了 Reset_Handler,因为它也来自 CMSIS 库。

我一定在某个地方犯了一个错误,因为供应商库已经过尝试并且是真实的,但我似乎无法找到它。预先感谢您的阅读!

c stm32 stm32f4 cmsis
1个回答
0
投票

你尝试过

gpio_write(led, off);
吗?

© www.soinside.com 2019 - 2024. All rights reserved.