We'll continue this series with a short  assembly routine to read the state of Key2 on the Stm32 Mini. 


The keypress toggles Led1 and then it is debounced by a 250mS Delay. The routine is basically the same as  


the Blinky routine, with one new equate for Key2 and starts as usual by firstly initialising the clock for PortA 


and setting Pin2 to a general purpose Output and Pin1 as a default floating Input, which is held Hi by Resistor 7 (10k). 


When Key2 is momentarily depressed and released Led1 will be toggled from On to Off and back to On respectively in 


accordance  with the previous state of the Led. The s-suffix of the ands instruction  in the following piece of code from 


the program sets the condition flags to allow the following bne to take effect and this is another 


difference to be noted by ex-AVR assembler freaks!! 


    ldr r0,[r1,#0x08]                                 ; R0 < @GPIOA_IDR
s r0,r0, #Key_2                            ; Key2 = 0?
    bne GetKey                                        ; If not > Get Key


The GPIOx_IDR register is the basic Input Register Port for each of the Input Ports A,B,C,D and GPIOx_ODR is the 


corresponding basic Output Port and both input and output usage for PortA is demonstrated in this routine. 


The led state, pointed to by R1,  is first read into  R0 and R0 is then Exclusive-Or'd with the value 0x0002


and the result is then sent back out to PortA. Rather simple and basic is this program but it works just so beautifully and well!



__asm void PshBut() {
GPIOA_CRL     equ 0x40010800             ; GPIOA_CRL Base
RCC_CR            equ 0x40021000            ; RCC_CR Base
LedOne              equ 0x0004                     ; Led1
Key_2                 equ 0x0002                    ; Push Button 2
    ldr r1,=RCC_CR                                 ; R1 = RCC_CR Base
    movw r0,#0x0004                                 ; R0 =Enable PortA Clock 
    str r0,[r1,#0x18]                                  ; R0 > @RCC_APB2ENR 

    ldr r1,=GPIOA_CRL                          ; R1 > GPIOA_CRL Base 
    ldr r0,=0x44444344                             ; PortA_1=Key2:PortA_2=Led 
    str r0,[r1,#0x00]                                  ; R0 > @GPIOA_CRL 
    ldr r0,[r1,#0x08]                                 ; R0 < @GPIOA_IDR
    ands r0,r0, #Key_2                            ; Key2 = 0?
    bne GetKey                                        ; If not > Get Key

    ldr r0,[r1,#0x0c]                                 ; R0 < @GPIOA_0DR
    eor r0,r0, #LedOne                            ; Exor Led1 Pin 
    str r0,[r1,#0x0c]                                 ; R0 > @GPIOA_0DR 
    bl Dly250                                            ; [ 250 mS Key Debounce

    bal GetKey                                         ; > Get Key
; 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 
    bal Delay 
    ldr r0,=mS2000                                 ; Delay = 2 Seconds 
    subs r0,r0,#1                                     ; - Delay 
    bne Delay
    bx lr

    ALIGN                                             ; Pad out 

// Main C Routine
} int main() { PshBut(); }