自学内容网 自学内容网

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;
        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;
}

原文地址:https://blog.csdn.net/weixin_44254079/article/details/140444806

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!