Guest User

STM32F10 SysTick Timer ASM (RU)

a guest
Jun 4th, 2021
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ARM 4.67 KB | None | 0 0
  1. @@ Таймер SysTick
  2.  
  3. .syntax unified
  4. .cpu cortex-m3
  5. .thumb
  6. .global _start
  7.  
  8.     @; Интервал переключения диода на PC13, миллисекунд :
  9.  
  10.         LED_TOGGLE_TIME_ms = 3000 / 2
  11.  
  12.     @; регистры, биты и макросы :
  13.  
  14.         SCB_VTOR    = 0xe000ed00 + 0x08
  15.  
  16.         STK         = 0xe000e010
  17.         STK_CTRL    = STK + 0x00
  18.         STK_LOAD    = STK + 0x04
  19.         STK_VAL     = STK + 0x08
  20.          COUNTFLAG  = 1 << 16
  21.  
  22.         RCC_APB2ENR = 0x40021000 + 0x18
  23.          IOPCEN     = 1 << 4
  24.  
  25.         GPIOC       = 0x40011000
  26.         GPIOC_CR    = GPIOC + 0x00
  27.         GPIOC_ODR   = GPIOC + 0x0c
  28.          PC13       = 1 << 13
  29.          O_OPEN_DRAIN = 0b0101
  30.  
  31.         .macro WriteReg reg, val
  32.             ldr r0, =\reg
  33.             ldr r1, =\val
  34.             str r1, [r0]
  35.         .endm
  36.  
  37.         .macro ConfigPin gpio, pin, conf
  38.             ldr r0, =\gpio + \pin / 8 * 4
  39.             ldr r1, [r0]
  40.             ldr r2, =\conf
  41.             bfi r1, r2, #\pin % 8 * 4, #4
  42.             str r1, [r0]
  43.         .endm
  44.  
  45.  
  46. .text
  47.     vectors:
  48.         .word 0x20005000        @; значение sp
  49.         .word _start + 1        @; reset; адрес начала программы + 1
  50.  
  51.     @; убери /** и **/, если собираешься
  52.     @; использовать прерывание таймера.
  53.     @; вектор этого прерывания находится
  54.     @; по адресу 0x3c относительно начала
  55.     @; таблицы векторов
  56.     /**
  57.         .org vectors + 0x3c
  58.         .word stk_int + 1       @; systick; адрес обработчика + 1
  59.  
  60.     stk_int:
  61.         @; здесь надо написать что будет,
  62.         @; когда сработает прерывание (когда
  63.         @; таймер досчитает до нуля),
  64.         @; например:
  65.             @; ldr r0, =GPIOC_ODR
  66.             @; ldr r1, [r0]
  67.             @; eor r1, #PC13
  68.             @; str r1, [r0]
  69.  
  70.         @; возвращаемся из прерывания :
  71.  
  72.             bx lr
  73.     **/
  74.  
  75.     _start:
  76.         @; (важно!)
  77.         @; если не менять регистр SCB_VTOR, то
  78.         @; прерывания могут не работать сразу после
  79.         @; запуска кода ЗАГРУЗЧИКОМ и при компиляции
  80.         @; для адресов, отличных от 0x00000000,
  81.         @; 0x08000000 и 0x20000000.
  82.  
  83.             @; WriteReg SCB_VTOR, vectors
  84.  
  85.         @; настраивам выход PC13 :
  86.  
  87.             WriteReg RCC_APB2ENR, IOPCEN
  88.             ConfigPin GPIOC_CR, 13, O_OPEN_DRAIN
  89.  
  90.         @; (необязательно)
  91.         @; сбрасываем таймер, если он раньше
  92.         @; был запущен, например, загрузчиком  :
  93.  
  94.             @; WriteReg STK_CTRL, 0
  95.             @; WriteReg STK_VAL, 0
  96.  
  97.         @; записываем в таймер время в микросекундах,
  98.         @; как только таймер досчитает до 0, он начнёт сначала;
  99.         @; максимум ~ 16 секунд (2^24 микросекунд) :
  100.  
  101.             WriteReg STK_LOAD, 1000 * LED_TOGGLE_TIME_ms
  102.  
  103.         @; запускаем таймер (если нужно прерывание,
  104.         @; то запиши 3, а не 1) :
  105.  
  106.             WriteReg STK_CTRL, 1
  107.  
  108.         @; в данный момент прерывание таймера не используется
  109.         @; и в основнм цикле мы росто проверяем состояние
  110.         @; таймера. с прерыванием таймер не надо проверять:
  111.         @; при его срабатывании контроллер сам выолнит
  112.         @; функцию-обработчик прерывания (stk_int).
  113.  
  114.         @; в случае, когда используется прерывание,
  115.         @; основной цикл может быть сокращён до
  116.  
  117.         @;  main_loop:
  118.         @;      b main_loop
  119.  
  120.         main_loop:
  121.             @; ждём пока таймер досчитает до 0 :
  122.                 ldr r0, =STK_CTRL
  123.                 ldr r0, [r0]
  124.                 tst r0, #COUNTFLAG
  125.                 beq main_loop
  126.  
  127.             @; досчиал, переключаем светодиод :
  128.                 ldr r0, =GPIOC_ODR
  129.                 ldr r1, [r0]
  130.                 eor r1, #PC13
  131.                 str r1, [r0]
  132.  
  133.             @; повторяем основной цикл :
  134.                 b main_loop
  135. .end
  136.  
Advertisement
Add Comment
Please, Sign In to add comment