Firstly these guys have helped me enormously to understand the Arm microprocessor in an


assembly language environment and are well worth the read!



    We'll start by writing a very short and simple assembly program to blink Led1 on the Stm32 Mini.


After declaring a few equates, the program starts by firstly initialising the clock for PortA and setting Pin2 to a general purpose


output with a bandwidth of 50 Mhz. Unlike the AVR/PIC the Ports are synchronous and have their own clock!!!


    Led 1 on board the Stm32 Mini is set to Hi for 250mS and then to Low for 2 Seconds using the atomic BitSet/Reset Registers on PortA


The program then loops back to to the label "Blink" and the spiel repeats itself endlessly. Both delays are handled purely in software 


as for now .... (Hardware timers, Dma and interrupts are due later :-) ...! Use the manuals described in the introduction to


understand what's going on and all the best to ex-AVR programmers, who, just like I was, must be bewildered


by the apparent complexities of this powerful beast. We are using the excellent Keil uVision compiler Lite version, which


allows us to compile and link up to 32Kbytes of code free. It has a built in optimising compiler/simulator and to enable us


to use these super tools, I've decided for now to use the built-in loader/linker to initialise and call the assembly program. 


This comes with a fixed "C" overhead of 688 bytes but with 32Kbytes still free, I think we can afford it!


    Setting up the project using the Keil uVision Ide is relatively straight forward, if at first a bit time consuming; but once


done, it's amazing how easy it gets with a little practice and help and encouragement is always to be found here ;-)



__asm void Blinky() {

: BLINKY ( 72 Bytes of Assembler code + 688 bytes of C initialisation code )

GPIOA_CRL      equ 0x40010800        ; Gpio_A Base
RCC_CR            equ 0x40021000        ; Rcc Base
LedOne               equ 0x0004                ; Led 1
    ldr r1,=RCC_CR                             ; R1 = RCC_CR Base
    movw r0,#0x0004                             ; Enable PortA 
    str r0,[r1,#0x18]                              ; R0 > @RCC_APB2ENR 

    ldr r1,=GPIOA_CRL                     ; R1 > GPIOA_CRL Base 
    ldr r0,=0x44444344                         ; PortA_2 = General Push_Pull Output 
    str r0,[r1,#0x00]                             ; R0 > @GPIOA_CRL 
    movw r0,#LedOne                         ; Led1 On 
    str r0,[r1,#0x10]                             ; R0 > @GPIOA_BSRR 
    bl Dly250                                         ; [ Delay 250 MilliSeconds

    movw r0,#LedOne                         ; Led1 Off 
    str r0,[r1,#0x14]                             ; R0 > @GPIOA_BRR
    bl Dly02S                                         ; [ Delay 2 Seconds

    bal Blink                                         ; Loop back > Blink
; Delay Routines: Delay uS = R0*18
mS0250 EQU (250000*18)             ; 250 MilliSeconds Delay
mS2000 EQU (2000000*18)             ; 2000 MilliSeconds Delay
    ldr r0,=mS0250                         ; Delay = 250 mS 
    b Delay 
    ldr r0,=mS2000                         ; Delay = 2 Seconds 
    subs r0,r0,#1                             ; - Delay 
    bne Delay
    bx lr

   ALIGN                                     ; Pad out to an even two bytes
// Main C Routine
} int main() { Blinky(); }