我想确保已正确设置我的第一个嵌入式软件项目,因此正在尝试使STM324F11RE微控制器上的LED闪烁。我没有使用任何IDE,因为我想从头开始做所有事情。我的项目结构如下。
├── build
│ ├── Buggy.bin
│ ├── Buggy.dis
│ ├── Buggy.elf
│ ├── Buggy.hex
│ ├── Buggy.map
│ ├── main.o
│ ├── startup_stm32f411xe.o
│ ├── stm32f4xx_it.o
│ └── system_stm32f4xx.o
├── lib
│ ├── cmsis
│ │ ├── include
│ │ │ ├── arm_common_tables.h
│ │ │ ├── arm_const_structs.h
│ │ │ ├── arm_math.h
│ │ │ ├── core_cm0.h
│ │ │ ├── core_cm0plus.h
│ │ │ ├── core_cm3.h
│ │ │ ├── core_cm4.h
│ │ │ ├── core_cm7.h
│ │ │ ├── core_cmFunc.h
│ │ │ ├── core_cmInstr.h
│ │ │ ├── core_cmSimd.h
│ │ │ ├── core_sc000.h
│ │ │ └── core_sc300.h
│ │ └── stm32f4xx
│ │ ├── stm32f4xx.h
│ │ └── system_stm32f4xx.h
│ ├── Makefile
│ └── STM32F4xx_StdPeriph_Driver
│ ├── include
│ │ ├── misc.h
│ │ ├── stm32f4xx_adc.h
│ │ ├── stm32f4xx_crc.h
│ │ ├── stm32f4xx_dbgmcu.h
│ │ ├── stm32f4xx_dma.h
│ │ ├── stm32f4xx_exti.h
│ │ ├── stm32f4xx_flash.h
│ │ ├── stm32f4xx_flash_ramfunc.h
│ │ ├── stm32f4xx_gpio.h
│ │ ├── stm32f4xx_i2c.h
│ │ ├── stm32f4xx_iwdg.h
│ │ ├── stm32f4xx_pwr.h
│ │ ├── stm32f4xx_rcc.h
│ │ ├── stm32f4xx_rtc.h
│ │ ├── stm32f4xx_sdio.h
│ │ ├── stm32f4xx_spi.h
│ │ ├── stm32f4xx_syscfg.h
│ │ ├── stm32f4xx_tim.h
│ │ ├── stm32f4xx_usart.h
│ │ └── stm32f4xx_wwdg.h
│ ├── libstdperiph.a
│ ├── Makefile
│ └── src
│ ├── misc.c
│ ├── misc.o
│ ├── stm32f4xx_adc.c
│ ├── stm32f4xx_adc.o
│ ├── stm32f4xx_crc.c
│ ├── stm32f4xx_crc.o
│ ├── stm32f4xx_dbgmcu.c
│ ├── stm32f4xx_dbgmcu.o
│ ├── stm32f4xx_dma.c
│ ├── stm32f4xx_dma.o
│ ├── stm32f4xx_exti.c
│ ├── stm32f4xx_exti.o
│ ├── stm32f4xx_flash.c
│ ├── stm32f4xx_flash.o
│ ├── stm32f4xx_flash_ramfunc.c
│ ├── stm32f4xx_flash_ramfunc.o
│ ├── stm32f4xx_gpio.c
│ ├── stm32f4xx_gpio.o
│ ├── stm32f4xx_i2c.c
│ ├── stm32f4xx_i2c.o
│ ├── stm32f4xx_iwdg.c
│ ├── stm32f4xx_iwdg.o
│ ├── stm32f4xx_pwr.c
│ ├── stm32f4xx_pwr.o
│ ├── stm32f4xx_rcc.c
│ ├── stm32f4xx_rcc.o
│ ├── stm32f4xx_rtc.c
│ ├── stm32f4xx_rtc.o
│ ├── stm32f4xx_sdio.c
│ ├── stm32f4xx_sdio.o
│ ├── stm32f4xx_spi.c
│ ├── stm32f4xx_spi.o
│ ├── stm32f4xx_syscfg.c
│ ├── stm32f4xx_syscfg.o
│ ├── stm32f4xx_tim.c
│ ├── stm32f4xx_tim.o
│ ├── stm32f4xx_usart.c
│ ├── stm32f4xx_usart.o
│ ├── stm32f4xx_wwdg.c
│ └── stm32f4xx_wwdg.o
├── main.c
├── main.h
├── Makefile
├── startup_stm32f411xe.s
├── stm32f4xx_conf.h
├── stm32f4xx_flash.ld
├── stm32f4xx_it.c
├── stm32f4xx_it.h
└── system_stm32f4xx.c
我正在使用STD_Periph库来处理与实际硬件和CMSIS的接口,以对实际处理器核心和外围设备(我认为)进行硬件抽象。
main.c源文件应包含每秒使板上的LED闪烁的代码。
#include "stm32f4xx.h"
void TimingDelay_Decrement(void);
static __IO uint32_t uwTimingDelay;
static void Delay(__IO uint32_t nTime);
int main(void) {
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
while (1) {
GPIO_ToggleBits(GPIOD, GPIO_Pin_13);
Delay(1000);
}
}
void Delay(__IO uint32_t nTime)
{
uwTimingDelay = nTime;
while(uwTimingDelay != 0x00) {
uwTimingDelay--;
}
}
void TimingDelay_Decrement(void)
{
if (uwTimingDelay != 0x00)
{
uwTimingDelay--;
}
}
[当我使用make
命令使用Makefile构建项目时,一切都成功进行。然后,我运行make flash,它也成功完成。但是,没有一个LED每秒闪烁一次。我没有知识去了解问题所在,尤其是因为没有错误消息,因此调试起来很困难。我感觉到它与Makefile或链接脚本有关,因此我将在下面包含它们。
Makefile:
# STM32F4-Discovery Makefile
C_SRC=$(wildcard *.c) \
$(wildcard src/*.c)
# Add assembly source files here or use $(wildcard *.s) for all .s files
S_SRC = $(wildcard *.s)
# Project name
PROJ_NAME = Buggy
OUTPATH = build
BINPATH = /usr/bin/
OUTPATH := $(abspath $(OUTPATH))
BASEDIR := $(abspath ./)
MKDIR_P = mkdir -p
###################################################
# Check for valid float argument
# NOTE that you have to run make clean after
# changing these as hardfloat and softfloat are not
# binary compatible
ifneq ($(FLOAT_TYPE), hard)
ifneq ($(FLOAT_TYPE), soft)
#override FLOAT_TYPE = hard
override FLOAT_TYPE = soft
endif
endif
###################################################
AS=$(BINPATH)arm-none-eabi-as
CC=$(BINPATH)arm-none-eabi-gcc
LD=$(BINPATH)arm-none-eabi-gcc
OBJCOPY=$(BINPATH)arm-none-eabi-objcopy
OBJDUMP=$(BINPATH)arm-none-eabi-objdump
SIZE=$(BINPATH)arm-none-eabi-size
LINKER_SCRIPT = stm32f4xx_flash.ld
CPU = -mcpu=cortex-m4 -mthumb
CFLAGS = $(CPU) -c -std=gnu99 -g -O2 -Wall
LDFLAGS = $(CPU) -mlittle-endian -mthumb-interwork -Wl,--gc-sections,-Map=$(OUTPATH)/$(PROJ_NAME).map,--cref --specs=nano.specs
ifeq ($(FLOAT_TYPE), hard)
CFLAGS += -fsingle-precision-constant -Wdouble-promotion
CFLAGS += -mfpu=fpv4-sp-d16 -mfloat-abi=hard
else
CFLAGS += -msoft-float
endif
# Default to STM32F411xE if no device is passed
ifeq ($(DEVICE_DEF), )
DEVICE_DEF = STM32F411xE
endif
CFLAGS += -D$(DEVICE_DEF)
vpath %.a lib
# Includes
INCLUDE_PATHS = -I$(BASEDIR)/lib/cmsis/stm32f4xx -I$(BASEDIR)/lib/cmsis/include -I$(BASEDIR)
INCLUDE_PATHS += -I$(BASEDIR)/lib/STM32F4xx_StdPeriph_Driver/include
# Library paths
LIBPATHS = -L$(BASEDIR)/lib/STM32F4xx_StdPeriph_Driver
# Libraries to link
LIBS = -lstdperiph -lc -lgcc -lnosys
OBJS = $(C_SRC:.c=.o)
OBJS += $(S_SRC:.s=.o)
###################################################
.PHONY: lib proj
all: dir lib proj
$(SIZE) $(OUTPATH)/$(PROJ_NAME).elf
lib:
$(MAKE) -C lib FLOAT_TYPE=$(FLOAT_TYPE) BINPATH=$(BINPATH) DEVICE_DEF=$(DEVICE_DEF) BASEDIR=$(BASEDIR)
proj: $(OUTPATH)/$(PROJ_NAME).elf
.s.o:
$(AS) $(CPU) -o $(addprefix $(OUTPATH)/, $@) $<
.c.o:
$(CC) $(CFLAGS) -std=gnu99 $(INCLUDE_PATHS) -o $(addprefix $(OUTPATH)/, $@) $<
$(OUTPATH)/$(PROJ_NAME).elf: $(OBJS)
$(LD) $(LDFLAGS) -T$(LINKER_SCRIPT) $(LIBPATHS) -o $@ $(addprefix $(OUTPATH)/, $^) $(LIBS) $(LD_SYS_LIBS)
$(OBJCOPY) -O ihex $(OUTPATH)/$(PROJ_NAME).elf $(OUTPATH)/$(PROJ_NAME).hex
$(OBJCOPY) -O binary $(OUTPATH)/$(PROJ_NAME).elf $(OUTPATH)/$(PROJ_NAME).bin
$(OBJDUMP) -S --disassemble $(OUTPATH)/$(PROJ_NAME).elf > $(OUTPATH)/$(PROJ_NAME).dis
dir:
$(MKDIR_P) $(OUTPATH)
clean:
rm -f $(OUTPATH)/*.o
rm -f $(OUTPATH)/$(PROJ_NAME).elf
rm -f $(OUTPATH)/$(PROJ_NAME).hex
rm -f $(OUTPATH)/$(PROJ_NAME).bin
rm -f $(OUTPATH)/$(PROJ_NAME).dis
rm -f $(OUTPATH)/$(PROJ_NAME).map
# Remove the following line if you don't want to clean the Libraries as well
$(MAKE) clean -C lib
flash:
st-flash --reset write $(OUTPATH)/$(PROJ_NAME).bin 0x08000000
链接描述文件:
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20020000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;; /* required amount of heap */
_Min_Stack_Size = 0x400;; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH
/* Constant data goes into FLASH */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
/* used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections goes into RAM, load LMA copy after code */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM AT> FLASH
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(4);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(4);
} >RAM
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
编辑:
我已经安装了cubeMX并使用了其生成的代码。但是,闪烁的LED仍不可见。
这是我在main.c文件中的主要方法:
int main(void)
{
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
while (1) {
// write pin state
// NOTE: You can in turn use HAL_GPIO_TogglePin
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);
// synchronous delay for 500 ms
HAL_Delay(500);
}
}
我假设生成的代码正常运行,所以错误可能出在我的main.c中,或者仅仅是硬件问题。
如果这是您的第一个项目,请不要使用SPL(标准外围设备库)。 STM不再支持它,并且没有适用于较新STM32 uC的库。安装cubeMX并使用此工具项目生成的启动。