ARM体系结构和接口技术(四)LED灯实验---②

一、特殊功能控制寄存器

控制寄存器
在这里插入图片描述
数据寄存器
在这里插入图片描述

因此,控制LED1,需要配置GPIOE控制器模式:
1> 配置GPIOE_MODER寄存器,配置PE10引脚为输出的模式
2> 配置GPIOE_OTYPER寄存器,配置PE10引脚为推挽输出
3> 配置GPIOE_OSPEEDR寄存器,配置PE10引脚为低速模式
4> 配置GPIOE_PUPDR寄存器,配置PE10引脚禁止上下拉电阻
5> 配置GPIOE_ODR寄存器,配置PE10引脚输出高低电平

(一)GPIOx_MODER寄存器

在这里插入图片描述
配置PE10引脚为输出模式,即配置GPIOE_MODER寄存器的第[20:21]位为01

(二)GPIOx_OTYPER寄存器

GPIO端口输出类型寄存器
在这里插入图片描述
配置PE10引脚为推挽输出模式,即配置GPIOE_OTYPER寄存器的第[10]位为0

(三)GPIOx_OSPEEDR寄存器

GPIO端口输出速度寄存器
在这里插入图片描述
配置PE10引脚为低速模式,即配置GPIOE_OSPEEDR寄存器的第[21:20]位为00

(四)GPIOx_PUPDR寄存器

GPIO上下拉电阻寄存器
在这里插入图片描述
配置PE10引脚为禁用上下拉模式,即配置GPIOE_PUPDR寄存器的第[21:20]位为00
注:11: Reserved保留

(五)GPIOx_IDR寄存器

在这里插入图片描述
在这里插入图片描述

  • 注:IDR寄存器是只读寄存器

(六)GPIOx_ODR寄存器

在这里插入图片描述
点亮LED1,就需要PE10输出高电平,即第[10]位输出1;
熄灭LED1,就需要PE10输出低电平,即第[10]位输出0;

(七)GPIOx_BSRR寄存器

在这里插入图片描述
在这里插入图片描述

二、 查看外设控制器对应的特殊功能寄存器的基地址

在这里插入图片描述
在这里插入图片描述

三、RCC

在这里插入图片描述
在这里插入图片描述

四、代码实现

实现LED1~3交替闪烁

(一)汇编版本

/*
	LED1灯---PE10引脚,对应的总线为AHB4
	LED2---PF10,总线AHB4
	LED3---PE8
*/
.text 
.global _start

_start:
	/* 1. LED灯的初始化 */
	/* 1.1 使能GPIOE和GPIOF外设控制器的时钟源  
			RCC_MP_AHB4ENSETR[5:4] = 0b3  0x50000A28
	 */
	@ 使能GPIOE和GPIOF的时钟源
	ldr r0, =0x50000A28			@ 准备地址
	ldr r1, [r0]				@ 读取地址中的数据
	orr r1, r1, #(0x3 << 4);	@ 修改数据
	str r1, [r0]				@ 写数据到地址中

	/* 1.2 配置PE8,PE10,PF10引脚为输出模式  
			GPIOE_MODER[21:20][17:16] = 0b01     0x50006000
			GPIOF_MODER[21:20] = 0b01     0x50007000
	*/
	@PE8和PE10
	ldr r0, =0x50006000
	ldr r1, [r0]
	bic r1, r1, #(0x3 << 20)
	orr r1, r1, #(0x1 << 20)
	bic r1, r1, #(0x3 << 16)
	orr r1, r1, #(0x1 << 16)
	str r1, [r0]
	@PF10
	ldr r0, =0x50007000
	ldr r1, [r0]
	bic r1, r1, #(0x3 << 20)
	orr r1, r1, #(0x1 << 20)
	str r1, [r0]

	/* 1.3 配置PE8,PE10,PF10引脚为推挽输出 
			GPIOE_OTYPER[10] = 0b0       0x50006004
	*/
	@PE10,PE8
	ldr r0, =0x50006004
	ldr r1, [r0]
	bic r1, r1, #(0x1 << 8)
	bic r1, r1, #(0x1 << 10)
	str r1, [r0]
	@PF10
	ldr r0, =0x50007004
	ldr r1, [r0]
	bic r1, r1, #(0x1 << 10)

	/* 1.4 配置PE10,PE8,PF10引脚为低速模式 
			GPIOE_OSPEEDR[21:20] = 0b00     0x50006008
	 */
	 @PE10,PE8
	ldr r0, =0x50006008
	ldr r1, [r0]
	bic r1, r1, #(0x3 << 20)
	bic r1, r1, #(0x3 << 16)
	str r1, [r0]
	@PF10
	ldr r0, =0x50007008
	ldr r1, [r0]
	bic r1, r1, #(0x3 << 20)
	str r1, [r0]

	/* 1.5 配置PE10引脚禁止上下拉电阻
			GPIOE_PUPDR[21:20][17:16] = 0b00      0x5000600C
	 */ 
	@PE8,PE10
	ldr r0, =0x5000600C
	ldr r1, [r0]
	bic r1, r1, #(0x3 << 20)
	bic r1, r1, #(0x3 << 16)
	str r1, [r0]
	@PF10
	ldr r0, =0x5000700C
	ldr r1, [r0]
	bic r1, r1, #(0x3 << 20)
	str r1, [r0]
	/* 2. 实现led1灯闪烁的逻辑 */
	stop:
		/* 2.1 配置PE10引脚输出高电平 
				GPIOE_ODR[10] = 0b1    0x50006014
				GPIOE_BSRR[10] = 0b1   0x50006018
		 */
		@LED1亮,LED3灭
		ldr r0, =0x50006018
		mov r1, #(0x1 << 10)
		orr r1, r1, #(0x1 << 24) 
		str r1, [r0]
		@LED2灭
		ldr r0, =0x50007018
		mov r1,#(0x1 << 26) @LED2灭
		str r1, [r0]
		@延时1s
		bl delay_1s

		@LED1,3,2亮
		ldr r0, =0x50006018
		mov r1, #(0x1 << 26)
		orr r1, r1, #(0x1 << 24)
		str r1, [r0]
		
		ldr r0, =0x50007018
		mov r1, #(0x1 << 10)
		str r1, [r0]
		@延时1s
		bl delay_1s

		/* 2. 配置PE10引进输出低电平  
			GPIOE_ODR[10] = 0b0         0x50006014
			GPIOE_BSRR[26] = 0b1        0x50006018
		 */
		@LED1/2,3亮
		ldr r0, =0x50006018
		mov r1, #(0x1 << 26)
		orr r1, r1, #(0x1 << 8) @LED3亮
		str r1, [r0]
		@LED2灭
		ldr r0, =0x50007018
		mov r1,#(0x1 << 26) @LED2灭
		str r1, [r0]
		@延时1s
		bl delay_1s

		b stop


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

.end

(二)C语言版本

led.h

#ifndef __LED_H__
#define __LED_H__

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;
	volatile unsigned int BSRR;
} gpio_t;

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

#define RCC_AHB4 (*((unsigned int *)0x50000A28))

typedef  enum{
        LED1 = 1,
        LED2,
        LED3
}leds_t;

void led_init(void);
void led_turn_on(leds_t led);
void led_turn_off(leds_t led);

#endif

led.c

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

/***
 * 功能:LED1~3初始化;
 * LED1---PE10
 * LED2---PF10
 * LED3---PE8
***/
void led_init(void){
    //使能GPIOE和GPIOF的时钟,[5:4]置1
    RCC_AHB4 |= 0x3 << 4;
    //GPIOx_MODER寄存器,输出模式01
    //PE8
    GPIOE.MODER &= ~(0x3 << 16);
    GPIOE.MODER |= 0x1 << 16;
    //PE10
    GPIOE.MODER &= ~(0x3 << 20);
    GPIOE.MODER |= 0x1 << 20;
    //PF10
    GPIOF.MODER &= ~(0x3 << 20);
    GPIOF.MODER |= 0x1 << 20;
    //GPIOx_OTYPER寄存器,推挽输出,置0
    GPIOE.OTYPER &= ~(0x1 << 8);
    GPIOE.OTYPER &= ~(0x1 << 10);
    GPIOF.OTYPER &= ~(0x1 << 10);
    //GPIOx_OSPEEDR寄存器,低速,00
    GPIOE.OSPEEDR &= ~(0x3 << 16);
    GPIOE.OSPEEDR &= ~(0x3 << 20);
    GPIOF.OSPEEDR &= ~(0x3 << 20);
    //GPIOx_PUPDR寄存器,禁用上下拉电阻,00
    GPIOE.PUPDR &= ~(0x3 << 16);
    GPIOE.PUPDR &= ~(0x3 << 20);
    GPIOF.PUPDR &= ~(0x3 << 20);
}

void led_turn_on(leds_t led){
    switch (led)
    {
    case LED1://PE10
        GPIOE.BSRR = 0x1 << 10;
        //BSRR寄存器不需要担心向除了操作位以外的其他位中写入0,因为写0无意义,所以此处可以直接赋值操作,而无需使用"GPIOE.BSRR|=0x1<<10"
        break;
    case LED2:
        GPIOF.BSRR = 0x1 << 10;
        break;
    case LED3:
        GPIOE.BSRR = 0x1 << 8;
    }
}

void led_turn_off(leds_t led){
    switch (led)
    {
    case LED1://PE10
        GPIOE.BSRR = 0x1 << 26;
        break;
    case LED2:
        GPIOF.BSRR = 0x1 << 26;
        break;
    case LED3:
        GPIOE.BSRR = 0x1 << 24;
    }
}

main.c

#include "./include/led.h"

void delay_ms(unsigned int ms)
{
	int i, j;
	for (i = 0; i < ms; i++)
		for (j = 0; j < 1800; j++)
			;
}

int main()
{
	//初始化
	led_init();
	
	while(1)
	{
		led_turn_on(LED1);
		led_turn_off(LED2);
		led_turn_off(LED3);
		delay_ms(1000);//延时1s
		led_turn_on(LED2);
		led_turn_off(LED3);
		led_turn_off(LED1);
		delay_ms(1000);//延时1s
		led_turn_on(LED3);
		led_turn_off(LED1);
		led_turn_off(LED2);
		delay_ms(1000);//延时1s
	}
	return 0;
}

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-16 10:02:04       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-16 10:02:04       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-16 10:02:04       58 阅读
  4. Python语言-面向对象

    2024-07-16 10:02:04       69 阅读

热门阅读

  1. RandomAccessFile详细总结

    2024-07-16 10:02:04       20 阅读
  2. XML 解析异常问题解决

    2024-07-16 10:02:04       27 阅读
  3. GCN、GIN

    2024-07-16 10:02:04       22 阅读
  4. c#中的事件

    2024-07-16 10:02:04       26 阅读
  5. QT下,如何获取控制台输入

    2024-07-16 10:02:04       25 阅读
  6. Ajax是什么?如何在HTML5中使用Ajax?

    2024-07-16 10:02:04       24 阅读
  7. C 语言 do while 语句

    2024-07-16 10:02:04       25 阅读
  8. Apache Spark 的基本概念和在大数据分析中的应用

    2024-07-16 10:02:04       21 阅读