汇编编程驱动LED

  • 基于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
相关推荐
kyle~2 天前
x86 汇编LOCK前缀 --- 硬件架构向软件提供的核心同步原语
汇编·c++·性能优化·硬件架构·实时系统
典典分享指南3 天前
飞书 + 企业微信 + 微信文档多端协同实践指南
汇编·flask·intellij-idea·fastapi
极客互动API8 天前
企业微信 iPad 协议服务搭建与 AI 回调实战
网络·汇编·人工智能·微信·企业微信·ipad
wechatbot88813 天前
极客互动企业微信 SCRM 私域运营实战效果全景
大数据·汇编·微信·自动化·企业微信·rpa
祈禾18 天前
计算机组成原理之编译、汇编、链接、解释
开发语言·汇编·笔记·学习
水饺编程20 天前
AT&T 汇编语言学习笔记开篇语
c语言·汇编·c++
iCxhust20 天前
8088单板机VScode集成开发环境使用方法二(汇编版)
汇编·单片机·微机原理·8088单板机
·薯条大王20 天前
经济实惠玩云服务器|一台云服务器多人共用,子账号配置教程
java·linux·运维·服务器·汇编·c++·python
txg66622 天前
VULOC:基于汇编切片的漏洞定位框架,精准锁定二进制中的危险代码
汇编·人工智能·深度学习·安全·网络安全
sunburn-22 天前
Java 队列全面详解:从入门到面试实战
java·开发语言·汇编·ide·idea