4.3、使用寄存器版本点亮LED灯(内附代码)

发布者:Enchanted2021最新更新时间:2022-04-21 来源: eefocus关键字:寄存器版本  点亮  LED灯 手机看文章 扫描二维码
随时随地手机看文章

第一种:指针形式


led.c文件:

 

#include "led.h"

#include "stm32f4xx.h"

void LED_Init(void)

{

    //1左移五位既是将第五位置为1,查寄存器可知1是使能0失能

    RCC->AHB1ENR|= 1<<5;//使能RCC的AHB1时钟

 

 

    //PF9 的GPIO配置

    //将(1 1)左移18位再取反清零:2代表两位控制一IO,因为IO是F9,所以最后是~(3<<2*9),达到清零效果

 

     GPIOF->MODER &= ~(3<<2*9);//配置为0用&,配置为1用 | 

     GPIOF->MODER |= 1<<(2*9);//1既是0 1,代表输出模式(查寄存器)

 

     GPIOF->OSPEEDR &= ~(3<<2*9);//同理,清零

     GPIOF->OSPEEDR |= 2<<(2*9);//2是1 0,将F9设置为50MHZ的速度

 

     GPIOF->PUPDR &= ~(3<<2*9);//清零

     GPIOF->PUPDR |=1<<(2*9);//上拉

 

     GPIOF->OTYPER &= ~(1<<9);//清零,该寄存器是低16位有效,1位控制1个IO

     GPIOF->OTYPER |=0<<9;//置0,既是输出推挽(复位)

 

     GPIOF->ODR|= 1<<9;//1 控制高低电平

     //GPIOF->ODR&=~(1<<9);//

 

     //PF10         同理配置PF10 

     GPIOF->MODER &= ~(3<<2*10);

     GPIOF->MODER |= 1<<(2*10);

 

     GPIOF->OSPEEDR &= ~(3<<2*10);

     GPIOF->OSPEEDR |= 2<<(2*10);

 

     GPIOF->PUPDR &= ~(3<<2*10);

     GPIOF->PUPDR |=1<<(2*10);

 

     GPIOF->OTYPER &= ~(1<<10);

     GPIOF->OTYPER |=0<<10;

 

     GPIOF->ODR|= 1<<10;

}

///

led.h文件:

#ifndef __LED_H

#define __LED_H

 

void LED_Init(void);

 

#endif

///

 

main.c文件:

 

#include "stm32f4xx.h"

#include "led.h"

#include "delay.h"

 

int main(void)

{

    delay_init(168);

 

    LED_Init();

 

    while(1)

    {

 

        GPIOF->ODR&=~(1<<9);

        GPIOF->ODR&=~(1<<10);

        delay_ms(500);

 

        GPIOF->ODR |= 1<<9;

        GPIOF->ODR |=1<<10;

        delay_ms(500);

    }

}


------------------------------------------------------------------------------------------------------------------


第二种方法:配置基地址开始


// 设置寄存器宏定义

//1、时钟线

#define RCC_AHB1ENR *(volatile unsigned long *)(0x40023800 + 0x30)  // volatile 防止编译器优化 AHB1外设使能时钟线

 

#define GPIOF_MODER *(volatile unsigned long *)(0x40021400 + 0x00)  // GPIOF的模式寄存器

#define GPIOF_OTYPER *(volatile unsigned long *)(0x40021400 + 0x04)  // GPIOF的输出类型寄存器

#define GPIOF_OSPEEDR *(volatile unsigned long *)(0x40021400 + 0x08)  // GPIOF的输出速度寄存器PUPDR

#define GPIOF_PUPDR *(volatile unsigned long *)(0x40021400 + 0x0c)  // GPIOF的上下拉寄存器

#define GPIOF_ODR *(volatile unsigned long *)(0x40021400 + 0x14)  // GPIOF的输出数据寄存器

#define GPIOF_BSRR *(volatile unsigned long *)(0x40021400 + 0x18)  // GPIOF的复位/置位寄存器

 

#define GPIOE_MODER *(volatile unsigned long *)(0x40021000 + 0x00)  // GPIOF的模式寄存器

#define GPIOE_OTYPER *(volatile unsigned long *)(0x40021000 + 0x04)  // GPIOF的输出类型寄存器

#define GPIOE_OSPEEDR *(volatile unsigned long *)(0x40021000 + 0x08)  // GPIOF的输出速度寄存器PUPDR

#define GPIOE_PUPDR *(volatile unsigned long *)(0x40021000 + 0x0c)  // GPIOF的上下拉寄存器

#define GPIOE_ODR *(volatile unsigned long *)(0x40021000 + 0x14)  // GPIOF的输出数据寄存器

#define GPIOE_BSRR *(volatile unsigned long *)(0x40021000 + 0x18)  // GPIOF的复位/置位寄存器

 

 

// 大概时间的延时函数

void delay(int n)

{

    while(n--)

    {

        int i = 1000;

        while(i--);

    }

}

 

// 初始化LED

int init_led(void)

{

    // 2、初始化时钟、寄存器  第5位置1就是使能

    RCC_AHB1ENR |= 1<<5; 

 

    //3、配置寄存器各种参数,LED只是输出,所以选择每个参数里面的输出模式

    // ①初始化GPIOF为输出模式

    //---------------模式--移动位数

    GPIOF_MODER &= ~(0x3<<18);   // 清空第18位和19位  11

    GPIOF_MODER |= 1<<18; // 配置PF9

 

    //GPIOF_MODER &= ~(0xF<<18);   // 清空第18位和19位、20位、21位  1111

    //GPIOF_MODER |= 0x5<<18; // 配置PF9、PF10

    GPIOF_MODER &= ~(0x3<<20); // 清空第20位、21位   11

    GPIOF_MODER |= 1<<20;//配置PF10

 

    // ②配置GPIOF的输出类型为推挽

    GPIOF_OTYPER &= ~(0x1<<9);  // 清空第9位

    GPIOF_OTYPER &= ~(0x1<<10);  // 清空第10位

 

    // ③配置GPIOF的输出速度

    GPIOF_OSPEEDR &= ~(0x3<<18);  // 清空第18位和19位  11

    GPIOF_OSPEEDR &= ~(0x3<<20);  // 清空第20 21  11

    GPIOF_OSPEEDR |= 0x2<<18; // 50M速度

    GPIOF_OSPEEDR |= 0x2<<20; // 50M速度

 

    // ④配置 GPIOF为上拉输出

    GPIOF_PUPDR &= ~(0x3<<18);  // 清空第18位和19位  11

    GPIOF_PUPDR |= 1<<18; // 配置PF9为上拉输出

    GPIOF_PUPDR &= ~(0x3<<20);  // 清空第20位和21位  11

    GPIOF_PUPDR |= 1<<20; // 配置PF10为上拉输出

 

    // ⑤输出数据:高电平 1 低电平 0

    GPIOF_ODR |= 1<<9; // PF的第9个引脚输出高电平

    GPIOF_ODR |= 1<<10; // PF的第10个引脚输出高电平

 

    /*********************************PE脚**************************************/

    // 初始化时钟 寄存器第4位置1就是使能

    RCC_AHB1ENR |= 1<<4; //PE脚

 

    // 初始化GPIOF为输出模式

    GPIOE_MODER &= ~(0x3<<26);   // 清空第26位和272829位  11

    GPIOE_MODER |= 1<<26; // 配置PF9, 1010即是5,可同时配置

 

    GPIOE_MODER &= ~(0x3<<28); // 清空第20位、21位   11

    GPIOE_MODER |= 1<<28;//配置PF10

 

    // 配置GPIOF的输出类型为推挽

    GPIOE_OTYPER &= ~(0x1<<13);  // 清空第9位

    GPIOE_OTYPER &= ~(0x1<<14);  // 清空第10位

 

    // 配置GPIOF的输出速度

    GPIOE_OSPEEDR &= ~(0x3<<26);  // 清空第18位和19位  11

    GPIOE_OSPEEDR &= ~(0x3<<28);  // 清空第20 21  11

    GPIOE_OSPEEDR |= 0x2<<26; // 50M速度

    GPIOE_OSPEEDR |= 0x2<<28; // 50M速度

 

    // 配置 GPIOF为上拉输出

    GPIOE_PUPDR &= ~(0x3<<26);  // 清空第18位和19位  11

    GPIOE_PUPDR |= 1<<26; // 配置PF9为上拉输出

    GPIOE_PUPDR &= ~(0x3<<28);  // 清空第20位和21位  11

    GPIOE_PUPDR |= 1<<28 ;// 配置PF10为上拉输出

 

    // 输出数据:高电平 1 低电平 0

    GPIOE_ODR |= 1<<13; // PF的第9个引脚输出高电平

    GPIOE_ODR |= 1<<14; // PF的第10个引脚输出高电平

    return 0;

}

 

int main(void)

{

    // 初始化LED

    init_led();

 

     while (1)

     {

        // 点亮LED0

        GPIOF_ODR &= ~(1<<9); // PF的第9个引脚输出低电平

        delay(2000);

        GPIOF_ODR |= 1<<9;

        delay(2000);

 

        // 输出数据:高电平 1 低电平 0

        GPIOF_ODR &= ~(1<<10);

        delay(2000);

        GPIOF_ODR |= 1<<10; // PF的第9个引脚输出高电平 

        delay(2000);

 

        GPIOE_ODR &= ~(1<<13);

        delay(2000);

        GPIOE_ODR |= 1<<13; // PE的第13、14个引脚输出高电平

        delay(2000);

 

        GPIOE_ODR &= ~(1<<14);

        delay(2000);

        GPIOE_ODR |= 1<<14;

        delay(2000); 

     }

}


两者的区别在于一个需要配置基地址,一个直接用指针对寄存器进行操作,那怎样配置基地址,下面解释一下:


1、根据STM32F4xx中文参考手册的2.3节存储器的映射找到对应总线、外设的边界基地址,我这里只截了部分图,仅供参考

2、找到对应寄存器的偏移地址,在STM32F4xx中文参考手册7.4节

配置后如下所示:

2、最后对应寄存器进行对其位移操作即可(寄存器映射),可参考上面的代码

总结:这里以一个简单的LED闪烁来了解对寄存器进行具体的操作,使自己能够用寄存器来进行项目的开发,其他的外设配置是一样的原理。

关键字:寄存器版本  点亮  LED灯 引用地址:4.3、使用寄存器版本点亮LED灯(内附代码)

上一篇:STM32的DMA基本原理及实现过程
下一篇:教你如何使用STM32控制无源蜂鸣器发声播放音乐

推荐阅读最新更新时间:2024-11-12 20:27

stm32 通过串口控制led灯亮灭 并通过lcd显示led灯的亮灭状态
#include main.h #include stm32f0xx_hal.h /* USER CODE BEGIN Includes */ #include lcd.h /* USER CODE END Includes */ /* Private variables ---------------------------------------------------------*/ UART_HandleTypeDef huart1; /* USER CODE BEGIN PV */ /* Private variables -----------------------------------------
[单片机]
Power Integrations推出CREE LED灯泡驱动器参考设计
美国加利福尼亚州圣何塞,2014年6月11日讯 – 高效率、高可靠性LED驱动器IC领域的世界领导者Power Integrations公司(纳斯达克股票代号:POWI)今日推出四款适用于PAR30及PAR38 LED灯泡的驱动器参考设计。这四款设计由Power Integrations和CREE共同开发而成,它们体现了Power Integrations的LYTSwitch™-4驱动器IC与CREE MT-G2 EasyWhite LED的完美结合。DER-364和DER-365分别详细介绍了低压及高压PAR 30 LED灯泡驱动器,DER-350和DER-396则分别对应于低压及高压PAR 38灯泡。这四款参考设计以及其他参考
[电源管理]
兆驰半导体新进Unimax设备经调试产出外延片成功点亮,Mini LED扩产提速
江西兆驰半导体有限公司消息显示,5月27日,该公司新进Unimax设备经调试产出外延片成功点亮,标志着兆驰半导体扩产计划顺利进行,Mini LED扩产提速。 据悉,自签约以来,兆驰半导体扩产计划进展顺利,首批设备于上月进厂调试,5月27日正式点亮。经此项验证,后续设备将开始分批交货进厂,同时与之配套的平片、PSS及芯片设备也将按计划扩产。 官方消息显示,此前公布的100万片产能,预计将在2023年第一季度达成。 本轮扩产所选购的Unimax外延设备是国内领先的外延MOCVD设备,在波长均一性方面表现优秀,为外延片参数更好地匹配Mini/Micro LED新型显示芯片工艺需求做好充分准备,同时具备更稳定的量产性能。
[手机便携]
【扫盲】LED灯丝灯驱动技术全方位解析
我从去年年底就开始销售 LED 灯丝灯的驱动,在此期间,新客户在产品选型时,有很多疑问。看来,大家对这款灯几种驱动方案的特点还有些陌生。为了方便客户入门,也为了梳理一下这方面的知识,今天,我抛砖引玉,就自己对LED灯丝驱动的理解,跟大家分享如下。    一、LED灯丝驱动分类   1、从驱动方案角度,LED灯丝电源分为三类:阻容降压;线性恒流;IC恒流。   2、从结构角度,LED灯丝电源分为两类:全玻璃无塑件;带塑件。其中无塑件还需要区分灯头类型,比如E26/E27/B22是一类;E14/E17是另外一类。    二、3种LED灯丝驱动方案的主要特点   1、阻容降压:尺寸小,成本低,电压变动不恒流,有频闪,必过EMC
[电源管理]
【扫盲】<font color='red'>LED灯</font>丝灯驱动技术全方位解析
能够发电的足球,踢30分钟后可以点亮LED灯三小时
  据国外媒体报道,踢足球充满乐趣且能锻炼身体,但现在它还能为你家提供电能。   非盈利社会企业Uncharted Play公司的八位哈佛大学毕业生组成的研究队伍发明出了能产生电力的足球,而它产生的电力可供一个小LED灯持续照明。研究人员将这个足球命名为“SOCCKET”,这个足球的里面有一个钟摆。当足球滚动的时候,这个钟摆就会不停地摇摆,聚集动能,然后将一个与之连接的发电机转变为可充电的电池。经过30分钟的运动后,这个足球的电力就能供应一盏LED灯持续照明3个小时。   此外,这种足球是由不透气、防水的乙烯泡沫制成,这意味着它非常的耐用,完全可以用于最激烈的足球比赛。这个能产生电力的足球仅比正常足球重一盎司,其发明人希望将这个足
[电源管理]
能够发电的足球,踢30分钟后可以<font color='red'>点亮</font><font color='red'>LED灯</font>三小时
STM32之点亮LED
学习一个新的处理器,第一个程序肯定就是点亮LED,它可以让我们较快的、较清晰的了解到一个处理器的程序结构,学习32也不例外,首先第一个程序我们就来点亮LED,点亮LED程序有很多种,这里我们用库函数来实现LED的闪烁 本人使用的开发板是正点原子的精英版开发板。 首先复制一下我们之前建好的工程模板,然后把文件夹命名为LED。 然后打开这个工程文件,第一步我们需要再建立两个空白页,并按照我上一篇博客的方法把他俩存到HARDWARE文件夹里面,一个命名为led.c,另一个命名为led.h,然后再在keil MDK软件里面把这两个文件给添加到工程中去,添加完之后,我们的工程结构如下图 添加完之后,我们不要忘记要把
[单片机]
STM32之<font color='red'>点亮</font>LED
51单片机:LED灯流水灯
知道闪烁原理后,我们就可以将所有引脚依次输出0V、延时、输出5V,就能达到流水灯效果,但这样写太呆板,咱们利用C语言for循环,再进行位运算就可以简单达到效果,程序如下 #include reg52.h //引用头文件 void Delay(int time) { while(time--) //while循环一次需要10us { } } int main() { int i = 0; while(1) { for(i=0;i 8;i++) { P2=~(0x01 i); Delay(50000); } } return 0; } 实验现象如
[单片机]
51单片机:<font color='red'>LED灯</font>流水灯
STM32-点亮LED灯(GPIO配置)
点亮LED灯应该是每一人学习硬件的第一个实验了吧!从51到32在到ARM,废话少说,下面开始使用STM32点亮LED灯。 GPIO:又叫通用输入输出口,是微控制器必不可少的外设单元,用来和外界进行信号传递,数据交互的接口。 STM32的GPIO根据型号的不同分为A-H组,每一组都称为GPIOx组,每组都有独立的寄存器,因为相对于寄存器,函数版的使用还是比较容易入门的,尤其是有些编程基础的人来讲,但是寄存器是不可以忽视的,学会了基础的函数操作还是要回头去看看具体寄存器是如何运行的,这点很重要,高手和菜鸟的区别吧! STM32的GPIO还具有十分强大复用功能,这点以后会介绍和使用到。现在就把它的GPIO当成一个可输出高低电平的引脚就可
[单片机]

推荐帖子

瑞萨芯片的学习
我们一起来学习瑞萨这块芯片。电子竞赛要用到的芯片。瑞萨芯片的学习估计还是飞机的主控支持一下楼主~~请问MCU是不是必须用瑞萨的单片机啊,以前没有学过,用12c芯片可以吗??我靠看来得现学了
王。。。。 电子竞赛
STM32
NANDFlash模拟U盘的过程中,需要给NAND做文件系统吗,如果需要的话,步骤有哪些呢???STM32
meijianmao stm32/stm8
关于应用MSP430F449设计一个电流表的量程问题
我们在利用F449进行设计一个电流表,在对固定电阻取电压时考虑以下几个问题:1.F449的供电电压是9v(我是说那个变压器),那么对于单片机进行AD转换时的驱动电压是多少?也就是我所能得到的电压的范围是多少??2.F449在进行AD转换过程中,所能分辨的最小的电压增量是多少,比如0.005v和0.006v,单片机是否能进行辨别,如果不能的话,是由什么来计算和确定这个分辨量的??很急。。。跪求能者能解答。。。小女子在此一拜。。。~~o(_)o~~关于应用MSP430F449设计
skyzxcvbnm 微控制器 MCU
CircuitPython 发布 4.0.2 版
作为micropython目前最重要的分支,CircuitPython发布了4.0.2版,这是4.x的第二个错误修复版本。自4.0.1以来的新修复 修复导致崩溃的根显示组的错误gc。感谢@dhalbert和@ATMakersBill 修复gamepadshift在快速阅读时工作。感谢@deshipu和@kattni 修复nrfNeoPixel写短链。感谢@dhalbert和@bmeisels 修复导入损坏的.mpy时崩溃。感谢@tannewt和@jn
dcexpert MicroPython开源版块
如何保证SPI flash中的数据安全?
各位大侠,小弟有个问题请教:请问:将用户开发的程序存储到SPIFLASH后供其他芯片调用,有没有什么措施《防止FLASH中的数据被导出》,导出数据有时能够直接用于其他FLASH中;另外,是否有自带加密功能的SPIFLASH芯片呢,如果有,请推荐下型号,或是分享下资料;感激不尽,在线等待答复。如何保证SPIflash中的数据安全?普通的SPIFLASH好象没有办法加密我有办法解决。QQ:359117122我也想知道
wende 嵌入式系统
三极管怎么加个反馈
想100kHz的信号高电压放大,这样用三极管怎么样?但这样输出幅度和三极管的B值有关。能不能加个反馈使得输出放大像运放应用一样只和配搭的电阻值有关,当然电路越简单越好,精度可以差些。如果能推荐个高压高频运放直接用也非常感谢,未来可能电压高到100V,频率300kHz,但是功率不大三极管怎么加个反馈此电路中三极管已经加有本级负反馈,是三极管发射极到地串联了100欧电阻构成的。由于本级负反馈,输出幅度与三极管电流放大倍数关系不是很大。此电路三极管发射极电阻数值为100欧,集电
rockchn 模拟电子
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved