用汇编与C语言分别实现对RCC于GPIO寄存器的设置,并点亮3盏LED灯
.text
.global _start
_start:
LED1_INIT:
/**********LED1点灯----->PE10************/
/**********RCC************/
@1.设置GPIOE组时钟使能,通过RCC_AHB4ENSETR寄存器设置 0x50000A28[4]=1
ldr r0,=0x50000A28 @偏移到RCC寄存器地址
ldr r1,[r0] @读取寄存器内的值
orr r1,r1,#(0x3 << 4) @使能GPIPE与GPIOF
str r1,[r0] @写入寄存器
/**********GPIO************/
@LED输出模式
ldr r0,=0x50006000 @偏移到GPIOE MODER的地址
ldr r2,=0x50007000 @偏移到GPIOF MODER的地址
ldr r1,[r0] @读取E MODER的值
bic r1,r1,#(0x1 << 17) @设置PE8的模式为输出
orr r1,r1,#(0x1 << 16)
bic r1,r1,#(0x1 << 21) @设置PE10的模式为输出
orr r1,r1,#(0x1 << 20)
str r1,[r0] @写入E MODER寄存器
ldr r1,[r2] @读取F MODER的值
bic r1,r1,#(0x1 << 21) @设置PF10的模式为输出
orr r1,r1,#(0x1 << 20)
str r1,[r2] @写入F MODER寄存器
@LED推挽输出
ldr r0,=0x50006004 @获取E OTYPER的地址
ldr r2,=0x50007004 @获取F OTYPER的地址
ldr r1,[r0] @获取E OTYPER寄存器的值
and r1,r1,#(~(0x1 << 8)) @设置E8 E10的模式为推挽输出
and r1,r1,#(~(0x1 << 10))
str r1,[r0] @写入E OTYPER寄存器
ldr r1,[r2] @获取F OTYPER寄存器的值
and r1,r1,#(~(0x1 << 10)) @设置F10的模式为推挽输出
str r1,[r2] @写入F OTYPER寄存器
@LED低速输出
ldr r0,=0x50006008 @获取E SPEEDER寄存器的地址
ldr r2,=0x50007008 @获取F SPEEDER寄存器的地址
ldr r1,[r0] @获取E SPEEDER寄存器的值
bic r1,r1,#(0x3 << 16) @设置E8 E10的模式为低速
bic r1,r1,#(0x3 << 20)
str r1,[r0] @写入E SPEEDER寄存器
ldr r1,[r2] @获取F SPEEDER寄存器的值
bic r1,r1,#(0x3 << 20) @设置F10的模式为低速
str r1,[r2] @写入F SPEEDER寄存器
@LED禁止上下拉
ldr r0,=0x5000600c @获取E、F PUPDR寄存器的地址
ldr r2,=0x5000700c
ldr r1,[r0] @读取E PUPDR寄存器的值
bic r1,r1,#(0x3 << 16) @设置E8 E10的模式为禁止上下拉
bic r1,r1,#(0x3 << 20)
str r1,[r0] @写入E PUPDR寄存器
ldr r1,[r2] @获取F PURDR寄存器的值
bic r1,r1,#(0x3 << 20) @设置F10的模式为禁止上下拉
str r1,[r2] @写入F PUPDR寄存器
@LED输出高电平
LED_ON:
ldr r0,=0x50006014 @获取E、F ODR寄存器的地址
ldr r2,=0x50007014
ldr r1,[r0] @获取E ODR寄存器的值
orr r1,r1,#(0x1 << 8) @设置E8 E10的输出为高电平
orr r1,r1,#(0x1 << 10)
str r1,[r0] @写入E ODR寄存器
ldr r1,[r2] @获取F ODR寄存器的值
orr r1,r1,#(0x1 << 10) @设置F10的输出为高电平
str r1,[r2] @写入F ODR寄存器
bl delay_1s
b LED_OFF
@LED输出低电平
LED_OFF:
ldr r0,=0x50006014 @同LED_ON
ldr r2,=0x50007014
ldr r1,[r0]
and r1,r1,#(~(0x1 << 8)) @设置输出为低电平
and r1,r1,#(~(0x1 << 10))
str r1,[r0]
ldr r1,[r2]
and r1,r1,#(~(0x1 << 10))
str r1,[r2]
bl delay_1s
b LED_ON
delay_1s:
mov r3, #0x10000000
mm:
cmp r3, #0
subne r3, r3, #1
bne mm
mov pc, lr
.end
#ifndef __LED_H__
#define __LED_H__
#define GPIOE ((gpio_t*)0x50006000)
#define GPIOF ((gpio_t*)0x50007000)
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;
//LED1 ----> PE10
void led1_init();
void led1_on();
void led1_off();
//LED2 ----> PF10
void led2_init();
void led2_on();
void led2_off();
//LED3 ----> PE8
void led3_init();
void led3_on();
void led3_off();
#endif
#include "../include/led.h"
void led1_init()
{
*(volatile unsigned int*)0x50000A28 = *(volatile unsigned int*)0x50000A28 | (0x1 << 4);
GPIOE->MODER = GPIOE->MODER & (~(0x3<<20));
GPIOE->MODER = GPIOE->MODER | (0x1<<20);
GPIOE->OTYPER = GPIOE->OTYPER & (~(0x1<<10));
GPIOE->OSPEEDR = GPIOE->OSPEEDR | (0x3 << 20);
GPIOE->PUPDR = GPIOE->PUPDR & (~(0x3<<20));
}
void led1_on()
{
GPIOE->ODR = GPIOE->ODR | (0x1 << 10);
}
void led1_off()
{
GPIOE->ODR = GPIOE->ODR & (~(0x1 << 10));
}
//LED2 ----> PF10
void led2_init()
{
*(volatile unsigned int*)0x50000A28 = *(volatile unsigned int*)0x50000A28 | (0x1 << 5);
GPIOF->MODER = GPIOF->MODER & (~(0x3<<20));
GPIOF->MODER = GPIOF->MODER | (0x1<<20);
GPIOF->OTYPER = GPIOF->OTYPER & (~(0x1<<10));
GPIOF->OSPEEDR = GPIOF->OSPEEDR | (0x3 << 20);
GPIOF->PUPDR = GPIOF->PUPDR & (~(0x3<<20));
}
void led2_on()
{
GPIOF->ODR = GPIOF->ODR | (0x1 << 10);
}
void led2_off()
{
GPIOF->ODR = GPIOF->ODR & (~(0x1 << 10));
}
//LED3 ----> PE8
void led3_init()
{
GPIOE->MODER = GPIOE->MODER & (~(0x3<<16));
GPIOE->MODER = GPIOE->MODER | (0x1<<16);
GPIOE->OTYPER = GPIOE->OTYPER & (~(0x1<<8));
GPIOE->OSPEEDR = GPIOE->OSPEEDR | (0x3 << 8);
GPIOE->PUPDR = GPIOE->PUPDR & (~(0x3<<16));
}
void led3_on()
{
GPIOE->ODR = GPIOE->ODR | (0x1 << 8);
}
void led3_off()
{
GPIOE->ODR = GPIOE->ODR & (~(0x1 << 8));
}
#include "./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()
{
led1_init();
led2_init();
led3_init();
while(1)
{
led1_on();
delay_ms(1000);
led1_off();
delay_ms(1000);
led2_on();
delay_ms(1000);
led2_off();
delay_ms(1000);
led3_on();
delay_ms(1000);
led3_off();
delay_ms(1000);
}
return 0;
}
LED