历史上的今天
今天是:2025年02月09日(星期日)
2020年02月09日 | 基于STM32单片机流水灯控制中的GPIO_Init()函数解析
2020-02-09 来源:elecfans
学习STM32时,首先要熟悉流水灯例程,在这里就来分析流水灯中的GPIO_Init()函数
例如:流水灯例程中使用的端口是macLED1_GPIO_PORT=GPIOB,
控制的引脚是GPIO_Pin_0,
引脚的模式是GPIO_Mode_Out_PP(通用推挽输出),
引脚的速率是GPIO_Speed_50MHz,
用到的寄存器是CRL
将上述的引脚、模式、速率换算成32位的16进制,分别是:
1)控制的引脚是GPIO_Pin_0
换算成32位的16进制是:0x0000 0001
2)引脚的模式是GPIO_Mode_Out_PP(通用推挽输出)
换算成32位的16进制是:0x0000 0010
3)引脚的速率是GPIO_Speed_50MHz
换算成32位的16进制是:0x0000 0003
然后调用库函数GPIO_Init(),初始化GPIOB
GPIO_Init(macLED1_GPIO_PORT, &GPIO_InitStructure);
GPIO_Init()函数的定义如下:


GPIO Mode Configuration
currentmode=((uint32_t)GPIO_InitStruct-》GPIO_Mode)&((uint32_t)0x0F);
可以得出currentmode=0x0000 0010 & 0x0000 000F
=0x0000 0000
if ((((uint32_t)GPIO_InitStruct-》GPIO_Mode) & ((uint32_t)0x10)) != 0x00)
判断是否是输出模式,“是”,执行下面代码;“否”,不执行
如:0x0000 0010 & 0x0000 00010 !=0x 0000 0000
则执行下面语句
{
/* Output mode */
currentmode “= (uint32_t)GPIO_InitStruct-》GPIO_Speed;
可以得出currentmode=currentmode | 0x0000 0003=0x0000 0000
=0x0000 0003
}
GPIO CRL ConfiguraTIon
if(((uint32_t)GPIO_InitStruct-》GPIO_Pin&((uint32_t)0x00FF)) != 0x00)
判断是否是Pin0~Pin7引脚,“是”,执行下面代码;“否”,不执行
如:0x0000 0001 & 0x 0000 00FF != 0x0000 0000
则执行下面语句
{
tmpreg = GPIOx-》CRL;
备份原CRL寄存器的值
则是:tmpreg=0x4444 4444
for (pinpos = 0x00; pinpos 《 0x08; pinpos++)
{
pos = ((uint32_t)0x01) 《《 pinpos;
pos是0x0000 0001左移 pinpos 位得到的
如:pos=0x0000 0001 《《 0x00
= 0x0000 0001
为后面的if (currentpin == pos) 判断作准备
/* Get the port pins posiTIon */
currentpin = (GPIO_InitStruct-》GPIO_Pin) & pos;
可得currentpin= 0x0000 0001 & 0x0000 0001
=0x0000 0001
为后面的if (currentpin == pos) 判断作准备
if (currentpin == pos)
由上面得出的pos = 0x0000 0001
currentpin = 0x0000 0001
两者相等,则执行下面代码语句
{
pos = pinpos 《《 2;
可得pos= 0x0000 0000 《《 2
=0x 0000 0000
/* Clear the corresponding low control register bits */
pinmask = ((uint32_t)0x0F) 《《 pos;
可得pinmask=0x0000 000F 《《 0x0000 0000
= 0x0000 000F
tmpreg &= ~pinmask;
可得tmpreg= tmpreg & ~pinmask
= 0x4444 4444 & 0xFFFF FFF0
= 0x4444 4440
/* Write the mode configuraTIon in the corresponding bits */
tmpreg |= (currentmode 《《 pos);
首先,要知道currentmode 《《 pos = 0x0000 0003 《《 0x 0000 0000
= 0x 0000 0003
可得tmpreg= tmpreg | 0x0000 0003
= 0x4444 4440 & 0x0000 0003
= 0x4444 4443
/* Reset the corresponding ODR bit */
if (GPIO_InitStruct-》GPIO_Mode == GPIO_Mode_IPD)
判断是否为下拉输入模式
{
GPIOx-》BRR = (((uint32_t)0x01) 《《 pinpos);
}
else
{
/* Set the corresponding ODR bit */
if (GPIO_InitStruct-》GPIO_Mode == GPIO_Mode_IPU)
判断是否为上拉输入模式
{
GPIOx-》BSRR = (((uint32_t)0x01) 《《 pinpos);
}
}
结果,两种输入模式都不是,而是通用推挽输出,所以不执行
}
}
GPIOx-》CRL = tmpreg;
把前面处理后的暂存值写入到CRL寄存器之中
也就是GPIOx-》CRL= 0x4444 4443
}
最终,向GPIOB组的CRL寄存器写入一个值:
GPIOx-》CRL = 0x4444 4443
转换为二进制是:(0100 0100 0100 0100 0100 0100 0100 0011)B
因此,Pin0的控制值为(0011)B
下面是CRL寄存器的说明

对比一下CRL寄存器的说明,Pin0的控制值正好可以把GPIO设置为符合我们输入参数要求的状态,即最大速率为50MHz的通用推挽输出模式。
史海拾趣
|
复古磁带又出现了!这次要介绍的是款磁带形式的 MP3,没错,它看起来很像是一个磁带,却是个 MP3。它的特色可是不为人知了,看外形与价格也知道,没有昂贵的LCD 屏幕,而且它还有一个秘密,就是没有存储,底部可以发现个 SD 槽,那就是要点所在,你 ...… 查看全部问答> |
|
请教一个问题: 我在Platform Builder 建立和模拟器的连接、下载运行时映像时,遇到下面的问题。 the specified ce boot image couldnot be loaded. your virtual machi ...… 查看全部问答> |
|
我单位设备最近直流24V电源电压一直偏低,一般工作的时候电压都在17 -18V,有时候能低到15V,380V变220V变压器电压都比正常低20V左右,220V变24V直流电源在拔掉24V输出的时候,变压器电压恢复正常了,只要接上24V变压器电压变低,直流输出的24V电源 ...… 查看全部问答> |
|
看了STM32应用上讲的使用定时器产生PWM输出,其中一个配置步骤: 根据需要的频率和占空比计算出输出高电平的时间和低电平的时间:OCHy = 通道y的高电平时间;OCLy =通道y的低电平时间把OCHy写入对应的输出比较寄存器,并启动计数器开始计数,比较 ...… 查看全部问答> |
|
Linux-2.6.21 S3c6400中断剖析<五>(原创)-上海嵌入式索漫科技培训教材 作者:下家山(请尊重原创,转载请注明) http://www.xiajiashan.com 4.1.2.1 desc->chip->unmask(irq)函数来自哪里? 其实default_startup和default_enable最终调用的是一个函数desc->chip->unmask(irq);那么这 ...… 查看全部问答> |




