2

I'm trying to write the timer interrupt code I wrote in C (pa3 pin blinks at 10 ms intervals) with arm assembly language, I checked the tim2_cnt value in debug mode, it works fine, but when I look at tim2 from nvic, it is not enabled, it is in pending mode.I don't know exactly how to do the timer interrupt in assembly language.I tried to write my own code by looking at the disassembly feature from keil uvision. So where am I doing wrong? (I'm using stm32f103c8)

C code=

#include "stm32f10x.h"
 
void TIM2_IRQHandler()
{
    TIM2->SR =0x00;
    GPIOA->ODR ^=0x0008;//toggle pa3
}
 
int main(void)
{
    RCC->APB2ENR = 0x04; /// port a
    GPIOA->CRL   = 0x00003000; 
    __disable_irq();
    RCC->APB1ENR =0x1;// timer2 
    TIM2->ARR = 0xffff; 
    TIM2->PSC = 0x36;  // 10hz  
    TIM2->DIER = 0x1;// (OVERFLOW) 
    TIM2->CR1 = 0x1; // TIMx_CR1.CEN
    NVIC_EnableIRQ(TIM2_IRQn);
    __enable_irq();
    while(1)
    {
        
    }
}

Assembly code=

EXPORT Program
 
GPIOA_IDR          EQU 0x40010808
 
GPIOA_CRL          EQU 0x40010800
GPIOB_IDR          EQU 0x40010C08
GPIOA_ODR          EQU 0x4001080C
RCC_APB2ENR        EQU 0x40021000
RCC_APB1ENR        EQU 0x40021000
TIM2_ARR           EQU 0x4000002C
TIM2_PSC           EQU 0x40000028
TIM2_DIER          EQU 0x4000000C
TIM2_CR1           EQU 0x40000000
TIM2_SR            EQU 0x40000010
 
                   AREA start, CODE, READONLY             
timer_             MOVS     r0,#0x00
                   MOV      r1,#0x40000000
                   STRH     r0,[r1,#0x10]
                   LDR      r0,=GPIOA_ODR  
                   LDR      r0,[r0,#0x00]
                   EOR      r0,r0,#0x08
                   LDR      r1,=GPIOA_ODR  
                   STR      r0,[r1,#0x00] 
                   ADDS     R7,R7,#1         ;counter for debugging            
                   BX       LR
Program            MOVS     r0,#0x04
                   LDR      r1,=RCC_APB2ENR  
                   STR      r0,[r1,#0x18]
     ; pa3 out
                   MOV      r0,#0x3000
                   LDR      r1,=GPIOA_CRL  
                   STR      r0,[r1,#0x00]
 
                   ADDS     R11,R11,#1  
                   CPSID    I 
                   MOVS     r0,#0x01
                   LDR      r1,=RCC_APB1ENR  
                   STR      r0,[r1,#0x1C]
    ;        TIM2->ARR = 0xffff;  
                   MOVW     r0,#0xFFFF
                   LSLS     r1,r1,#18
                   STRH     r0,[r1,#0x2C]
    ;         TIM2->PSC = 54;  
                   MOVS     r0,#0x36
                   STRH     r0,[r1,#0x28]
    ;        TIM2->DIER = 0x1; 
                   MOVS     r0,#0x01
                   STRH     r0,[r1,#0x0C]
    ;         TIM2->CR1 = 0x1;  
                   STRH     r0,[r1,#0x00]
                   MOVS     r0,#0x1C
 
                   BL       timer_
                   CMP      r0,#0x00
                   BLT      interrupt ;
                   NOP
                   NOP
                   AND      r2,r0,#0x1F
                   MOVS     r1,#0x01
                   LSLS     r1,r1,r2
                   LSRS     r2,r0,#5
                   LSLS     r2,r2,#2
                   ADD      r2,r2,#0xE000E000
                   STR      r1,[r2,#0x100]
                   ADDS     R8,R8,#1      ;counter for debugging     
                   NOP
interrupt          NOP
                   ADDS     R5,R5,#1   ;counter for debugging                 
                   MOVS     R6,#0x3    ;control 
                   CPSIE    I
                   NOP
while              B        while    
                   MOVS     R6,#0x7
                   ALIGN
                   END
dogukanbicer
  • 25
  • 1
  • 5
  • 1
    Does your 'C' `TIM2_IRQHandler` handler works ? How do you set `timer_` to be an interrupt handler ? `STRH r0,[r1,#0x10]`, does `TIM2` timer has 16bit registers ? PS: invest a bit of a time in proper description, "but it doesn't work" as good explanation as nothing – user3124812 Jul 28 '21 at 10:36
  • c code is working properly. ; TIM2->SR =0x00;//interrupt flag active timer_ MOVS r0,#0x00 MOV r1,#0x40000000 STR r0,[r1,#0x10]; EOR r0,r0,#0x08;toggle for pa3 I don't know set timer_ to interrupt handler Assembly language. I wrote the assembly code mostly in C by looking at the disassembly feature in keil uvision 5 – dogukanbicer Jul 28 '21 at 18:51
  • My suggestion is, as with regular c, check with a debugger if the timer register values are correctly written and if the CNT is running. – Damiano Jul 29 '21 at 05:52
  • I checked the tim2_cnt value in debug mode, it works fine, but when I look at tim2 from nvic, it is not enabled, it is in pending mode. – dogukanbicer Jul 29 '21 at 09:17
  • I don't understand: if you have a working C code, you already have the assembly : it is the output of the the compilation... – Guillaume Petitjean Jul 30 '21 at 09:46
  • You are right, but the assembly code in the c compiler is unnecessarily long. I want to write a more optimized assembly code myself. – dogukanbicer Jul 30 '21 at 11:32

0 Answers0