野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11569|回复: 4

流水灯GPIO_Init()问题

[复制链接]
发表于 2015-3-31 20:11:34 | 显示全部楼层 |阅读模式
/*备份原CRL 寄存器的值*/
31. tmpreg = GPIOx->CRL;
32. /*循环,一个循环设置一个寄存器位*/
33. for (pinpos = 0x00; pinpos < 0x08; pinpos++)
34. {
35. /*pos 的值为1 左移pinpos 位*/
36. pos = ((uint32_t)0x01) << pinpos;
37. /* 令pos 与输入参数GPIO_PIN 作位与运算,为下面的判断作准备*/
38. currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
39. /*判断,若currentpin=pos,说明GPIO_PIN 参数中含的第pos 个引脚需要配置*/
40. if (currentpin == pos)
41. {
42. /*pos 的值左移两位(乘以4),因为寄存器中4 个寄存器位配置一个引脚*/
43. pos = pinpos << 2;
44. /*以下两个句子,把控制这个引脚的4 个寄存器位清零,其它寄存器位不变*/
45. pinmask = ((uint32_t)0x0F) << pos;
46. tmpreg &= ~pinmask;
47. /* 向寄存器写入将要配置的引脚的模式*/
48. tmpreg |= (currentmode << pos);
49. /* 复位GPIO 引脚的输入输出默认值*/
50. /*判断是否为下拉输入模式*/
51. if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
52. {
53. /*下拉输入模式,引脚默认置0,对BRR 寄存器写1 可对引脚置0*/
54. GPIOx->BRR = (((uint32_t)0x01) << pinpos);
55. }
56. else
57. {
58. /*判断是否为上拉输入模式*/
59. if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
60. {
61. /*上拉输入模式,引脚默认值为1,对BSRR 寄存器写1 可对引脚置1*/
62. GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
63. }
64. }
65. }
66. }
67. /*把前面处理后的暂存值写入到CRL 寄存器之中*/
68. GPIOx->CRL = tmpreg;






1.
42. /*pos 的值左移两位(乘以4),因为寄存器中4 个寄存器位配置一个引脚*/
43. pos = pinpos << 2;
这个我看过CRL是每4位控制一个引脚 哪和左移(比如0x01变成0x04)什么关系啊不懂啊!



2.
44. /*以下两个句子,把控制这个引脚的4 个寄存器位清零,其它寄存器位不变*/
45. pinmask = ((uint32_t)0x0F) << pos;
46. tmpreg &= ~pinmask;
这个是怎么做到清零的,没算出来,看不懂





回复

使用道具 举报

发表于 2015-3-31 21:16:57 | 显示全部楼层
本帖最后由 亽亼 于 2015-3-31 21:19 编辑

1. pos = pinpos << 2; 因为寄存器中4 个寄存器位配置一个引脚:这样比如我要配置第4(pinpos为3,因为从0开始算)管脚,那么pos=12。这个12就是CRL寄存器中第4管脚的首位(12,13,14,15)。主要就是把管脚最低位拿出来,给下面程序用
2.  pinmask = ((uint32_t)0x0F) << pos;还是以第4管脚为例,pos=12。这样的结果就是CRL寄存器中的第(12,13,14,15)位全部为1。即(0xf000)
    tmpreg &= ~pinmask;后面的(~pinmask)使得原本是(0xf000)变为(0xffff0fff)。再与tmpreg进行&(与)运算。就可以达到清零作用了。
回复 支持 反对

使用道具 举报

发表于 2015-3-31 21:20:57 | 显示全部楼层
随便提下,在《零角度玩转stm32-V2》里边有讲解置1和清零这几个运算
回复 支持 反对

使用道具 举报

发表于 2015-7-21 01:27:53 | 显示全部楼层
本帖最后由 seu 于 2015-7-21 01:29 编辑

请教一下
pinmask = ((uint32_t)0x0F) << pos
pos=12,这个左移的操作, 0x0F 左移12位,是因为0x0F转化uint32_t类型,一共有32位,所以高位没有移出吗?
回复 支持 反对

使用道具 举报

发表于 2015-7-21 08:46:15 | 显示全部楼层
可以这样理解的
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-23 18:52 , Processed in 0.030919 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表