点亮STM32F103C8T6上的LED

点亮STM32F103C8T6上的LED,c,arm,embedded,stm32,stm32f1,C,Arm,Embedded,Stm32,Stm32f1,我正在尝试STM32F103C8T6上的LED灯(端口c上的针脚13)。我没有使用IDE。代码: #include "include/stm32f10x.h" int main() { RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; GPIOC->CRH &= ~GPIO_CRH_CNF13; GPIOC->CRH |= GPIO_CRH_MODE13_0; GPIOC->BSRR = GPIO

我正在尝试STM32F103C8T6上的LED灯(端口c上的针脚13)。我没有使用IDE。代码:

#include "include/stm32f10x.h"

int main()
{
    RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;

    GPIOC->CRH  &= ~GPIO_CRH_CNF13;
    GPIOC->CRH  |=  GPIO_CRH_MODE13_0;

    GPIOC->BSRR  = GPIO_BSRR_BR13;

    while(1)
    {
        GPIOC->BSRR = GPIO_BSRR_BS13;
    }

    return 0;
}
包含目录中文件的链接:

我就是这样编译的

arm none eabi gcc--specs=nosys.specs-o输出led.c


上传到mc后,什么也没有发生。

要点亮蓝色小球上的led,您需要PC13低电平(复位),因此使用gpioc bsrr寄存器中设置的复位位13进行写入,然后结束程序,使gpio线变高,关闭led

#include "include/stm32f10x.h"

int main()
{
    RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;

    GPIOC->CRH  &= ~GPIO_CRH_CNF13;
    GPIOC->CRH  |=  GPIO_CRH_MODE13_0;

    GPIOC->BSRR  = GPIO_BSRR_BR13;

    while(1)
    {
        continue;
    }

    return 0;
}
请看示意图

要明白这并不是一个普遍的真理。你必须看一下电路板的设计。此外,并非所有stm32f103c8t6芯片的引脚上都有led,但我假设这是一块stm32“蓝色药丸”板

编辑

该电路板的完整工作闪烁示例

flash.ld

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

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

.cpu cortex-m0
.thumb


.thumb_func
.global _start
_start:
stacktop: .word 0x20001000
.word reset
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang

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

.align

.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
眨眼器01.c

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

#define GPIOCBASE 0x40011000
#define RCCBASE 0x40021000

int notmain ( void )
{
    unsigned int ra;
    unsigned int rx;

    ra=GET32(RCCBASE+0x18);
    ra|=1<<4; //enable port c
    PUT32(RCCBASE+0x18,ra);
    //config
    ra=GET32(GPIOCBASE+0x04);
    ra&=~(3<<20);   //PC13
    ra|=1<<20;      //PC13
    ra&=~(3<<22);   //PC13
    ra|=0<<22;      //PC13
    PUT32(GPIOCBASE+0x04,ra);

    for(rx=0;;rx++)
    {
        PUT32(GPIOCBASE+0x10,1<<(13+0));
        for(ra=0;ra<200000;ra++) dummy(ra);
        PUT32(GPIOCBASE+0x10,1<<(13+16));
        for(ra=0;ra<200000;ra++) dummy(ra);
    }
    return(0);
}
包含和不包含thumb2扩展的构建(flash.s不必是thumb2扩展,只需要前面示例中的剩余内容)

现在,您要将什么文件以及如何将其上载到mcu?加载elf对您没有好处没有操作系统,但根据您使用的工具,它可能会读取elf并下载可加载的部分。我编写了自己的工具,因为它与bootloader uart接口的接口非常简单。我还将openocd与各种swd/jtag接口(stlink、j-link)一起使用来编写这些代码。它们来自亚洲,所以当你第一次解锁它们时,你知道你可以通过uart接口解锁,我很确定我也从openocd中找到了它

因此,要么你的二进制版本不好/无法正确引导,要么下载是问题所在(或者两者兼而有之)

stm32中的闪存映射为0x08000000,从应用程序引导时,它们会将其重新映射为0x00000000。也应该能够使用0x00000000,但我见过的大多数都使用0x08000000。如文件所述,复位时第一个字加载到堆栈指针中,第二个字是复位向量的拇指地址(lsbit设置为指示拇指,因此下面的0x41表示复位向量位于地址0x40,如图所示)

08000000:
8000000:20001000和CS r1、r0、r0
80000004:0800041 stmdaeq r0,{r0,r6}
80000008:0800047 stmdaeq r0,{r0,r1,r2,r6}
8000000C:0800047 stmdaeq r0,{r0,r1,r2,r6}
8000010:0800047 stmdaeq r0,{r0,r1,r2,r6}
8000014:0800047 stmdaeq r0,{r0,r1,r2,r6}
8000018:0800047 stmdaeq r0,{r0,r1,r2,r6}
800001c:0800047 stmdaeq r0,{r0,r1,r2,r6}
8000020:0800047 stmdaeq r0,{r0,r1,r2,r6}
8000024:0800047 stmdaeq r0,{r0,r1,r2,r6}
8000028:0800047 stmdaeq r0,{r0,r1,r2,r6}
800002c:0800047 stmdaeq r0,{r0,r1,r2,r6}
800030:0800047 stmdaeq r0,{r0,r1,r2,r6}
80000034:0800047 stmdaeq r0,{r0,r1,r2,r6}
8000018:0800047 stmdaeq r0,{r0,r1,r2,r6}
800003c:0800047 stmdaeq r0,{r0,r1,r2,r6}
08000040 :
800040:f000 f80a bl 800058
8000044:e7ff b.n 800046
08000046 :
800046:e7fe b.n 800046

对于初学者,您必须解决此问题,然后一旦有机会启动,您就可以查看代码。

您确定有一个LED连接到插脚C13,并且它被配置为高电平激活?当然,您可以编写我需要的配置吗?似乎现在我有输出模式10兆赫,通用输出推挽。是的,它在PC13中。我指的LED的“配置”是硬件,而不是软件。“STM32F103C8T6”指定微控制器-没有“LED”。任何LED都将特定于您的电路板;在这种情况下,您需要指定正在使用的电路板或指示LED如何连接到引脚(可能是示意图)。然而,最明显的尝试是将其设置为低而不是高——“开”状态取决于LED的连接方式。同样的结果,是的,我使用的是蓝色药丸。你必须从矢量表开始,向我们展示二进制文件的转储/反汇编,然后从那里开始。我对汇编有一点熟悉,所以我只做了
arm none eabi objdump-d输出
。是真的吗?这是你的第一个问题,它的构建是错误的,对于初学者来说,链接器脚本把它放在了错误的地方,你基本上是为linux构建的。没有矢量表虽然建议反转逻辑是合理的,甚至是显而易见的(对有经验和电子基础知识的人来说),但我很好奇你能假设使用的是特定的电路板。鉴于有许多STM32 COTS板,而且开发人员可能正在进行内部设计,我很好奇您是如何以如此明显的确定性得出这一假设的。我在STM32上工作了9年,直到你在这里提到之前,我从未听说过这个董事会。
arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m3 flash.s -o flash.o
arm-none-eabi-gcc -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding  -mthumb -mcpu=cortex-m0 -march=armv6-m -c blinker01.c -o blinker01.thumb.o
arm-none-eabi-ld -o blinker01.thumb.elf -T flash.ld flash.o blinker01.thumb.o
arm-none-eabi-objdump -D blinker01.thumb.elf > blinker01.thumb.list
arm-none-eabi-objcopy blinker01.thumb.elf blinker01.thumb.bin -O binary
arm-none-eabi-gcc -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding  -mthumb -mcpu=cortex-m3 -march=armv7-m -c blinker01.c -o blinker01.thumb2.o
arm-none-eabi-ld -o blinker01.thumb2.elf -T flash.ld flash.o blinker01.thumb2.o
arm-none-eabi-objdump -D blinker01.thumb2.elf > blinker01.thumb2.list
arm-none-eabi-objcopy blinker01.thumb2.elf blinker01.thumb2.bin -O binary
08000000 <_start>:
 8000000:   20001000    andcs   r1, r0, r0
 8000004:   08000041    stmdaeq r0, {r0, r6}
 8000008:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800000c:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000010:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000014:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000018:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800001c:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000020:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000024:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000028:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800002c:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000030:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000034:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000038:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800003c:   08000047    stmdaeq r0, {r0, r1, r2, r6}

08000040 <reset>:
 8000040:   f000 f80a   bl  8000058 <notmain>
 8000044:   e7ff        b.n 8000046 <hang>

08000046 <hang>:
 8000046:   e7fe        b.n 8000046 <hang>