- 基于STM32MP157
汇编版
点亮LED
z80
.text
.global _start
_start:
/* LED1灯的初始化 */
/* 1. 使能GPIOE外设的时钟源
RCC_MP_AHB4ENSETR[4] = 0b1 寄存器地址 = 0x50000A28 */
ldr r0, =0x50000A28 @ 准备地址
ldr r1, [r0] @ 将地址中的数据读到寄存器中
orr r1, r1, #(0x1 << 4) @ 修改对应的位,保持其他位不变
str r1, [r0] @ 将修改的结果写回到寄存器中
/* 2. 配置PE10引脚为输出模式
GPIOE_MODER[21:20] = 0b01 寄存器地址 = 0x50006000 */
ldr r0, =0x50006000
ldr r1, [r0]
and r1, r1, #(~(0x3 << 20))
orr r1, r1, #(0x1 << 20)
str r1, [r0]
/* 3. 配置PE10引脚为推挽输出
GPIOE_OTYPER[10] = 0b0 寄存器地址 = 0x50006004 */
ldr r0, =0x50006004
ldr r1, [r0]
and r1, r1, #(~(0x3 << 10))
str r1, [r0]
/* 4. 配置PE10引脚为低速模式
GPIOE_OSPEEDR[21:20] = 0b00 寄存器地址 = 0x50006008 */
ldr r0, =0x50006008
ldr r1, [r0]
bic r1, r1, #(0x3 << 20)
str r1, [r0]
/* 5. 配置PE10引脚禁止上和核下拉电阻
GPIOE_PUPDR[21:20] = 0b00 寄存器地址 = 0x5000600C */
ldr r0, =0x5000600C
ldr r1, [r0]
and r1, r1, #(~(0x3 << 20))
str r1, [r0]
/* 裸机开发中,必须有一个死循环,防止程序跑飞 */
loop:
/* 循环点亮或者熄灭LED灯 */
/* 1. 配置PE10引脚输出高电平, LED1灯亮
GPIOE_ODR[10] = 0b1 寄存器地址 = 0x50006014 */
ldr r0, =0x50006014
ldr r1, [r0]
orr r1, r1, #(0x1 << 10)
str r1, [r0]
bl delay_1s
/* 2. 配置PE10引脚输出低电平, LED1灯灭
GPIOE_ODR[10] = 0b0 寄存器地址 = 0x50006014 */
ldr r0, =0x50006014
ldr r1, [r0]
bic r1, r1, #(0x1 << 10)
str r1, [r0]
bl delay_1s
b loop
@ 大概 1s的延时函数
delay_1s:
mov r3, #0x10000000
mm:
cmp r3, #0
subne r3, r3, #1
bne mm
mov pc, lr
.end
- 编译程序
bash
arm-linux-gnueabihf-gcc -c led.s -o led.o
arm-linux-gnueabihf-ld led.o -o led.elf -Ttext=0xC0008000
arm-linux-gnueabihf-objcopy -O binary led.elf led.bin
C语言版
C语言访问特殊功能寄存器
- 方式一:
c
volatile unsigned int *gpioe_moder = (volatile unsigned int *)0x50006000;
*gpioe_moder = *gpioe_moder & (~(0x3 << 20));
- 方式二:
c
#define GPIOE_MODER (*(volatile unsigned int *)0x50006000)
GPIOE_MODER &= (~(0x3 << 20));
- 方式三:
c
#define GPIOA_MODER *(volatile unsigned int *)0x50002000
#define GPIOA_OTYPER *(volatile unsigned int *)0x50002004
#define GPIOA_OSPEEDR *(volatile unsigned int *)0x50002008
#define GPIOA_PUPDR *(volatile unsigned int *)0x5000200C
#define GPIOA_IDR *(volatile unsigned int *)0x50002010
#define GPIOA_ODR *(volatile unsigned int *)0x50002014
#define GPIOF_MODER *(volatile unsigned int *)0x50007000
#define GPIOF_OTYPER *(volatile unsigned int *)0x50007004
#define GPIOF_OSPEEDR *(volatile unsigned int *)0x50007008
#define GPIOF_PUPDR *(volatile unsigned int *)0x5000700C
#define GPIOF_IDR *(volatile unsigned int *)0x50007010
#define GPIOF_ODR *(volatile unsigned int *)0x50007014
--------------------------------------------------------------------------------------
/* 以上宏定义可改为以下形式 */
typedef struct {
volatile unsigned int MODER;
volatile unsigned int OTYPER;
volatile unsigned int OSPEEDR;
volatile unsigned int PUPDR;
volatile unsigned int IDR;
volatile unsigned int ODR;
} gpio_t;
#define GPIOA (*(gpio_t *)0x50002000)
#define GPIOB (*(gpio_t *)0x50003000)
#define GPIOC (*(gpio_t *)0x50004000)
#define GPIOD (*(gpio_t *)0x50005000)
#define GPIOE (*(gpio_t *)0x50006000)
#define GPIOF (*(gpio_t *)0x50007000)
GPIOE.MODER &= (~(0x3 << 20));
GPIOE.MODER |= (0x1 << 20);
点亮LED
c
typedef struct{
volatile unsigned int MODER;
volatile unsigned int OTYPER;
volatile unsigned int OSPEEDR;
volatile unsigned int PUPDR;
volatile unsigned int IDR;
volatile unsigned int ODR;
}gpio_t;
#define GPIOE ((gpio_t *)0x50006000)
void delay_ms();
void led_flashing(){
// 1. 使能GPIOE外设的时钟源 RCC_MP_AHB4ENSETR[4] = 0b1
RCC_MP_AHB4ENSET |= (0x1 << 4);
// 2. 设置为输出模式 GPIOE_MODER[21:20] = 0b01
GPIOE->MODER &= (~(0x3 << 20));
GPIOE->MODER |= (0x1 << 20);
//3. 设置PE10引脚为推挽输出 GPIOE_OTYPER[10] = 0b0
GPIOE->OTYPER &= (~(0x1 << 10));
//4. 设置PE10引脚为低速模式 GPIOE_OSPEEDR[21:20] = 0b00
GPIOE->OSPEEDR &= (~(0x3 << 20));
//5. 设置PE10引脚禁止上下拉电阻 GPIOE_PUPDR[21:20] = 0b00
GPIOE->PUPDR &= (~(0x3 << 20));
while(1){
/*亮*/
GPIOE->ODR |= (1 << 10);
delay_ms();
/*灭*/
GPIOE->ODR &= ~(1 << 10);
delay_ms();
}
}
void delay_ms(unsigned int ms)
{
int i = 0x10000000;
while(i--) ;
}
- 编译
bash
arm-linux-gnueabihf-gcc -S led.c -o led.s -marm
arm-linux-gnueabihf-as led.s -o led.o
arm-linux-gnueabihf-ld led.o -o led.elf -Ttext=0xc0008000 -eled_flashing
arm-linux-gnueabihf-objcopy -O binary led.elf led.bin
或
bash
arm-linux-gnueabihf-gcc -c led.c -o led.o -marm
arm-linux-gnueabihf-ld led.o -o led.elf -Ttext=0xc0008000 -eled_flashing
arm-linux-gnueabihf-objcopy -O binary led.elf led.bin