用汇编和C语言实现点灯实验

汇编代码 

.text 
.global _start
_start: 
	/**********LED1点灯**************/
	  
led1_init:
      @ LED1  ------->PE10
	  @1.设置PE10引脚的GPIOE这一组时钟使能 RCC_MPU_AHB4ENSETR   0x50000A28[4] = 1
		@1.将寄存器中的值读出来
		ldr r0,=0x50000A28
		ldr r1,[r0]
		orr r1,r1,#(0x1<<4)  @ 2.修改相应的位
		@ 3.修改完成后,写回去
		str r1,[r0]   

	  @2.设置PE10引脚的GPIOE_MODER控制器为输出模式  0x50006000[21:20] = 01
	  ldr r0,=0x50006000
	  ldr r1,[r0]
	  and r1,r1,#(~(0x3<<20))
	  orr r1,r1,#(0x1<<20)
	  str r1,[r0]
	  @3.设置PE10引脚的GPIOE_OTYPER寄存器为推挽输出 0x50006004[10] = 0
	  ldr r0,=0x50006004
	  ldr r1,[r0]
	  and r1,r1,#(~(0x1<<10))
	  str r1,[r0]
	  @4.设置PE10引脚的GPIOE_OSPEEDR寄存器为低速输出模式 0x50006008[21:20] = 00
	  ldr r0,=0x50006008
	  ldr r1,[r0]
	  and r1,r1,#(~(0x3<<20))
	  str r1,[r0]
	  @5.设置PE10引脚的GPIO_PUPDR寄存器禁止上下拉电阻 0x5000600C[21:20] = 00
	  ldr r0,=0x5000600C
	  ldr r1,[r0]
	  and r1,r1,#(~(0x3<<20))
	  str r1,[r0]




led2_init:
      @ LED2  ------->PF10
	  @1.设置PF10引脚的GPIOE这一组时钟使能 RCC_MPU_AHB4ENSETR   0x50000A28[5] = 1
		@1.将寄存器中的值读出来
		ldr r0,=0x50000A28
		ldr r1,[r0]
		orr r1,r1,#(0x1<<5)  @ 2.修改相应的位
		@ 3.修改完成后,写回去
		str r1,[r0]   

	  @2.设置Pf10引脚的GPIOE_MODER控制器为输出模式  0x50007000[21:20] = 01
	  ldr r0,=0x50007000
	  ldr r1,[r0]
	  and r1,r1,#(~(0x3<<20))
	  orr r1,r1,#(0x1<<20)
	  str r1,[r0]
	  @3.设置PF10引脚的GPIOE_OTYPER寄存器为推挽输出 0x50007004[10] = 0
	  ldr r0,=0x50007004
	  ldr r1,[r0]
	  and r1,r1,#(~(0x1<<10))
	  str r1,[r0]
	  @4.设置PF10引脚的GPIOE_OSPEEDR寄存器为低速输出模式 0x50007008[21:20] = 00
	  ldr r0,=0x50007008
	  ldr r1,[r0]
	  and r1,r1,#(~(0x3<<20))
	  str r1,[r0]
	  @5.设置PE10引脚的GPIO_PUPDR寄存器禁止上下拉电阻 0x5000700C[21:20] = 00
	  ldr r0,=0x5000700C
	  ldr r1,[r0]
	  and r1,r1,#(~(0x3<<20))
	  str r1,[r0]



	/**********LED3点灯**************/
led3_init:
      @1.设置PE10引脚的GPIOE这一组时钟使能 RCC_MPU_AHB4ENSETR   0x50000A28[4] = 1
		@1.将寄存器中的值读出来
		ldr r0,=0x50000A28
		ldr r1,[r0]
		orr r1,r1,#(0x1<<4)  @ 2.修改相应的位
		@ 3.修改完成后,写回去
		str r1,[r0]   
 @ LED3  ------->PE8
	 
	  @2.设置PE8引脚的GPIOE_MODER控制器为输出模式  0x50006000[17:16] = 01
	  ldr r0,=0x50006000
	  ldr r1,[r0]
	  and r1,r1,#(~(0x3<<16))
	  orr r1,r1,#(0x1<<16)
	  str r1,[r0]
	  @3.设置PE10引脚的GPIOE_OTYPER寄存器为推挽输出 0x50006004[8] = 0
	  ldr r0,=0x50006004
	  ldr r1,[r0]
	  bic r1,r1,#(0x1<<8)
	  str r1,[r0]
	  @4.设置PE8引脚的GPIOE_OSPEEDR寄存器为低速输出模式 0x50006008[17:16] = 00
	  ldr r0,=0x50006008
	  ldr r1,[r0]
	  and r1,r1,#(~(0x3<<16))
	  str r1,[r0]
	  @5.设置PE8引脚的GPIO_PUPDR寄存器禁止上下拉电阻 0x5000600C[17:16] = 00
	  ldr r0,=0x5000600C
	  ldr r1,[r0]
	  and r1,r1,#(~(0x3<<16))
	  str r1,[r0]
	
led1_on:
	@设置PE10引脚的GPIOE_ODR寄存器输出高电平,灯点亮  0x50006014[10] = 1
	  ldr r0,=0x50006014
	  ldr r1,[r0]
	  orr r1,r1,#(0x1 << 10)
	  str r1,[r0]
	  bl delay_1s

	
led1_off:
	@设置PE10引脚的GPIOE_ODR寄存器输出低电平,灯熄灭  0x50006014[10] = 0
	  ldr r0,=0x50006014
	  ldr r1,[r0]
	  bic r1,r1,#(0x1<<10)
	  str r1,[r0]
	  b led2_on
 
led2_on:
	@设置PF10引脚的GPIOE_ODR寄存器输出高电平,灯点亮  0x50007014[10] = 1
	  ldr r0,=0x50007014
	  ldr r1,[r0]
	  orr r1,r1,#(0x1<<10)
	  str r1,[r0]
	  bl delay_1s

	
led2_off:
	@设置PF10引脚的GPIOE_ODR寄存器输出低电平,灯熄灭  0x50007014[10] = 0
	  ldr r0,=0x50007014
	  ldr r1,[r0]
	  bic r1,r1,#(0x1<<10)
	  str r1,[r0]
 	  str r1,[r0]

	  bl delay_1s
	  b led3_on

led3_on:
	@设置PE8引脚的GPIOE_ODR寄存器输出高电平,灯点亮  0x50006014[8] = 1
	  ldr r0,=0x50006014
	  ldr r1,[r0]
	  orr r1,r1,#(0x1<<8)
	  str r1,[r0]
	  bl delay_1s

	
led3_off:
	@设置PE8引脚的GPIOE_ODR寄存器输出低电平,灯熄灭  0x50006014[8] = 0
	  ldr r0,=0x50006014
	  ldr r1,[r0]
	  bic r1,r1,#(0x1<<8)
	  str r1,[r0]
	  bl delay_1s
	  b led1_on





@ 大概1s的延时函数
delay_1s:
	mov r3, #0x10000001
	mm:
	cmp r3, #0
	subne r3, r3, #1
	bne mm
	mov pc, lr

.end

C语言实现点灯:

测试文件main.c

#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()
{
	RCC_AHB4_ENSTER|=(0x1<<4);
	hal_gpio_init(GPIOE,10);
	hal_gpio_init(GPIOE,8);
	RCC_AHB4_ENSTER|=(0x1<<5);
	hal_gpio_init(GPIOF,10);

	// LED灯初始化
	 
	while(1)
	{
		hal_gpio_output_high(LED1);
		delay_ms(500);
		hal_gpio_output_low(LED1);
		delay_ms(500);

		hal_gpio_output_high(LED2);
		delay_ms(500);
		hal_gpio_output_low(LED2);
		delay_ms(500);

		hal_gpio_output_high(LED3);
		delay_ms(500);
		hal_gpio_output_low(LED3);
		delay_ms(500);
	}
	return 0;
}

头文件led.h

#ifdef __LED_H__
#define __LED_H__

typedef struct{

	volatile unsigned int MODER;

	volatile unsigned int OTYPER;

	volatile unsigned int OSPEEDER;

	volatile unsigned int PUPDR;

	volatile unsigned int IDR;

	volatile unsigned int ODR;

}gpio_t;

enum{
	int led1=1,
	int led2,
	int led3,

};

#define GPIOE ((gpio_t)0x50006000)

#define GPIOF ((gpio_t)0x50007000)

#define RCC_AHB4_ENSTER (*(volatile unsigned int*)0x5000A28)


void hal_gpio_init(gpio_t *gpiox,int pin);

void hal_gpio_output_high(unsigned int lex);

void hal_gpio_output_low(unsigned int ledx);

#endif

源文件led.c

#include "../include/led.h"

void hal_gpio_init(gpio_t *gpiox,int pin)
{
	gpiox->MODER&=(~(0x3<MODER|=(0x1<OTYPER&=(~(0x1<OSPEEDER&=(~(0x3<PUPDR&=(~(0x3<ODR|=(0x1<<10);
		break;

	case led2:
		GPIOF->ODR|=(0x1<<10);
		break;

	case led3:
		GPIOE->ODR|=(0x1<<8);
		break;
	
	default:
		break;
	}
}

void hal_gpio_output_low(unsigned int ledx)
{
		switch(ledx)
	{
	case led1:
		GPIOE->ODR&=(~(0x1<<10));
		break;

	case led2:
		GPIOF->ODR&=(~(0x1<<10));
		break;

	case led3:
		GPIOE->ODR&=(~(0x1<<8));
		break;
	
	default:
		break;
	}
}

你可能感兴趣的:(arm,单片机,stm32,物联网)