当前位置: 首页 > article >正文

寄存器控制LED灯亮

一、整体代码

LED.c


#define RCC_APB2ENR (*(volatile unsigned int *)0x40021018)
#define GPIOA_CRL   (*(volatile unsigned int *)0x40010800)
#define GPIOA_ODR   (*(volatile unsigned int *)0x4001080C)
 
#define GPIOB_CRL   (*(volatile unsigned int *)0x40010C00)
#define GPIOB_ODR   (*(volatile unsigned int *)0x40010C0C)



void led1_init(void)//初始化
{
    RCC_APB2ENR |=0x1<<2;//GPIOA时钟使能
    RCC_APB2ENR |=0x1<<3;//GPIOB时钟使能
    
    GPIOA_CRL   &=~(0xf<<20);//23-20清零
    GPIOA_CRL   |=0x3<<20;//23-20->0011
    
    GPIOB_CRL &=~0xf;
    GPIOB_CRL |=0x3;
}

void led1_on(void)
{
    GPIOA_ODR &=~(0x1<<5);//5->0
    GPIOB_ODR &=~0x1;
}

void led1_off(void)
{
    
    GPIOA_ODR |=0x1<<5;//5->1
    GPIOB_ODR |=0x1;
}


LED.h

#ifndef LED_H
#define LED_H

void led1_init(void);
void led1_on(void);
void led1_off(void);
void mydelay(int x);

#endif

main.c

#include "led.h"

void mydelay(int x)
{
    int i=0;
    while(x--)
        for(i=500;i>=0;i--);
}

int main()
{
    led1_init();
    while(1)
    {
        led1_on();
        mydelay(500);
        
        led1_off();
        mydelay(500);
    }
}


二、分析

在这里插入图片描述
基地址加偏移地址等于寄存器地址
在这里插入图片描述
首先我们只数据手册上找到APB2的说明
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

如上图所示外设时钟RCC的基地址为0x4002 1000,偏移地址为0x18,两者相加便是他的寄存器地址
CRL(端口配置低寄存器),ODR(端口输出数据寄存器)同理(即为Port系列GPIO里面),GPIOA基地址为0x4001 0800,GPIOB基地址为0x4001 0C00

1)

在这里插入图片描述
0x1<<2 的操作是将二进制数 00000001 左移 2 位,得到 00000100,然后通过按位或赋值操作(|=)将 RCC_APB2ENR 寄存器中对应 GPIOA 时钟使能的位(第 2 位)置 1,从而开启 GPIOA 端口的时钟,使得后续可以对 GPIOA 端口的相关寄存器进行配置。B同理
在这里插入图片描述
在这里插入图片描述
GPIOA_CRL 寄存器用于配置 GPIOA 端口的低 8 位引脚(PA0 - PA7)的相关属性。0xf 转换为二进制是 1111,0xf<<20 就是把 1111 左移 20 位,得到一个在二进制表示下第 23 到 20 位为 1,其余位为 0 的数值。然后使用按位与非操作(&=~),将 GPIOA_CRL 寄存器中对应的第 23 到 20 位清零,这一步是为了清除原来可能存在的配置,为接下来准确设置引脚属性做准备。

2)

在这里插入图片描述0x1<<5 这个操作首先将十六进制数 0x1(转换为二进制就是 00000001)左移 5 位,得到二进制数 00100000。然后使用按位与非操作(&=~),将 GPIOA_ODR 寄存器中对应第 5 位(也就是 PA5 引脚对应的输出数据位,)清零,这里的对应PA5引脚清零代表亮灯在这里插入图片描述

3)

同2)
在这里插入图片描述
仔细阅读数据手册


http://www.kler.cn/a/456877.html

相关文章:

  • 华为云Welink数据怎么连接到小满CRM?
  • ROS2软件架构全面解析-学习如何设计通信中间件框架
  • 华为消费级QLC SSD来了
  • 自动驾驶新纪元:城区NOA功能如何成为智能驾驶技术的分水岭
  • 【每日学点鸿蒙知识】Shape描述、全局loading组件、checkbox样式、H5监听键盘收起、弹窗不关闭
  • # 【鸿蒙开发】多线程之Worker的使用
  • 前后端分离(前端删除数据库数据)
  • Linux top指令
  • Hadoop的生态系统所包含的组件
  • 物料描述的特殊字符
  • 关于自编译的一些文件
  • 谈谈 Wi-Fi 的 RTS/CTS 设计
  • 冥想的实践
  • QML学习(二) Qt Quick模块及QtQuick.Controls模块基础组件分类说明
  • 高精度算法:加减乘除 (学习笔记)
  • 强大的接口测试可视化工具:Postman Flows
  • JAVA: 子类“覆盖”父类的成员变量
  • React里使用uuid插件--生成随机的id
  • 大型系统中 Redis 的优化与挑战
  • Ubuntu升级ssh版本到9.8
  • AppAgent 源码 (AndroidController 类 )
  • 【LLM论文日更】| 训练大型语言模型在连续潜在空间中进行推理
  • 服务器被攻击怎么办
  • 如何注册华为云国际版账户:详细步骤指南
  • info There appears to be trouble with your network connection. Retrying
  • YOLOX算法及其改进