一、前言
一、前言
上一节我们学习了怎样用固件库和寄存器去实现LED的控制,现在,我们就可以很简单的写出我们的程序。
首先,还是看我们的原理图
图1
可以看到各个端口所控制的LED,接下来就写出我们的代码。
二、寄存器控制LED(包含ODR、BSRR、BRR)
需求:
图2
1、分别点亮红、绿、蓝灯;
2、使用ODR、BSRR、BRR来控制
首先,我们将要使用的地址使用我们认识的词或者比较好看的词代替
图3
然后,我们就可以按照控制LED的一般方法去配置LED外设,我们先配置和使用我们比较熟悉的ODR寄存器,你可以想象它是一个开关,控制着LED的亮灭。写入1,它就是开,写入0,它就是关。
图4
这里就是控制两个灯的函数,不过用了形参light1和light2来控制灯的亮什么颜色,u16是unsigned short,如果不会C语言的可以在评论区扣个1,我会出个C语言与单片机的教程。
言归正传,我们可以看到图4中的
GPIOB_ODR = 0xFFFF;
这是为了清除ODR端口的全部设置为高电平,这样LED就不会亮,简单粗暴,不过非常有用。
注意:在实现简单的点亮LED等简单电路时可以使用这条代码,但在实现较为复杂的电路时,最好不要使用此代码,以防出现Bug。
还有这条代码可以应用在消除一些情况不明的端口电位,将其初始化,再将要实现的功能写入。
那么,我们可以使用什么代码呢?
我们可以使用以下代码进行清除:
GPIO_ODR |= 0x23
图5
因为我们要使用的是ODR的0、1、5这三位,因此,我们先让他们置1,即0010 0011,这样就可以将他们直接进行清零操作而不影响其他位的ODR电平情况。
接下来,我们可以看到
//清空控制PBX的端口位
GPIOB_CRL &= ~((0x0F<< (4*light1)) | (0x0F<< (4*light2)));
这是为了清除我们要使用的GPIOB_CRL的端口,当然了,不用去猜测跟"谁"去进行与运算,因为"谁"取决于上一次使用这个端口后留下来的电位情况,因此在每一次使用端口前都需要将端口清零,这样进行与运算就可以得到你想要的结果,因为0与1相与还是得1。
我们再往下写
//配置PBX为通用推挽输出,速度为10M
GPIOB_CRL |= ((1<< 4*light1) | (1<< (4*light2)));
这段代码就是设置我们的CRL寄存器,让GPIOB的PB0|PB1|PB5端口设置为推挽输出和10MHz输出(0001或者0x1);
我们将这些配置以及相关外设现象成一个开关连着灯泡开关接着电源,配置好后,这样我们就完成了一个完整的回路。
接下来,要想让灯泡亮,我们就要打开开关。让我们的“开关”ODR置0;
//PBX输出电平
GPIOB_ODR &= ~((num3<<light1) | (nums3<<light2));
以上就是使用ODR来控制GPIO端口的一种使用方法。
接下来,我们使用BSRR和BRR来实现LED的亮灭。
首先还是来看BSRR的原理:
图6
我们可以看到BSRR,它还是相当于一个开关,但是不是像ODR那样写0输出低电平,写1输出高电平,而是写入高16位1为输出低电平,写入低16位1为输出高电平,我们可以把它想象成两个按键,一个摁一下关,另一个摁一下开。
了解了原理后,我们可以来分析代码:
图7
我们可以看到在这个函数的第一行那里我写了以下代码:
GPIOB_BRR = 0x0000;
这一行依旧是清零操作,依旧简单暴力地去清空BSRR的所有位,但是这清零操作对于BSRR来说,一点影响都没有,单纯是为了强迫症,也可以不写。
接下来
为了让LED亮起来,我们就要让BSRR的高16位写入1,想让LED灭,就要使BSRR的低16位写入1。
图8
我这里直接使用寄存器去操作BSRR,利用形参number去判断BSRR在哪个16位写入1。
是不是非常简单
下面的BRR相较于BSRR来说有点特殊,它只有低16位可以操作,而且只能让它亮,就不是非常好。
我们可以看一下BRR寄存器的位实现
图9
BRR它只能对低16位的寄存器进行控制,写入1时,将该位置0,得到一个低电平,可以利用它这样的特性来点亮LED。
下面为我写的BRR寄存器控制LED的代码,美中不足的是它不能够关灯
为了让他可以关灯,我们可以在LED对应位置给它一个高低平,
GPIO_ODR = 0x23; // 使用ODR强制置1
//GPIO_BSRR |= (0x23<<16) //或者使用BSRR去给它置1
三、总结
使用寄存器来控制GPIO(LED),其实就是按照使用手册上的对应端口控制寄存器来实现控制。BRR、BSRR和ODR都可以控制LED,那为什么还需要这么多的控制寄存器,我的理解就是BSRR和BRR是为了防止有人在写代码的时候将1和0搞混乱,导致的BUG,而使用这两个寄存器就不容易搞混。ODR寄存器使用方便,操作简单,但容易搞混。实际开发还是按照个人习惯来判断寄存器的好坏,我个人比较喜欢BSRR,操作简单又不会搞混。
关注公众号,有超多好东西等着你