题目:
1.用汇编语言实现LED1/LED2/LED3三盏灯点亮
2.用C语言实现LED1/LED2/LED3三盏灯点亮
3.思考:如何封装初始化函数,如何封装操作GPIO接口函数,枚举关键字/特点
代码:
代码一:
asm_led.S
.text
.global _start
_start:
/**********LED1点灯----->PE10**************/
/**********RCC**************/
@GPIO 时钟使能 RCC_AHB4ENSETR寄存器设置 0x50000a28[4]=1;
ldr r0,=0x50000A28 @使能GPIOE时钟
ldr r1,[r0]
orr r1,r1,#(0x1<<4)
str r1,[r0]
ldr r0,=0x50000A28 @使能GPIOF时钟
ldr r1,[r0]
orr r1,r1,#(0x1<<5)
str r1,[r0]
/**********GPIO**************/
/*led1*/
ldr r0,=0x50006000 @moder
ldr r1,[r0]
and r1,r1,#(~(0x3<<20))
orr r1,r1,#(0x1<<20)
str r1,[r0]
ldr r0,=0x50006004 @otyper
ldr r1,[r0]
and r1,r1,#(~(0x1<<10))
str r1,[r0]
ldr r0,=0x50006008 @ospeedr
ldr r1,[r0]
and r1,r1,#(~(0x3<<20))
str r1,[r0]
ldr r0,=0x5000600c @pupdr
ldr r1,[r0]
and r1,r1,#(~(0x3<<20))
str r1,[r0]
/*led2*/
ldr r0,=0x50007000 @moder
ldr r1,[r0]
and r1,r1,#(~(0x3<<20))
orr r1,r1,#(0x1<<20)
str r1,[r0]
ldr r0,=0x50007004 @otyper
ldr r1,[r0]
and r1,r1,#(~(0x1<<10))
str r1,[r0]
ldr r0,=0x50007008 @ospeedr
ldr r1,[r0]
and r1,r1,#(~(0x3<<20))
str r1,[r0]
ldr r0,=0x5000700c @pupdr
ldr r1,[r0]
and r1,r1,#(~(0x3<<20))
str r1,[r0]
/*led3*/
ldr r0,=0x50006000 @moder
ldr r1,[r0]
and r1,r1,#(~(0x3<<16))
orr r1,r1,#(0x1<<16)
str r1,[r0]
ldr r0,=0x50006004 @otyper
ldr r1,[r0]
and r1,r1,#(~(0x1<<8))
str r1,[r0]
ldr r0,=0x50006008 @ospeedr
ldr r1,[r0]
and r1,r1,#(~(0x3<<16))
str r1,[r0]
ldr r0,=0x5000600c @pupdr
ldr r1,[r0]
and r1,r1,#(~(0x3<<16))
str r1,[r0]
loop:
bl led1_on
bl led2_on
bl led3_on
bl delay_1s
bl led1_off
bl led2_off
bl led3_off
bl delay_1s
b loop
led1_on:
ldr r0,=0x50006014 @odr
ldr r1,[r0]
orr r1,r1,#(0x1<<10)
str r1,[r0]
mov pc,lr
led1_off:
ldr r0,=0x50006014 @odr
ldr r1,[r0]
and r1,r1,#(~(0x1<<10))
str r1,[r0]
mov pc,lr
led2_on:
ldr r0,=0x50007014 @odr
ldr r1,[r0]
orr r1,r1,#(0x1<<10)
str r1,[r0]
mov pc,lr
led2_off:
ldr r0,=0x50007014 @odr
ldr r1,[r0]
and r1,r1,#(~(0x1<<10))
str r1,[r0]
mov pc,lr
led3_on:
ldr r0,=0x50006014 @odr
ldr r1,[r0]
orr r1,r1,#(0x1<<8)
str r1,[r0]
mov pc,lr
led3_off:
ldr r0,=0x50006014 @odr
ldr r1,[r0]
and r1,r1,#(~(0x1<<8))
str r1,[r0]
mov pc,lr
@ 大概1s的延时函数
delay_1s:
mov r3, #0x10000000
mm:
cmp r3, #0
subne r3, r3, #1
bne mm
mov pc, lr
.end
代码二:
led.h
#ifndef __LED_H__
#define __LED_H__
#define led1 gpioe,10
#define led2 gpiof,10
#define led3 gpioe,8
#define RCC_AHB4_ENSETR (*(volatile unsigned int*)0x50000A28)
#define GPIO_BASE(offset) ((gpio_t*)(0x50002000+offset*0x1000))
enum gpio
{
gpioa,
gpiob,
gpioc,
gpiod,
gpioe,
gpiof,
gpiog,
gpioh,
gpioi,
gpioj,
gpiok,
};
typedef struct{
volatile unsigned int MODER; //00
volatile unsigned int OTYPER; //04
volatile unsigned int OSPEEDR; //08
volatile unsigned int PUPDR; //0C
volatile unsigned int IDR; //10
volatile unsigned int ODR; //14
}gpio_t;
void led_init(enum gpio x,int n);
void led_on(enum gpio x,int n);
void led_off(enum gpio x,int n);
#endif
led.c
#include"led.h"
void led_init(enum gpio x,int n)
{
RCC_AHB4_ENSETR|=(0x1<<x);
GPIO_BASE(x)->MODER&=~(0x3<<(2*n));
GPIO_BASE(x)->MODER|=(0x1<<(2*n));
GPIO_BASE(x)->OTYPER&=~(0x1<<n);
GPIO_BASE(x)->OSPEEDR&=~(0x3<<(2*n));
GPIO_BASE(x)->PUPDR&=~(0x3<<(2*n));
}
void led_on(enum gpio x,int n)
{
GPIO_BASE(x)->ODR|=(0x1<<n);
}
void led_off(enum gpio x,int n)
{
GPIO_BASE(x)->ODR&=~(0x1<<n);
}
main.c
#include "led.h"
extern void printf(const char *fmt, ...);
void delay_ms(int ms)
{
int i,j;
for(i = 0; i < ms;i++)
for (j = 0; j < 1800; j++);
}
int main()
{
led_init(led1); // LED灯初始化
led_init(led2); // LED灯初始化
led_init(led3); // LED灯初始化
led_on(led2);
led_on(led3);
while(1)
{
led_on(led1);
delay_ms(500);
led_off(led1);
delay_ms(500);
}
return 0;
}
运行结果:
结果一:

结果二:
