разработка STM32 + asm
Форум — Development
Всем доброго времени суток! Недавно начал розбиратся с микроконтроллером stm32f103c8t6.
Код прошивки решено было писать на ассемблере.
@ Compiler settings
.syntax unified
.thumb
.cpu cortex-m3
@ Global Variables
.equ TIMER_FREQUENCY ,0x00001500
@ Libs
.include "libs/stm32f10x.inc"
.include "libs/stm32.inc"
.include "libs/time.inc"
@ Program
.section .text
.word 0x20005000 @ Стек
.word Reset+1 @ Адрес перехода при сбросе.
Reset:
RCC_CLOCK_SET RCC_APB2ENR, RCC_APB2Periph_GPIOC
GPIO_MODE_SET GPIOC_BASE, GPIO_CRH, 0x22222222
BLINK_LOOP:
GPIO_STATE_SET GPIOC_BASE, 0x0000FFFF
DELAY 1000
GPIO_STATE_SET GPIOC_BASE, 0xFFFF0000
DELAY 1000
B BLINK_LOOP
FUNC_DELAY:
MOV32 R2, TIMER_FREQUENCY
MUL R2, R3
DELAY_LOOP: SUBS R2, R2, 1
BNE DELAY_LOOP
BX LR
time.inc
.macro DELAY time
MOV32 R3, \time
BL FUNC_DELAY
.endm
stm32.inc
.macro MOV32 regnum,number
MOVW \regnum,:lower16:\number
MOVT \regnum,:upper16:\number
.endm
.macro RCC_CLOCK_SET RCC_APB, RCC_APBPeriph
MOV32 R0, RCC_BASE + \RCC_APB @ адрес
MOV32 R1, \RCC_APBPeriph @ значение
LDR R2, [R0] @ прочитали значение регистра
ORR R1, R1, R2 @ логическое, побитовое ИЛИ : R1= R1 ИЛИ R2
STR R1, [R0] @ запись R1 по адресу указанному в R0
.endm
.macro GPIO_MODE_SET GPIO_BASE, GPIO, GPIO_PIN
MOV32 R0, \GPIO_BASE + \GPIO
MOV32 R1, \GPIO_PIN
LDR R2, [R0]
ORR R1, R1, R2
STR R1, [R0]
.endm
.macro GPIO_STATE_SET GPIO_BASE, GPIO_PIN
MOV32 R0, \GPIO_BASE + GPIO_BSRR
MOV32 R1, \GPIO_PIN
STR R1, [R0]
.endm
stm32f10x.inc
@ <MEMORY>
.equ FLASH_BASE ,0x08000000
.equ SRAM_BASE ,0x20000000
.equ PERIPH_BASE ,0x40000000
@ <Peripheral memory map>
.equ APB1PERIPH_BASE ,PERIPH_BASE
.equ APB2PERIPH_BASE ,PERIPH_BASE + 0x10000
.equ AHBPERIPH_BASE ,PERIPH_BASE + 0x20000
@ <GPIO>
.equ GPIO_BSRR ,0x10
.equ GPIO_CRL ,0x00 @ pin 0-7
.equ GPIO_CRH ,0x04 @ pin 8-15
.equ GPIO_IDR ,0x08
.equ GPIO_ODR ,0x0C
.equ GPIO_BRR ,0x14
.equ GPIO_LCKR ,0x18
.equ GPIOA_BASE ,APB2PERIPH_BASE + 0x0800
.equ GPIOB_BASE ,APB2PERIPH_BASE + 0x0C00
.equ GPIOC_BASE ,APB2PERIPH_BASE + 0x1000
.equ GPIOD_BASE ,APB2PERIPH_BASE + 0x1400
.equ GPIOE_BASE ,APB2PERIPH_BASE + 0x1800
.equ GPIOF_BASE ,APB2PERIPH_BASE + 0x1C00
.equ GPIOG_BASE ,APB2PERIPH_BASE + 0x2000
@ <RCC>
.equ RCC_BASE ,AHBPERIPH_BASE + 0x1000
.equ RCC_APB1RSTR ,0x10
.equ RCC_APB2RSTR ,0x0C
.equ RCC_AHBENR ,0x14
.equ RCC_APB1ENR ,0x1C
.equ RCC_APB2ENR ,0x18
.equ RCC_RCC_CIR ,0x08
.equ RCC_BDCR ,0x20
@ <RCC_PERIPH>
.equ RCC_AHBPeriph_DMA1 ,0x00000001
.equ RCC_AHBPeriph_DMA2 ,0x00000002
.equ RCC_AHBPeriph_SRAM ,0x00000004
.equ RCC_AHBPeriph_FLITF ,0x00000010
.equ RCC_AHBPeriph_CRC ,0x00000040
.equ RCC_APB2Periph_AFIO ,0x00000001
.equ RCC_APB2Periph_GPIOA ,0x00000004
.equ RCC_APB2Periph_GPIOB ,0x00000008
.equ RCC_APB2Periph_GPIOC ,0x00000010
.equ RCC_APB2Periph_GPIOD ,0x00000020
.equ RCC_APB2Periph_GPIOE ,0x00000040
.equ RCC_APB2Periph_GPIOF ,0x00000080
.equ RCC_APB2Periph_GPIOG ,0x00000100
.equ RCC_APB2Periph_ADC1 ,0x00000200
.equ RCC_APB2Periph_ADC2 ,0x00000400
.equ RCC_APB2Periph_TIM1 ,0x00000800
.equ RCC_APB2Periph_SPI1 ,0x00001000
.equ RCC_APB2Periph_TIM8 ,0x00002000
.equ RCC_APB2Periph_USART1 ,0x00004000
.equ RCC_APB2Periph_ADC3 ,0x00008000
.equ RCC_APB2Periph_TIM15 ,0x00010000
.equ RCC_APB2Periph_TIM16 ,0x00020000
.equ RCC_APB2Periph_TIM17 ,0x00040000
.equ RCC_APB2Periph_TIM9 ,0x00080000
.equ RCC_APB2Periph_TIM10 ,0x00100000
.equ RCC_APB2Periph_TIM11 ,0x00200000
.equ RCC_APB1Periph_TIM2 ,0x00000001
.equ RCC_APB1Periph_TIM3 ,0x00000002
.equ RCC_APB1Periph_TIM4 ,0x00000004
.equ RCC_APB1Periph_TIM5 ,0x00000008
.equ RCC_APB1Periph_TIM6 ,0x00000010
.equ RCC_APB1Periph_TIM7 ,0x00000020
.equ RCC_APB1Periph_TIM12 ,0x00000040
.equ RCC_APB1Periph_TIM13 ,0x00000080
.equ RCC_APB1Periph_TIM14 ,0x00000100
.equ RCC_APB1Periph_WWDG ,0x00000800
.equ RCC_APB1Periph_SPI2 ,0x00004000
.equ RCC_APB1Periph_SPI3 ,0x00008000
.equ RCC_APB1Periph_USART2 ,0x00020000
.equ RCC_APB1Periph_USART3 ,0x00040000
.equ RCC_APB1Periph_UART4 ,0x00080000
.equ RCC_APB1Periph_UART5 ,0x00100000
.equ RCC_APB1Periph_I2C1 ,0x00200000
.equ RCC_APB1Periph_I2C2 ,0x00400000
.equ RCC_APB1Periph_USB ,0x00800000
.equ RCC_APB1Periph_CAN1 ,0x02000000
.equ RCC_APB1Periph_CAN2 ,0x04000000
.equ RCC_APB1Periph_BKP ,0x08000000
.equ RCC_APB1Periph_PWR ,0x10000000
.equ RCC_APB1Periph_DAC ,0x20000000
.equ RCC_APB1Periph_CEC ,0x40000000
@ <BSSR>
.equ GPIO_BSRR_BS0 ,0x00000001 @< Port x Set bit 0
.equ GPIO_BSRR_BS1 ,0x00000002 @< Port x Set bit 1
.equ GPIO_BSRR_BS2 ,0x00000004 @< Port x Set bit 2
.equ GPIO_BSRR_BS3 ,0x00000008 @< Port x Set bit 3
.equ GPIO_BSRR_BS4 ,0x00000010 @< Port x Set bit 4
.equ GPIO_BSRR_BS5 ,0x00000020 @< Port x Set bit 5
.equ GPIO_BSRR_BS6 ,0x00000040 @< Port x Set bit 6
.equ GPIO_BSRR_BS7 ,0x00000080 @< Port x Set bit 7
.equ GPIO_BSRR_BS8 ,0x00000100 @< Port x Set bit 8
.equ GPIO_BSRR_BS9 ,0x00000200 @< Port x Set bit 9
.equ GPIO_BSRR_BS10 ,0x00000400 @< Port x Set bit 10
.equ GPIO_BSRR_BS11 ,0x00000800 @< Port x Set bit 11
.equ GPIO_BSRR_BS12 ,0x00001000 @< Port x Set bit 12
.equ GPIO_BSRR_BS13 ,0x00002000 @< Port x Set bit 13
.equ GPIO_BSRR_BS14 ,0x00004000 @< Port x Set bit 14
.equ GPIO_BSRR_BS15 ,0x00008000 @< Port x Set bit 15
.equ GPIO_BSRR_BR0 ,0x00010000 @< Port x Reset bit 0
.equ GPIO_BSRR_BR1 ,0x00020000 @< Port x Reset bit 1
.equ GPIO_BSRR_BR2 ,0x00040000 @< Port x Reset bit 2
.equ GPIO_BSRR_BR3 ,0x00080000 @< Port x Reset bit 3
.equ GPIO_BSRR_BR4 ,0x00100000 @< Port x Reset bit 4
.equ GPIO_BSRR_BR5 ,0x00200000 @< Port x Reset bit 5
.equ GPIO_BSRR_BR6 ,0x00400000 @< Port x Reset bit 6
.equ GPIO_BSRR_BR7 ,0x00800000 @< Port x Reset bit 7
.equ GPIO_BSRR_BR8 ,0x01000000 @< Port x Reset bit 8
.equ GPIO_BSRR_BR9 ,0x02000000 @< Port x Reset bit 9
.equ GPIO_BSRR_BR10 ,0x04000000 @< Port x Reset bit 10
.equ GPIO_BSRR_BR11 ,0x08000000 @< Port x Reset bit 11
.equ GPIO_BSRR_BR12 ,0x10000000 @< Port x Reset bit 12
.equ GPIO_BSRR_BR13 ,0x20000000 @< Port x Reset bit 13
.equ GPIO_BSRR_BR14 ,0x40000000 @< Port x Reset bit 14
.equ GPIO_BSRR_BR15 ,0x80000000 @< Port x Reset bit 15
На этапе компиляции никаких ошибок не возникает. Прошивка нормально заливается в микроконтроллер. Светодиод на плате моргает, но проверка пинов мультиметром показывает что питание на порты не подается(напряжение на порту C13(порт встроеного светодиода) скачет в приделах от 0 до 2 вольт, при чем 2 вольта появляется когда светодиод гаснет).
Подозрения в параметрах, передаваемых компилятору или линковщику
Makefile
all:
arm-none-eabi-as -o 'bin/main.o' main.asm
arm-none-eabi-ld -T stm32f103c8t6.ld -o 'bin/main.elf' 'bin/main.o'
arm-none-eabi-objcopy -O binary 'bin/main.elf' 'bin/output.bin'
rm -rf 'bin/main.o' 'bin/main.elf'
st-flash write 'bin/output.bin' 0x8000000
Буду рад любой помощи