Arm 点灯实验

1.汇编代码点灯


.text 
.global _start
_start: 
	/**********LED1点灯RCC和GPIO章节初始化**************/
LED1_init:
//	@ 1.通过RCC_AHB4_ENSETR:0x50000A28寄存器设置GPIOE控制器时钟使能 [0x50000A28][4] = 1
	ldr r0,=0x50000A28
	ldr r1,[r0] 
	orr r1,r1,#(0x1 << 4)
	orr r1,r1,#(0x1 << 5)
	str r1,[r0]
//	@ 2.通过GPIOE_MODER:0x50006000寄存器设置PE10引脚为输出模式[0x50006000][21:20] = 01
//	@ 3.通过GPIO_OTYPER:0x50006004寄存器设置PE10引脚为推挽输出模式	[0x50006004][10] = 0
//	@ 4.通过GPIO_OSPEEDR:0x50006008寄存器设置PE10引脚为低速输出模式 [0x50006008][21:20] = 00
//	@ 5.通过GPIO_PUPDR:0x5000600C寄存器设置PE10引脚为禁止上下拉电阻 [0x5000600C][21:20] = 00

  /*设置PE10引脚为输出模式*/
  ldr r0,=0x50006000
  ldr r1,[r0]
  bic r1,r1,#(0x3<<20)
	bic r1,r1,#(0x3<<16)
  orr r1,r1,#(0x1<<20)
	orr r1,r1,#(0x1<<16)
  str r1,[r0]  
  //led2
   ldr r0,=0x50007000
   ldr r1,[r0]
    bic r1,r1,#(0x3<<20)
   orr r1,r1,#(0x1<<20)
   str r1,[r0]
  /*设置PE10引脚为推挽输出*/
  ldr r0,=0x50006004
  ldr r1,[r0]
  bic r1,r1,#(0x1<<10)
	bic r1,r1,#(0x1<<8)
  str r1,[r0]
  //LED2
  ldr r0,=0x50007004
  ldr r1,[r0]
  bic r1,r1,#(0x1<<10)
  str r1,[r0]
  /*设置PE10引脚为低速输出*/
  ldr r0,=0x50006008
  ldr r1,[r0]
  bic r1,r1,#(0x3<<20)
	bic r1,r1,#(0x3<<16)
  str r1,[r0]
  //LED2
  ldr r0,=0x50007008
	ldr r1,[r0]
	bic r1,r1,#(0x3<<20)
	str r1,[r0]
  /*设置PE10引脚禁止上下拉电阻*/
  ldr r0,=0x5000600c
  ldr r1,[r0]
  bic r1,r1,#(0x3<<20)
	bic r1,r1,#(0x3<<16)
  str r1,[r0]
  //led2
  ldr r0,=0x5000700c
   ldr r1,[r0]
    bic r1,r1,#(0x3<<20)
    str r1,[r0]




LED1_ON:
//	@ 1.通过GPIOE_ODR:0x50006014寄存器设置PE10引脚为输出高电平[0x50006014][10] = 1
  /*设置PE10引脚输出*/
  ldr r0,=0x50006014
  ldr r1,[r0]
  orr r1,r1,#(0x1<<10)
  str r1,[r0]
  bl delay_1s


  //熄灭
 ldr r0,=0x50006014
 ldr r1,[r0]
 bic r1,r1,#(0x1<<10)
 str r1,[r0]  
 bl delay_1s

  ldr r0,=0x50007014
   ldr r1,[r0]
    orr r1,r1,#(0x1<<10)
    str r1,[r0]
    bl delay_1s
  
  
    //熄灭
   ldr r0,=0x50007014
   ldr r1,[r0]
   bic r1,r1,#(0x1<<10)
   str r1,[r0]  
   bl delay_1s   


  ldr r0,=0x50006014
  ldr r1,[r0]
  orr r1,r1,#(0x1<<8)
  str r1,[r0]
  bl delay_1s

 ldr r0,=0x50006014
 ldr r1,[r0]
 bic r1,r1,#(0x1<<8)
 str r1,[r0]  
 bl delay_1s

 b LED1_ON


//	@ 1.通过GPIOE_ODR:0x50006014寄存器设置PE10引脚为输出低电平[0x50006014][10] = 0


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

.end

2.c语言点灯

 2.1 头文件

#ifndef __LED_H__
#define __LED_H__
//定时器的使能
#define RCC_MP_AHB4ENSETR  (*(volatile unsigned int *)0x50000A28)
//枚举3栈灯
typedef enum{
    LED1=1,
    LED2,
    LED3,
}leds_t;
typedef enum{
    GPIO_SET=0,
    GPIO_RESET,
}led_status_t;
//1.封装寄存器  封装RCC外设的寄存器,GPIOE GPIOF
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)



//led灯的初始化
void hal_led_init(void);

//led灯的亮灭 参数:leds_t 那个灯, led_status_t 灯的状态
void hal_led_switch(leds_t , led_status_t);

#endif //__LED_H__

2.2 源文件

#include "../include/led.h"
// led灯的初始化
void hal_led_init(void)
{
    // 1. 使能GPIOE,GPIOF外设的时钟
    RCC_MP_AHB4ENSETR |= (0x3 << 4);
    // 2. 设置gpio引脚为输出模式
    GPIOE->MODER &= (~(0x3 << 20));
    GPIOE->MODER |= (0x1 << 20);
    GPIOE->MODER &= (~(0x3 << 16));
    GPIOE->MODER |= (0x1 << 16);
    GPIOF->MODER &= (~(0x3 << 20));
    GPIOF->MODER |= (0x1 << 20);
    // 3. 设置gpio引脚为推挽输出
    GPIOE->OTYPER &= (~(0x1 << 10));
    GPIOE->OTYPER &= (~(0x1 << 8));
    GPIOF->OTYPER &= (~(0x1 << 10));
    // 4. 设置gpio引脚为低速模式
    GPIOE->OSPEEDR &= (~(0x3 << 20));
    GPIOE->OSPEEDR &= (~(0x3 << 16));
    GPIOF->OSPEEDR &= (~(0x3 << 20));
    // 5. 禁止gpio引脚的上拉和下拉
    GPIOE->PUPDR &= (~(0x3 << 20));
    GPIOE->PUPDR &= (~(0x3 << 16));
    GPIOF->PUPDR &= (~(0x3 << 20));
}

/*
    功能LED灯的亮灭
 */
void hal_led_switch(leds_t leds, led_status_t statu)
{
    // 设置led灯亮
    switch (leds)
    {
    case LED1:
        if (statu == GPIO_SET)
        {
            GPIOE->ODR &= (~(0x1 << 10));
        }
        else
        {
            GPIOE->ODR |= (0x1 << 10);
        }

        break;
    case LED2:
        if (statu == GPIO_SET)
        {
            GPIOF->ODR &= (~(0x1 << 10));
        }
        else
        {
            GPIOF->ODR |= (0x1 << 10);
        }
        break;
    case LED3:
        if (statu == GPIO_SET)
        {
            GPIOE->ODR &= (~(0x1 << 8));
        }
        else
        {
            GPIOE->ODR |= (0x1 << 8);
        }

        break;
    default:
        break;
    }

  
}

2.3主函数

#include "./include/led.h"
extern void printf(const char *fmt, ...);
void delay_ms(unsigned int ms)
{
	int i,j;
	for(i = 0; i < ms;i++)
		for (j = 0; j < 1800; j++);
}


int main()
{
	// 初始化
	hal_led_init();
	while(1)
	{
		// 实现LED灯的交替闪烁
		hal_led_switch(LED1,GPIO_RESET);
		delay_ms(500);
		hal_led_switch(LED1,GPIO_SET);
		hal_led_switch(LED2,GPIO_RESET);
		delay_ms(500);
		hal_led_switch(LED2,GPIO_SET);
		hal_led_switch(LED3,GPIO_RESET);
		delay_ms(500);
		hal_led_switch(LED3,GPIO_SET);

	}
	return 0;
}

 

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