ARM -LED点灯实验

作业要求:

分别用汇编语言和C语言点亮三盏灯

一·、C语言方式:

 头文件:

#ifndef __LED_H__
#define __LED_H__

//宏定义封装RCC组寄存器
#define RCC_AHB4_ENSETR (*(volatile unsigned int*)0x50000A28)

//结构体封装GPIO组寄存器
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;
}gpoi_t;

#define GPIOE (*(gpoi_t*)0x50006000)
#define GPIOF (*(gpoi_t*)0x50007000)

//点亮LED1
void led1_init();
void led1_on();
void led1_off();


//点亮LED2
void led2_init();
void led2_on();
void led2_off();

//点亮LED3
void led3_init();
void led3_on();
void led3_off();

#endif

 源文件:

#include "led.h"

//点亮LED1
void led1_init()
{
	//1.通过RCC_AHB4_ENSETR:0x50000A28寄存器设置GPIOE控制器使能 0x50000A28[4] = 1
	RCC_AHB4_ENSETR|=(0x1<<4);
    //2.通过GPIOE_MODER:0x50006000寄存器设置PE10引脚为输出模式 0x50006000[21:20]= 01
	GPIOE.MODER&=(~(0x3<<20));
	GPIOE.MODER|=(0x1<<20);
	//3.通过GPIOE_OTYPER:0x50006004寄存器设置PE10引脚为推挽输出模式 0x50006004[10]= 0
	GPIOE.OTYPER&=(~(0x1<<10));
	//4.通过GPIOE_OSPEEDR:0x50006008寄存器设置PE10引脚为低速输出0x50006008[21:20]=00
	GPIOE.OSPEEDR&=(~(0x3<<20));
	//5.通过GPIOE_PUPDR:0x5000600C寄存器设置PE10引脚为禁止上下拉0x5000600C[21:20]= 00
	GPIOE.PUPDR&=(~(0x3<<20));
}

void led1_on()
{
	//1.通过GPIOE_ODR:0x50006014寄存器设置PE8引脚为输出高电平 0x50006014[10]= 1
	GPIOE.ODR|=(0x1<<10);
}

void led1_off()
{
	//1.通过GPIOE_ODR:0x50006014寄存器设置PE8引脚为输出低电平 0x50006014[10]= 0
	GPIOE.ODR&=(~(0x1<<10));
}

//点亮LED2
void led2_init()
{
	//1.通过RCC_AHB4_ENSETR:0x50000A28寄存器设置GPIOF控制器使能 0x50000A28[5] = 1
	RCC_AHB4_ENSETR|=(0x1<<5);
	//2.通过GPIOF_MODER:0x50006000寄存器设置PF10引脚为输出模式 0x50006000[21:20]= 01
	GPIOF.MODER&=(~(0x3<<20));
	GPIOF.MODER|=(0x1<<20);
	//3.通过GPIOF_OTYPER:0x50006004寄存器设置PF10引脚为推挽输出模式 0x50006004[10]= 0
	GPIOF.OTYPER&=(~(0x1<<10));
	//4.通过GPIOF_OSPEEDR:0x50006008寄存器设置PF10引脚为低速输出模式0x50006008[21:20]= 00
	GPIOF.OSPEEDR&=(~(0x3<<20));
	//5.通过GPIOF_PUPDR:0x5000600C寄存器设置PF10引脚为禁止上下拉0x5000600C[21:20]= 00
	GPIOF.PUPDR&=(~(0x3<<20));
}

void led2_on()
{
	//1.通过GPIOF_ODR:0x50006014寄存器设置PF10引脚为输出高电平 0x50006014[10]= 1
	GPIOF.ODR|=(0x1<<10);
}

void led2_off()
{
	//1.通过GPIOF_ODR:0x50006014寄存器设置PF10引脚为输出低电平 0x50006014[10]= 0
	GPIOF.ODR&=(~(0x1<<10));
}

//点亮LED3
void led3_init()
{
	//1.通过RCC_AHB4_ENSETR:0x50000A28寄存器设置GPIOE控制器使能 0x50000A28[4] = 1
	RCC_AHB4_ENSETR|=(0x1<<5);
	//2.通过GPIOE_MODER:0x50006000寄存器设置PE8引脚为输出模式 0x50006000[17:16]= 01
	GPIOE.MODER&=(~(0x3<<16));
	GPIOE.MODER|=(0x1<<16);
	//3.通过GPIOE_OTYPER:0x50006004寄存器设置PE8引脚为推挽输出模式 0x50006004[8]= 0
	GPIOE.OTYPER&=(~(0x1<<8));
	//4.通过GPIOE_OSPEEDR:0x50006008寄存器设置PE8引脚为低速输出模式0x50006008[17:16]= 00
	GPIOE.OSPEEDR&=(~(0x3<<16));
	//5.通过GPIOE_PUPDR:0x5000600C寄存器设置PE8引脚为禁止上下拉0x5000600C[17:16]= 00
	GPIOE.PUPDR&=(~(0x3<<16));
}

void led3_on()
{
	//1.通过GPIOE_ODR:0x50006014寄存器设置PE8引脚为输出高电平 0x50006014[8]= 1
	GPIOE.ODR|=(0x1<<8);
}

void led3_off()
{
	//1.通过GPIOE_ODR:0x50006014寄存器设置PE8引脚为输出低电平 0x50006014[8]= 0
	GPIOE.ODR&=(~(0x1<<8));
}

测试代码:

#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(); // LED1灯初始化
	led2_init(); // LED2灯初始化
	led3_init(); // LED3灯初始化
	while(1)
	{
		led1_on();
		delay_ms(300);
		led2_on();
		delay_ms(300);
		led3_on();
		delay_ms(300);
		led1_off();
		led2_off();
		led3_off();
		delay_ms(300);

	}
	return 0;
}

二、汇编语言方式:

.text
.global _start
_start: 
 
/**********LED1点亮PE10**************/
LED1_INIT:
	@1.通过RCC_AHB4_ENSETR:0x50000A28寄存器设置GPIOE控制器使能 0x50000A28[4] = 1
	ldr r0,=0x50000A28
	ldr r1,[r0]        			 
	orr r1,r1,#(0x1 << 4) 
	str r1,[r0]
 
	@2.通过GPIOE_MODER:0x50006000寄存器设置PE10引脚为输出模式 0x50006000[21:20]= 01
	ldr r0,=0x50006000
	ldr r1,[r0]
	and r1,r1,#(~(0x3 << 20))
	orr r1,r1,#(0x1 << 20)
	str r1,[r0]
 
	@3.通过GPIOE_OTYPER:0x50006004寄存器设置PE10引脚为推挽输出模式 0x50006004[10]= 0
	ldr r0,=0x50006004
	ldr r1,[r0]
	and r1,r1,#(~(0x1 << 10))
	str r1,[r0]
 
	@4.通过GPIOE_OSPEEDR:0x50006008寄存器设置PE10引脚为低速输出模式0x50006008[21:20]= 00
	ldr r0,=0x50006008
	ldr r1,[r0]
	and r1,r1,#(~(0x3 << 20))
	str r1,[r0]
 
	@5.通过GPIOE_PUPDR:0x5000600C寄存器设置PE10引脚为禁止上下拉0x5000600C[21:20]= 00
	ldr r0,=0x5000600C
	ldr r1,[r0]
	and r1,r1,#(~(0x3 << 20))
	str r1,[r0]
 
/**********LED2点亮PF10**************/
LED2_INIT:
	ldr r0,=0x50000A28
	ldr r1,[r0] 
	orr r1,r1,#(0x1 << 5) 
	str r1,[r0]
 
	ldr r0,=0x50007000
	ldr r1,[r0]
	and r1,r1,#(~(0x3 << 20))
	orr r1,r1,#(0x1 << 20)
	str r1,[r0]
 
	ldr r0,=0x50007004
	ldr r1,[r0]
	and r1,r1,#(~(0x1 << 10))
	str r1,[r0]

	ldr r0,=0x50007008
	ldr r1,[r0]
	and r1,r1,#(~(0x3 << 20))
	str r1,[r0]
 
	ldr r0,=0x5000700C
	ldr r1,[r0]
	and r1,r1,#(~(0x3 << 20))
	str r1,[r0]
 
/**********LED3点亮PE8**************/
LED3_INIT:
	ldr r0,=0x50000A28
	ldr r1,[r0] 
	orr r1,r1,#(0x1 << 4) 
	str r1,[r0]

	ldr r0,=0x50006000
	ldr r1,[r0]
	and r1,r1,#(~(0x3 << 16))
	orr r1,r1,#(0x1 << 16)
	str r1,[r0]
 
	ldr r0,=0x50006004
	ldr r1,[r0]
	and r1,r1,#(~(0x1 << 8))
	str r1,[r0]
 
	ldr r0,=0x50006008
	ldr r1,[r0]
	and r1,r1,#(~(0x3 << 16))
	str r1,[r0]

	ldr r0,=0x5000600C
	ldr r1,[r0]
	and r1,r1,#(~(0x3 << 16))
	str r1,[r0]
 
loop:
	bl led1_on
	bl delay_1s
	bl led2_on
	bl delay_1s
	bl led3_on
	bl delay_1s

	bl led1_off: 
	bl led2_off:
	bl led3_off:
	bl delay_1s
	b loop
 
led1_on:
	@1.通过GPIOE_ODR:0x50006014寄存器设置PE10引脚为输出高电平 0x50006014[10]= 1
	ldr r0,=0x50006014
	ldr r1,[r0]
	orr r1,r1,#(0x1 << 10)
	str r1,[r0]
	mov pc,lr

led2_on:
	ldr r0,=0x50007014
	ldr r1,[r0]
	orr r1,r1,#(0x1 << 10)
	str r1,[r0]
	mov pc,lr

led3_on:
	ldr r0,=0x50006014
	ldr r1,[r0]
	orr r1,r1,#(0x1 << 8)
	str r1,[r0]
	mov pc,lr
 
led1_off:
	@1.通过GPIOE_ODR:0x50006014寄存器设置PE10引脚为输出低电平 0x50006014[10]= 0
	ldr r0,=0x50006014
	ldr r1,[r0]
	and r1,r1,#(~(0x1 << 10))
	str r1,[r0]
	mov pc,lr

led2_off:
	ldr r0,=0x50007014
	ldr r1,[r0]
	and r1,r1,#(~(0x1 << 10))
	str r1,[r0]
	mov pc,lr
 
led3_off:
	ldr r0,=0x50006014
	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

你可能感兴趣的:(单片机,嵌入式硬件)