Ярлыки

_GetPixelIndex (1) _SetPixelIndex (1) 3-phase (1) 800x480 (1) АЦП (1) генератор (1) синхронный усилитель (2) структура (1) учебный курс (1) шаговый двигатель (1) ШИМ (2) accert (1) AD7608 (1) AD8429 (1) ADC (5) amplifer (1) arccos (1) arcsin (1) arctang (2) arctg (3) ARM (2) arm_sqrt_q15 (2) assembler (6) ASSERT (1) atan (2) bit (1) Bitband (1) boot (3) bootlloader (1) BUTTON (1) C (5) C# (1) CAN (2) CC2530 (5) CMSIS (4) command (1) Cordic (1) Core746I (1) CubeMX (4) DBGMCU (2) debug (2) debug.ini (1) delegate (1) Digital Potentiometers (1) DigitalPOT (1) Discovery (1) DMA (9) DMA2D (1) DSP (1) DSP library (1) DWT (1) EFM32 (5) EmWin (9) EXTI (1) FATFS (1) FMC (2) FreeRTOS (2) gl868-dual cmux (1) GPIO (4) GUI (2) GUIBuilder (1) GUIDRV_CompactColor_16 (1) HAL (3) HappyGecko (1) Hard Fault (2) heap (1) I2C (1) ID (1) ILI9320 (1) ILI9325 (1) Initialisation (1) InitLTDC (1) Instrumentithion (1) Interrupt (4) ITR (1) JTAG (1) Keil (5) LCDConf (2) lock-in (1) LTCD (1) LTDC (3) main (1) memory (1) MINI_STM32 Revision 01 (1) nBoot0 (1) NVIC (1) OnePulse (2) OSAL (4) pack (1) phase (1) printf (3) Pulse (1) PWM (12) RCC (2) RCR (1) Register (1) RESET (2) RS232 (3) RSS (1) RTC (3) RTOS-RTX (1) RTT (1) RTX-RTOS (1) SDCard (1) SDRAM (6) Segger (2) SPI (3) sqrt (3) SSD1298 (1) SSD1963 (1) Standart Peripherial Library (3) STANDBAY (1) startup (1) STemWin (8) stepper motor (1) STlink (2) STM32 (17) STM32429ZI (1) STM32Cube (1) STM32DBG.IN (1) STM32F (28) STM32F0 (4) STM32F1 (13) STM32F4 (10) STM32F4 Discovery (1) STM32F407ZG (1) STM32F429 (2) STM32F746 (1) STOP (1) string (1) struct (1) SWD (1) SWD JTAG (1) Synhronization (1) system_stm32f4xx.c (1) SystemInit (1) SysTick (1) task (4) telit (1) TIM (27) typedef (1) UART (1) USART (9) viewer (2) WM_PAINT (1) Z-stack (5) ZigBee (5)
Показаны сообщения с ярлыком assembler. Показать все сообщения
Показаны сообщения с ярлыком assembler. Показать все сообщения

суббота, 14 февраля 2015 г.

STM32 Assembler routine sqrt modul

Функция подсчета модуля вектора (квадрат модуля не должен превышать 32 бита)

AREA |.text|, CODE, READONLY
sqrt_32 PROC
EXPORT sqrt_32 [WEAK]

MUL R0,R0,R0
MUL R1,R1,R1
ADD R0,R0,R1

;       Optimised 32-bit integer sqrt
;      INPUT
;       Calculates square root of R0
;      OUTPUT
;       Result returned in R0

вторник, 24 июня 2014 г.

Writing Assembly Code

#include <stdio.h>
int square(int i);
int main(void)
{
  int i;
  for (i=0; i<10; i++)
    {  
       printf("Square of %d is %d\n", i, square(i));
    }
 }
int square(int i)
{
return i*i;

}

C as ARM code

    AREA |.text|, CODE, READONLY
    EXPORT square
    ; int square(int i)
square
    MUL r1, r0, r0    ; r1 = r0 * r0
    MOV r0, r1         ; r0 = r1
    MOV pc, lr          ; return r0

    END

C as Thumb code

    AREA |.text|, CODE, READONLY
    EXPORT square
    ; int square(int i)
square
    MUL r1, r0, r0    ; r1 = r0 * r0
    MOV r0, r1         ; r0 = r1
    BX lr                    ; return r0

    END

суббота, 7 декабря 2013 г.

STM32 Assembler

Арифметические операции
ADDADD R0, R1, Operand2
ADD R0, R1, 12bit const.
Сложение
R0 = R1 + R2
N, Z, C, V S
ADCADC R0, R1, R2
ADC R0, R1, 8bit const
Сложение с учётом переноса
R0 = R1 + R2 + C
N, Z, C, VS
ADDWADD R0, R1, 12bit const.Сложение с 12bit константойN, Z, C, V
SUBSUB R0, R1, R2
SUB R0, R1, 12bit const.
Вычитание
R0 = R1 - R2
N, Z, C, VS
SBCSBC R0, R1, R2
SBC R0, R1, 8bit const.
Вычитание с учётом переноса
R0 = R1 - R2 - C
N, Z, C, VS
SUBWSUB R0, R1, 12bit const.Вычитание с 12bit константойN, Z, C, V
RSBRSB R0, R1, R2
RSB R0, R1, 8bit const.
RSB R0, R1, R2, ASR#23
Вычитание с противоположным порядком
аргументов.
R0 = R2 - R1 или R0 = 8bit const - R1
N, Z, C, VS

Умножение. Деление.
MUL
MLA
MLS
R0 = R1 x R2
R0 = (R1 x R2) + R3
R0 = R3 - (R1 x R2)
Умножение. 32bit результат
Умножение и сложение
Умножение и вычитание
N, ZS
UMULL
UMLAL
SMULL
SMLAL
RLo, RHi = R2 x R3
RLo, RHi += R2 x R3
RLo, RHi = R2 x R3
RLo, RHi += R2 x R3
Умножение. 64bit результат
Умножение и сложение
Умножение со знаком. 64bit результат
Умножение со знаком и сложение
UDIV
SDIV
R0 = R1 / R2
R0 = R1 / R2
Деление без знака
Деление со знаком

Доступ к памяти
ADRADR R0, label +/- 12bit
ADR.W R0, label +/- 32bit
Загрузка адреса метки в регистр.
LDR
STR
LDR R0, [R1, #8bit const.]! - прединкремент
LDR R0, [R1], #8bit const. - постинкремент
LDRB R0, [R1] - без инкремента
STRB R0, [R1], #1
Загрузка/сохранение регистра в режиме
адресации со смещением.
B=байт, SB=байт со знаком (только загрузка)
H=полуслово, SH=полуслово со знаком (только загрузка)
LDR
STR
LDR R0, [R1, R2, {LSL#0..3}]
STR R0, [R1, R2, {LSL#0..3}]
Смещение задаётся третьим регистром.
B, SB, H, SH работают аналогично
LDR
LDRD
LDR R0, label
LDRD R0, R1, label
Смещение задаётся адресом метки.
B, SB, H, SH работают аналогично
Невозможно применить к STR/STRD.
LDRT
STRT
Непривилегированный доступ.
Аналогичны простому LDR/STR.
LDRD
STRD
LDRD R0, R1, [R2, #10bit const.]! - прединкремент
LDRD R0, R1, [R2], #10bit const. - постинкремент
LDRD R0, R1, [R2] - без инкремента
STRD R0, R1, [R2]
Загрузка/сохранение двух регистров в режиме
адресации со смещением.
Константа должна быть кратна 4.
LDM
STM
LDM R0, {R1-R3}
LDM R0!, {R1-R3} - постинкремент R0
IA, DB, FD, EA - см. описание
Загрузка/сохранение множества регистров.
IA - с увеличением адреса
DB - с уменьшением адреса.
PUSH
POP
PUSH {R0, R2-R7, R12}
POP {R0, R2-R7, R12}
Загрузка/чтение из стека
LDREX
STREX
LDREX R1, [R2, #10bit const.]
STREX R0, R1, [R2, #10bit const.]
Эксклюзивное чтение/запись регистра.
B=байт, H=полуслово.
CLREXCLREX (без параметров)Сброс признака эксклюзивного доступа.

Перемещение и обработка данных
MOV
MVN
MOV R0, R1
MOV R0, 16bit const.
MVN R0, R1
Загрузка/перемещение регистров
Загрузка 16-бит в мл. полуслово, сброс старшего
Перемещение регистра с инверсией
N, Z, C, VS
MOVTMOVT R0, 16bit const.Загр. 16bit в старшее полуслово. Младш. остаётся без изменений.
CMP
CMN
CMP R0, R1
CMN R0, R1
Сравнение
Сравнение с противоположным знаком
N, Z, C, VS
TSTTST R0, Operand2Проверить значение битов по маскеN, Z, CS
TEQTEQ R0, Operand2Проверить равенство двух величинN, ZS
REV
REV16
REVSH
RBIT
REV R0, R1Изменение порядка битов или байтов в слове
CLZCLZ R0, R1Подсчет количества ведущих нулей

Логические операции
AND
ORR
EOR
BIC
ORN
И
ИЛИ
Исключающее ИЛИ
Сброс битов по маске. И-НЕ
ИЛИ-НЕ
0 в маске сбрасывает биты. Второй Operand2 для всех команд
1 в маске устанавливает биты
1 в маске инвертирует биты
1 в маске сбрасывает биты
0 в маске устанавливает биты
N, Z, CS

Операции сдвига
ASR
LSL
LSR
ROR
RRX
Арифметический сдвиг вправо
Логический сдвиг влево
Логический сдвиг вправо
Циклический сдвиг вправо
Сдвиг вправо на 1 позицию через перенос



N, Z, CS

Ветвление. Подпрограммы.
BB labelПереход к метке
BXBX R0Переход по адресу в регистре
BLBL labelВыполнить подпрограмму label
BLXBLX R0Выполнить подпрограмму по адресу в регистре
BX LRBX LRВозврат из подпрограммы
CBZ
CBNZ
CBZ R0, label
CBNZ R0, label
Переход, если R0 = 0
Переход, если R0 != 0
TBB
TBH
TBB [R0, R1]
TBH [R0, R1, LSL #1]
Табличный переход по индексу. Короткий переход.
Длиннй переход
ITIT{x{y{z}}} condБлок условно исполняемых инструкций

Работа с битовыми полями
BFCBFC R0, #lsb, #widthСброс поля в ноль
BFIBFI R0, R1, #lsb, #widthКопирует младшие биты R1 в поле R0
UBFXUBFX R0, R1, #lsb, #widthКопирует поле R1 в мл. биты R0 с заполнением нулями
SBFXSBFX R0, R1, #lsb, #widthКопирует поле R1 в мл. биты R0 с расширением знака
UXTB
UXTH
UXTB R0, R1 {, ROR #8,16,24}Преобразование байта с заполнением нулями
Преобразование полуслова
SXTB
SXTH
SXTB R0, R1 {, ROR #8,16,24}Преобразование байта с расширением знака
Преобразование полуслова

Преобразование данных с насыщением
SSAT
USAT
SSAT Rd, #n, Rm {, shift #s}
USAT Rd, #n, Rm {, shift #s}
Число со знаком в число со знаком,
Число со знаком в число без знака
Q

Управление системой
MRS
MSR
MRS R0, PSR
MSR PSR, R0
Чтение/запись специальных регистров.
CPSIE
CPSID
Разрешение/запрет прерываний
WFEWFEОжидать событие
WFIWFIОжидать прерывание
BKPTТочка останова
DMB
DSB
DMBБарьер синхронизации доступа к ОЗУ
ISBISBСброс конвейера
SEVSEVДёрнуть ножкой события для внешних камней
SVCSVC 8bit const.Вызов системного сервиса
NOPNOP

Суффиксы условного исполнения
EQZ = 1Равенство
NEZ = 0Неравенство
CS, HSC = 1Больше или равно, беззнаковое сравнение
CC, LOC = 0Меньше, беззнаковое сравнение
MIN = 1Отрицательное значение, меньше нуля
PLN = 0Положительное значение, больше или равно нулю
VSV = 1Переполнение
V = 0Нет переполнения
HIC = 1 и Z=0Больше, беззнаковое сравнение
LSC = 0 или Z=1Меньше или равно, беззнаковое сравнение
GEN = VБольше или равно, знаковое сравнение
LTN != VМеньше, знаковое сравнение
GTZ = 0 и N = VБольше, знаковое сравнение
LEZ = 1 и N != VМеньше или равно, знаковое сравнение
AL1Безусловное исполнение

Встроенные псевдоинструкции компиллятора
MOV32MOV32 R0, 32bit const. (label)Загрузить слово в регистр.
LDRLDR R0, =labelЗагрузить 32bit адрес метки или #число
ADRLADRL R0, labelЗагрузить 32bit адрес метки

суббота, 25 февраля 2012 г.

Assembler STM32F4 GPIO

Некоторые основные  команды ассемблера

Во-первых, загрузка большого числа (32 бита) в регистр.
LDR Rn, =число.

Rn — название регистра (R0, R1, ...), число — то, что хотим загрузить.
Например:
LDR R0, =0x40023830 ; Адрес регистра RCC_AHB1ENR

Для красоты и читабельности число можно заменить обозначением:
; Загрузим в регистр R0 адрес регистра RCC_AHB1ENR
LDR R0, =RCC_AHB1ENR

Обозначение должно быть объявлено в начале файла примерно так:
RCC_AHB1ENR EQU 0x40023830

Так можно обозвать любые константы и использовать их в коде.

Во-вторых, загрузка из памяти по заданному в регистре адресу.
LDR Rn, [Rm]

Rn — куда читаем,
Rm — адрес, откуда читаем.

Например, хотим прочитать, что записано в регистре RCC_AHB1ENR, адрес которого у нас хранится в регистре R0.
; Прочитаем в регистр R1 его содержимое
LDR R1, [R0]

Запись происходит аналогично, только команда называется STR:
; Запишем обратно
STR R1, [R0]

Между чтением и записью необходимо установить бит, отвечающий за тактирование порта D.
На помощь приходят команда логики OR.
ORR Rd, Ra, Rb
ORR Rd, Ra, #число

Rd — куда записывается результат;
Ra — первый операнд;
Rb — второй операнд;
число — вариант записи второго операнда прямо числом, если число удовлетворяет ряду требований (см. документацию).
Есть и иные варианты, но фиг с ними пока.

Пример: установка бита.
; Установим бит тактирования порта D
ORR R1, R1, #RCC_AHB1ENR_GPIODEN ; RCC_AHB1ENR_GPIODEN объявлен как 0x00000008, бит 3.

Точно так же записываются и ряд других логических и математических операций, список есть в мануале по ядру.
Зная это, уже можно настраивать периферию и даже моргать светодиодами. Но грузить каждый раз адрес регистра так не круто. Он лежит во флеше отдельно и ядру приходится делать лишний запрос.

Очень помогает в борьбе с этим косвенная адресация.
Типа как оператор -> в языке Си.

Записывается:
LDR Rn, [Rm, #смещение]
STR Rn, [Rm, #смещение]

То есть к адресу, записанном в Rm добавляется некоторое смещение прям вот так. Что удобно, смещение от базового адреса периферии для каждого регистра указано прямо в Referense Manual. Конечно, базовый адрес тоже указан.

Пример:
LDR R1, [R0, #GPIO_MODER_OFFSET] ; GPIO_MODER_OFFSET — смещение от базового адреса периферии GPIO до регистра MODER: 0x00000000

К слову, базовый адрес GPIOD: 0x40020C00. Все адреса можно подглядеть в даташите или Reference Manual.

Безусловный переход.
Бесконечный цикл делается с помощью этой команды. Выполнение продолжится с метки, указанной в аргументе:
B метка

Метка может располагаться как до команды, так и после неё.

Последнее, что требуется: задержка. Можно её оформить в виде отдельной процедуры.

Процедура оформляется так:
; Программная задержка
; R0 - величина задержки
delay PROC
; Какой-то полезный код
BX LR ; Возрат (типа return)
ENDP

BX LR — переход по адресу, записанному в регистре LR (R14). В этот регистр автоматически кладётся адрес команды, следующей за вызовом подпрограммы. Соответственно, эта команда осуществляет выход из процедуры.

Если есть вложенные процедуры, содержимое регистра надо сохранять, так как он перезаписывается автоматически при выполнении команд вызова подпрограммы вне зависимости от его содержания =) Но об этом потом.

Код задержки прост: принимаем число в регистре R0 и вычитаем его до тех пор, пока оно не станет 0.
; Вычитаем единицу
SUBS R0, R0, #1
; Пока не обнулилась, крутим дальше
BNE delay

Флаг S у процедуры SUB обозначает, что при выполнении команды будут выставлены флаги статуса, соответствующие результату выполнения. Ну, то есть, не ноль ли результат, было ли переполнение или заём и т.д.

Условный переход формируется из команды B и условного суффикса. Весь список можно посмотреть тут: Conditional execution.
В данном случае, выполняется проверка на «не ноль» (NE = Not Equal).

И последнее, вызов подпрограммы.
BL метка

метка — название подпрограммы. Пример:
BL delay

Именно команда перехода с суффиксом L сохраняет адрес следующей за ней команды в регистре LR.

Пример кода, моргающего светодиодами: