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

文章目录

  • 一、特殊功能控制寄存器
    • (一)GPIOx_MODER寄存器
    • (二)GPIOx_OTYPER寄存器
    • (三)GPIOx_OSPEEDR寄存器
    • (四)GPIOx_PUPDR寄存器
    • (五)GPIOx_IDR寄存器
    • (六)GPIOx_ODR寄存器
    • (七)GPIOx_BSRR寄存器
  • 二、 查看外设控制器对应的特殊功能寄存器的基地址
  • 三、RCC
  • 四、代码实现
    • (一)汇编版本
    • (二)C语言版本

一、特殊功能控制寄存器

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

因此,控制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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/799499.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在互联网供应链系统可能是永远不会过时的系统

一、前言 在互联网在到人工智能&#xff0c;从基本的门户网站&#xff0c;社交网站&#xff0c;到移动互联网&#xff0c;视频网站&#xff0c;再到现在比较火爆短视频直播和人工智能AI&#xff0c;大模型。互联网的迭代&#xff0c;出现了无数的系统。但是有些系统一直久经不…

第八课:NAT地址转换(NAPT模式)

如何连接互联网&#xff1f; 如何远程管理网络设备&#xff1f; 1.路由怎么写&#xff1f; ip route 0.0.0.0 0.0.0.0 下一跳 0.0.0.0 0.0.0.0代表去往所有目的 2.NAT网络地址转换 PC&#xff0c;手机&#xff0c;在内网&#xff0c;用私网地址&#xff08;不要钱&#x…

c#中的特性

在C#中&#xff0c;特性&#xff08;Attributes&#xff09;是一种向程序元素&#xff08;如类、方法、属性等&#xff09;添加元数据的方式。特性可以用来提供关于程序元素的附加信息&#xff0c;这些信息可以在编译时和运行时被访问。 特性主要有以下几个用途&#xff1a; 提…

力扣第九题

回文数 提示&#xff1a; 给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。 代码展示&#…

<Rust>egui部件学习:如何在egui窗口中添加按钮button以及标签label部件?

前言 本专栏是关于Rust的GUI库egui的部件讲解及应用实例分析&#xff0c;主要讲解egui的源代码、部件属性、如何应用。 环境配置 系统&#xff1a;windows 平台&#xff1a;visual studio code 语言&#xff1a;rust 库&#xff1a;egui、eframe 概述 本文是本专栏的第二篇博…

Zookeeper源码学习

源码下载&#xff1a;https://archive.apache.org/dist/zookeeper/zookeeper-3.5.7/apache-zookeeper-3.5.7.tar.gz 1、持久化源码&#xff1a; Leader和Follower中的数据会在内存和磁盘中各保存一份。所以需要将内存中的数据持久化到磁盘中。 在zookeeper-server\org.apach…

计组_微程序

2024.06.26&#xff1a;计算机组成原理微程序学习笔记 第19节 控制器 9.1 硬布线控制器&#xff08;408基本不考&#xff09;9.2 微程序控制器&#xff08;好好学&#xff09;9.2.1 微程序(1) 基本概念(2) 控制器的组成(3) 控制器的工作过程 9.2.2 微指令(1) 编码方式&#xff…

验证服务插件:单据保存或审核时进行验证

提交审核的时候,校验 using Kingdee.BOS; using Kingdee.BOS.Core; using Kingdee.BOS.Core.DynamicForm.PlugIn; using Kingdee.BOS.Core.DynamicForm.PlugIn.Args; using Kingdee.BOS.Core.Validation; using Kingdee.BOS.Util; using System; using System.ComponentModel;…

【LeetCode:721. 账户合并 + 哈希表 + DFS】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

Linux--线程池(包含日志的解释)

线程系列&#xff1a; Linux–线程的认识(一) Linux–线程的分离、线程库的地址关系的理解、线程的简单封装&#xff08;二&#xff09; 线程的互斥&#xff1a;临界资源只能在同一时间被一个线程使用 生产消费模型 信号量 线程池 线程池&#xff08;Thread Pool&#xff09;是…

CSS实现超链接标签:鼠标光标为手形、取消下划线、当鼠标悬停时显示下划线

1、鼠标光标为手形 cursor: pointer; 2、显示/取消下划线 text-decoration: none; /* 文本取消下划线 */ text-decoration: underline; /* 文本添加下划线 */ 3、伪类选择器 伪类选择器是 CSS 中已经定义好的选择器&#xff0c;因此程序员不能随意命令。伪类选择器…

【BUG】已解决:ModuleNotFoundError: No module named ‘cv2’

已解决&#xff1a;ModuleNotFoundError: No module named ‘cv2’ 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c;武汉城市开…

C 语言指针进阶

1.0 指针的定义 指针是内存中一个最小单元的编号&#xff08;内存单元的编号称之为地址【地址就是指针指针就是地址】&#xff09;指针通常是用来存放内存地址的一个变量。本质上指针就是地址&#xff1a;口语上说的指针起始是指针变量&#xff0c;指针变量就是一个变量&#…

51单片机10(蜂鸣器介绍)

一、蜂鸣器介绍&#xff1a; 1、蜂鸣器是一种一体化结构的电子讯响器&#xff0c;采用直流电压供电&#xff0c;广泛应用于电子产品中作为发声器件。蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器。 &#xff08;1&#xff09;压电式蜂鸣器&#xff0c;它主要由多谐的一个增胀器…

JVM--自动内存管理--JAVA内存区域

1. 运行时数据区域 灰色的线程共享&#xff0c;白色的线程独享 白色的独享就是根据个体"同生共死" 程序计数器&#xff1a; 是唯一一个没有OOM(内存溢出)的地方 是线程独享的 作用&#xff1a; 是一块较小的内存空间,是当前线程所执行的字节吗的行号指示器 由于…

C#学习3-微软C#官方文档Microsoft-dotnet-csharp.pdf

文章目录 1.内插表达式的字段宽度和对齐方式 1.内插表达式的字段宽度和对齐方式 static void Main(string[] args) {var titles new Dictionary<string, string>() {["Doyle ,Arthur"] "Hound of the Basker,The",["Lodon ,Jack"] &quo…

vue router 切换路由的时候,页面的动画效果,使页面切换好看,以及控制有的页面使用切换路由特效,有的页面不用

一、使用切换效果 在router文件中 useTransition: true代表需要动画 meta: { title: “新开卡预填表单”, keepAlive: true, useTransition: true }, [{path: "/",name: "Home",meta: {title: "首页",keepAlive: true,useTransition: false},c…

Python 给存入 Redis 的键值对设置过期时间

Redis 是一种内存中的数据存储系统&#xff0c;与许多传统数据库相比&#xff0c;它具有一些优势&#xff0c;其中之一就是可以设置数据的过期时间。通过 Redis 的过期时间设置&#xff0c;可以为存储在 Redis 中的数据设置一个特定的生存时间。一旦数据到达过期时间&#xff0…

alike-cpp 编译

1. 源码链接&#xff1a; https://github.com/Shiaoming/ALIKE-cpp 2.已经安装好显卡驱动&#xff0c;cuda&#xff0c;cudnn,没安装的参考&#xff1a; 切记装cuda-11.x的版本&#xff0c;最好cuda11.3的版本 ubuntu重装系统后&#xff0c;安装cuda,cudnn-CSDN博客 3.安装…

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(十三)-更换无人机控制器

引言 本文是3GPP TR 22.829 V17.1.0技术报告&#xff0c;专注于无人机&#xff08;UAV&#xff09;在3GPP系统中的增强支持。文章提出了多个无人机应用场景&#xff0c;分析了相应的能力要求&#xff0c;并建议了新的服务级别要求和关键性能指标&#xff08;KPIs&#xff09;。…