在讲述寄存器配置之前,我们先来看看二进制中,在不改变其他位的条件下,对某个位的置1和清零。

先看口诀:

清零用&            (对某一位,进行"与"操作。与0相与,会清零。与1相与,不改变)

置1用 |              (对某一位,进行"或"操作。与0相或,不改变。与1相或,会置1)

例如:

二进制:0001 1100,我想要在不改变其他位的情况下,将第四位清零。因为,清零用&,与0相与,会清零,与1相与,不改变。所以:

0001 1100  &   ~(0x01<<3)  ==  0001 0100

注意:0x01<<3  ==  0000 1000(这里由于要和8位的二进制数相与,所以这里会自动扩展成8位)(而且注意这里的移动是指16进制转换成二进制的移动,而不是对16进制进行移动),所以 ~(0x01<<3)  ==  1111 0111,

所以0001 1100  &   ~(0x01<<3) ==  0001 1100  &  1111 0111 ==  0001 0100

这样,在不改变其他位的情况下,第四位就被清零了。

二进制:0001 0100,我想要在不改变其他位的情况下,将第四位置1。因为,置1用 | ,与0相或,不改变。与1相或,会置1。所以:

0001 0100  |   0x01<<3  ==  0001 1100

注意:0x01<<3  ==  0000 1000(这里由于要和8位的二进制数相与,所以这里会自动扩展成8位)

所以0001 0100  |   0x01<<3 ==  0001 0100  |  0000 1000 ==  0001 1100

这样,在不改变其他位的情况下,第四位就被置1了。

上述是某一位的改变,但是如果我想一下清零四个位呢?那我们就用0x0f来进行左移

如:0x0f << 4 == 0000 1111 << 4  ==  1111 0000

所以,1011 0100  &   ~(0x0f<<4)   ==  1011 0100  &  0000 1111  ==  0000 0100

前面的四位一下就被清零了。

如何读取寄存器中某个位的值?

上面我们讲述了如何置位/清零寄存器中的值,现在我们来看如何读取寄存器中的值

假设某寄存器的值为:0000011010,这串数据被关在黑黑的寄存器中,我又没开天眼,我要怎样才能知道寄存器中的第4位(注意:第一个数为第0位)是1还是0?

又上面可知,与0相与,会清零。与1相与,不改变。

所以:        0000011010与0000010000进行"&"操作,如果结果为真,则0000010000中的第4位就为1,如果结果为假,则0000011010中的第4位就为0

就像这样:   这两个数相与,一定为0,即:为假

注意:         0000011010与0000010000进行"&"操作,其结果是为真

而不是为1,因为"&"操作得出的结果为0000010000,0000010000不等于1,而是等于16

程序:do{

temp = GPIOA_CRL;

}while( ! (temp & (1<<16)))

该程序是读取GPIOA_CRL中的第16位是1还是0,如果是1,则为真。由于非 "!" 的存在,所以 ! (temp & (1<<16))为假,所以此时do.....while循环不再循环下去。注意:这里需要用do....while而不用while,是因为需要先执行temp = GPIOA_CRL; 将GPIOA_CRL寄存器中的值放在变量temp中,然后再对temp进行真假判断。

下面我们来看I/O口输出模式的寄存器配置:

1.端口配置低寄存器

        注意:在寄存器配置的时候,我们都是先将对应的位清零后,再置1。

端口配置低位寄存器是用来配置某一组I/O的P0~P7引脚(一组I/O有16个I/O口)的I/O口的模式和最大输出速度的。

其中MODE是用来配置输出模式的最大输出速度的,而CNF是用来配置I/O口的工作模式的。所以,该寄存器是每4个位 配置一个I/O口。

输出速度:

1,最大速度----引脚上的电平最大翻转速度
2,频率和周期是互为倒数的关系
        1MHZ=1000000Hz 
        1s=1000Ms=10000000us

I/O口输出模式下有三种输出速度可选(2MHz,10MHz,50MHz),这个速度是指I/O⼝驱动电路的响应速度;I/O管脚内部有多个响应

不同的驱动电路,⽤户可以根据⾃⼰的需要选择合适的驱动电路。

⾼低频⽐较 
⾼频驱动电路:输出频率⾼,噪⾳⼤,功耗⾼,电磁⼲扰强; 
低频驱动电路:输出频率低,噪⾳⼩,功耗低,电磁⼲扰弱;提⾼系统EMI(电磁⼲扰)性能;

总结:通过选择速度来选择不同的输出驱动模块,达到最佳的噪⾳控制和降低功耗的⽬的如果需要选择较⾼频率信号,但是却选择了低频驱
动模块,很有可能会失真的输出信号;所以GPIO的引脚速度应与应⽤匹配。

举⼏个栗⼦: 
1. 对于串⼝来说,加⼊最⼤波特率为115200,这样只需要⽤2M的GPIO的引脚速度就可以了,省电噪⾳⼜⼩; 
2. 对于I2C接⼝,假如使⽤400 000波特率,若想把余量留⼤⼀些,2M的GPIO引脚速度或许是不够,这时可以选⽤10M的GPIO引脚速度; 
3. 对于SPI接⼝,假如使⽤18M或9M的波特率,⽤10M的GPIO⼝也不够⽤了,需要选择呢50M的GPIO引脚速度 
4. GPIO⼝设置为输⼊时,输出驱动电路与端⼝是断开的,所以这时配置输出速度是⽆意义的; 
5. 在复位期间和刚复位后,复位功能未开启,I/O端⼝被配置成浮空输⼊模式; 
6. 所有端⼝都有外部中断能⼒,当使⽤外部中断功能时,端⼝必须设置成输⼊模式; 
7. GPIO的配置具有上锁的功能,当配置好GPIO后,可以通过程序锁住配置组合,知道下次芯⽚复位才能解开;

转载链接:https://wenku.baidu.com/view/fb519748bb4ae45c3b3567ec102de2bd9605de3c.html

图中的x表示,这个寄存器可以对GPIOA~GPIOE I/O组的I/O口进行配置。

寄存器中有一个偏移地址:

我们大家都知道有一个寻址方式叫: 基地址 + 偏移地址 寻址。STM32中就是通过基地址 + 偏移地址寻找方式来找到对应的寄存器的。

这个偏移地址表示的是在某I/O组中,该寄存器的首地址,就是以I/O口组中的基地址为标准,加上偏移量得到的。我们假设是GPIOA组,从图中我们知道GPIOA组的基地址为0x4001 0800,而端口配置低位寄存器的偏移量为0x00,所以基地址 + 偏移地址 = 0x4001 0800 +  0x00 = 0x4001 0800,这个0x4001 0800就是端口配置低位寄存器的首地址。

寄存器中还有一个复位值:

复位值,指的是:在单片机复位后,该寄存器中被默认初始化的值。图中,该寄存器的复位值是0x4444 4444 ,所以在复位后,该寄存器被默认赋值为0x4444 4444。

我们现在给GPIOC组中的I/O口Pin7配置为推挽输出模式,输出速度为2MHZ:

清零用&,与0相与,会清零,与1相与,不改变。

置1用|,与0相或,不改变。与1相或,会置1

GPIOC->CRL  &= ~( (uint32_t) 0xf << 28 );       //将28~31位清零

GPIOC->CRL |= 0x2 << 28;        //设置I/O口模式

即:1111 << 28 == 1111 0000 0000 0000 0000 0000 0000 0000,所以 ~(0xf << 28 ) == 0000 1111 1111 1111 1111 1111 1111 1111

注意:这里要加上(uint32_t) 写成~( (uint32_t) 0xf << 28 ),否则会报警告 warning: #61-D: integer operation result is out of range

因为编译器默认signed int 即32位有符号整数类型,而0xf << 28实际为0xf0000000,这样就有可能改写了符号位(最高位)。所以,我们将其强转为无符号整数类型uint32_t

2.端口配置高寄存器

端口配置高位寄存器是用来配置某一组I/O的P8~P15引脚(一组I/O有16个I/O口)的I/O口的模式和输出速度的。

3.端口输入数据寄存器

4.端口输出数据寄存器

端口输出数据一共有16位,分别对应GPIO组中的Pin0~Pin15,写1则对应的I/O口输出1,写0则I/O口输出0。注意:设置/清除的意思就是置1/清零。

如:GPIOC->ODR |= 0x111 << 6;

即:使GPIOC组中的Pin6~Pin8都输出高电平。

5.端口位设置/清除寄存器

端口位设置/清除寄存器的功能和ODR寄存器的功能一样,都是为了设置I/O口的输出电平。实际上往端口位设置/清除寄存器写1/0后,端口位设置/清除寄存器就会往ODR寄存器对应的位写1/0,所以对端口位设置/清除寄存器操作,就是间接的对ODR寄存器进行操作。

注意:我们由上述可以知道,每个I/O口都有上面所描述的寄存器组。

寄存器版——点灯函数:

void LED_Config(void)        //初始化函数,配置GPIOC的PC6~PC8为通用推挽输出模式,输出速度为2Mhz
{
    RCC->APB2ENR |=0X1<<4;        //打开GPIOC时钟

GPIOC->CRH &= ~0xf;                //设置PC8
    GPIOC->CRH |= 0x1<<1;

GPIOC->CRL &= ~((uint32_t)0xff<<24);        //设置PC6与PC7
    GPIOC->CRL |= 0x22<<24;

GPIOC->ODR |= 0x7 << 6;    //关灯  
    
}

void LED_Open(void)
{

GPIOC->ODR &= ~(0x7 << 6);     //开灯,即I/O口输出低电平

}

void LED_Close(void)
{

GPIOC->ODR |= 0x7 << 6;    //关灯,即I/O口输出高电平    
    
}

stm32f103 GPIO——一灯大师之I/O口输出模式的寄存器配置相关推荐

  1. stm32f103 GPIO—— 一灯大师之库函数版

    在使用库函数之前,我们先来看GPIO寄存器的结构体 该结构体中的成员,包含了引脚,输出速度,输出模式.我们可以使用这个结构体来对I/O口进行配置. GPIO_InitTypeDef GPIO_Init ...

  2. stm32 IO口模式的寄存器配置

    CRL的位意义如下: 举几个配置例子: GPIOB->CRH&=0XFFFF00FF; GPIOB->CRH|=0X00003300;//PB10,11推挽输出 GPIOB-> ...

  3. 树莓派绿灯闪了几下不闪了_城市猎人的树莓派笔记一灯大师

    " 城市猎人的树莓派笔记" 06 一灯大师 VS2019新建一个.NET core控制台应用程序(不再重复放图了,之前有),并命名为DualColorLed 先引用模块原理图,两个 ...

  4. STM32F103 GPIO之按键检测

    1.直接上代码 #include "stm32f10x.h" #include "led.h" #include "key.h"void K ...

  5. 一灯大师,点亮ESP32的LED

    零. 声明 本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下: 第一篇:ESP-IDF基本介绍,主要会涉及模组,芯片,开发板的介绍,环境搭建,程序编译下载,启动流程等一些基本的操作,让你对 ...

  6. 一灯大师之点亮OK6410开发板上4个LED裸机程序---嵌入式回归第十篇

    接着上一篇关闭mmu和cache后,这一篇来点亮开发板上的一盏LED小灯,前面所作的初始化工作基本看不到效果,其实这一段也是最麻烦的!如果有问题调试很麻烦!点亮了LED之后就可以用LED来看程序是否如 ...

  7. 武林外传—一灯大师与众弟子漫谈Api网关选型

    南帝段王爷隐居桃源后,潜心研究,构筑了一套武林秘籍访问系统,系统是微服务部署的,拆分为多个模块,每个模块只做一件事情.系统刚上线的时候非常顺利,但随着访问量的增大,模块的增多,新问题越来越显现出来,他 ...

  8. STM32 一灯大师——寄存器点亮流水灯

    目录 1.配置端口输出数据寄存器(ODR) 2.配置低寄存器(CRL) 3.配置复位和时钟控制寄存器(RCC) 4.拓展:如何让PC2和PC3两个LED灯同时闪烁? 5.总结: GPIO功能框图和常用 ...

  9. ## STM32F103的光照、烟雾MQ2、有毒气体MQ135的ADC配置(寄存器版与库函数版

    STM32F103的光照.烟雾MQ2.有毒气体MQ135的ADC配置(寄存器版与库函数版 //#include "adc.h"#if 0 //寄存器编程 /************ ...

最新文章

  1. 监督学习与无监督学习的区别_机器学习
  2. 29使用QRcode方式生成二维码
  3. Spark_Sql50题(DataFrame)
  4. 软件项目需求调研报告模板下载_需求调研规范
  5. scala解析xml_Scala XML处理–文字,序列化,解析,保存和加载示例
  6. Glide 加载图片背景变绿
  7. 编译原理 第3版 第一章练习
  8. 计算机二十四点游戏怎么玩,扑克牌二十四点怎么玩?扑克牌二十四点游戏规则介绍...
  9. MATLAB零基础入门教程视频课程
  10. mpa和pis_有关压力单位pis、bar与Mpa换算
  11. 服务器扩容思路及问题分析
  12. jscpd--前端代码重复率检测
  13. 锁仓怎么解_[期货知识]期货锁仓后怎么解锁?期货锁仓解锁技巧介绍 - 南方财富网...
  14. Python 基础 - Day 1 Assignment - Three tier menu 三级菜单
  15. Groovy~Groovy介绍
  16. 【2021-09-16】最右app之websign
  17. 量子计算(七):量子系统
  18. 只保留QQ拼音输入法的设置
  19. js实现图片连续滚动播放
  20. 计算机创建只读用户,如何把电脑的文件夹在局域网共享成只读,别人不能删除和修改?...

热门文章

  1. PotPlayer 1.4 简体中文安装版 (云眼娱乐开发)
  2. 打击游戏作弊,诸多侠盗猎车手Online玩家遭封号
  3. SpringBoot实战:整合Redis、mybatis,封装RedisUtils工具类等
  4. 人工智能时代,如何避免沦为机器附庸?
  5. Android Studio lint工具所提示的需要注意的内容简要记录
  6. Linux学习笔记(21~29)
  7. ajax验证修改密码
  8. “深绿” 及 AlphaGo 对QQ分分彩源码出租指挥与控制智能化的启示
  9. 腾讯云原生数据库 TDSQL-C-产品概述
  10. 微信小程序.图片上传功能