cancel
Showing results for 
Search instead for 
Did you mean: 

LED blinking in assembler for STM32F103C8T6

JerryMC22
Associate III

Hello,

I am trying small example LED blinking written in assembly only - see below. LED is placed to PB15. I am able to compile the program without error using this commands:

arm-none-eabi-gcc -save-temps -nostdlib -nostartfiles -mcpu=cortex-m3 -ffreestanding -O2 led-stm32.s -o led-stm32.elf
arm-none-eabi-objcopy -O binary led-stm32.elf led-stm32.bin

I am using "gcc-arm-none-eabi-10.3-2021.10-win32.exe". I am able to write the program to processor STM32F103C8T6 using STLINKV2, but nothing happend. LED on PB15 is no blinking, LED is no shining. LED is off. .

Can someone help me where is problem ?  :)  Do you (someone) have working example in assembly ?

 

@@@ led-stm32.asm

@@@ Directives
        .cpu cortex-m3
        .code 16               @
        .syntax unified
        .global _start
        .align 2

@@@ Equates
        .equ GPIOB_CRH,   0x40010C04
        .equ GPIOB_ODR,   0x40010C0C
        .equ RCC_APB2ENR, 0x40021018
        .equ STACKINIT,   0x20005000

        .equ LEDDELAY,    0x4E20  @20000

.section .text
         .org 0

@@@ Vectors
vectors:
        .word STACKINIT         @ stack pointer value when stack is empty
        .word _start + 1        @ reset vector (manually adjust to odd for thumb)
        .word _nmi_handler + 1  @
        .word _hard_fault  + 1  @
        .word _memory_fault + 1 @
        .word _bus_fault + 1    @
        .word _usage_fault + 1  @

_start:

        @@ Enable the Port B peripheral clock by setting bit 4
        ldr r6, = RCC_APB2ENR
        mov r0, #0x08
        str r0, [r6]

        @@ Set the config and mode bits for Port B bit 15 so it will
        @@ be a open drain output (up to 8 MHz) by setting bits 19-16
        @@ to '0110'.

        ldr r6, = GPIOB_CRH
        ldr r0, = #0x64444444  @ 0110 0100 0100 0100 0100 0100 0100 0100
        str r0, [r6]

        @@ Load R2 and R3 with the "on" and "off" constants
        mov r2, #0              @ value to turn on LED
        mov r3, #0x8000         @ value to turn off LED

        ldr r6, = GPIOB_ODR    @  point to Port B output data register

loop:
        str r2, [r6]           @ clear Port B, pin 15, turning on LED
        ldr r1, = LEDDELAY
delay1:
        subs r1, #1
        bne delay1

        str r3, [r6]           @ set Port B, pin 15, turning off LED
        ldr r1, = LEDDELAY
delay2:
        subs r1, #1
        bne delay2

        b loop                 @ continue forever

_dummy:                        @ if any int gets triggered, just hang in a loop
_nmi_handler:
_hard_fault:
_memory_fault:
_bus_fault:
_usage_fault:
        add r0, #1
        add r1, #1
        b _dummy

 

3 REPLIES 3
Peter BENSCH
ST Employee

I haven't checked your code yet due to time constraints, but you can use my ASM example that I once created for STM32G4 and the STM32CubeIDE as a guide. As Cortex-M4 and Cortex-M3 are very similar, you only need to adapt the ASM syntax to your toolchain and check the register addresses.

Hope that helps?

Regards
/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

So, I tested your program in asm + CubeIDE, but I was NOT able to get the code up and running. So I downloaded free Keil MDK 5.4:1 and I found this example

https://www.youtube.com/watch?v=Zj4-fgRph1s

on youtube and the code is working ok. Source code is in attachments. The compiler is armclang. it means that I did not use the queer GNU arm assembler.

 

 

File1.asm

stackStartAddress  EQU 0x20000100
 
      AREA mySection1, DATA, READONLY
       
      DCD stackStartAddress
      DCD myResetHandler
       
      AREA mySection2, CODE, READONLY
      ENTRY
      
      
myResetHandler   
      IMPORT myApplication
       
      B myApplication
      
      END


File2.asm

      EXPORT myApplication
       
RCC        EQU 0x40021000
Port_C     EQU 0x40010C00
 
       
      AREA mySection3, CODE, READONLY
       
myApplication
      ; enable the APB2 clock
      
      MOV r0, #0x08
      LDR r1, =RCC
      STR r0, [r1, #0x18]


      ; configure the GPIO C for output

      MOV r0, #0x20000000
      LDR r1, =Port_C
      STR r0, [r1, #0x04]


      ; set the builtin LED on/off
      
      MOV r0, #0x0000 ; #0x8000
      STR r0, [r1, #0x0C]


      B .

      ALIGN

      END


First.sct – script for linker

LR_IROM1 0x08000000 0x00010000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00010000  {  ; load address = execution address
   file1.o (mySection1, +First)
   file1.o (mySection2)
   file2.o (mySection3)
   
   ; .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00005000  {  ; RW data
   .ANY (+RW +ZI)
  }
}
JerryMC22
Associate III

Hi Jerry,

I finally succeeded and LED PB15 blink example using GNU assebler is working ok :) See attached code.

gcc-arm-none-eabi-10.3-2021.10-win32.exe is used from  https://developer.arm.com/downloads/-/gnu-rm

:)