1 /**
2 *函数功能:初始化引脚模式
3 *参数说明:GPIOx,该参数为GPIO_TypeDef 类型的指针,指向GPIO 端口的地址
4 * GPIO_InitTypeDef:GPIO_InitTypeDef 结构体指针,指向初始化变量
5 */
6 void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
7 {
8 uint32_t currentmode =0x00,currentpin = 0x00,pinpos = 0x00,pos = 0x00;
9 uint32_t tmpreg = 0x00, pinmask = 0x00;
10
11 /*---------------- GPIO 模式配置 -------------------*/
12 // 把输入参数GPIO_Mode 的低四位暂存在currentmode
13 currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) &
14 ((uint32_t)0x0F);
15
16 // bit4 是1 表示输出,bit4 是0 则是输入
17 // 判断bit4 是1 还是0,即首选判断是输入还是输出模式
18 if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) &
19 ((uint32_t)0x10)) != 0x00)
20 {
21 // 输出模式则要设置输出速度
22 currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;
23 }
24 /*-----GPIO CRL 寄存器配置 CRL 寄存器控制着低8 位IO- ----*/
25 // 配置端口低8 位,即Pin0~Pin7
26 if (((uint32_t)GPIO_InitStruct->GPIO_Pin &
27 ((uint32_t)0x00FF)) != 0x00)
28 {
29 // 先备份CRL 寄存器的值
30 tmpreg = GPIOx->CRL;
31
32 // 循环,从Pin0 开始配对,找出具体的Pin
33 for (pinpos = 0x00; pinpos < 0x08; pinpos++)
34 {
35 // pos 的值为1 左移pinpos 位
36 pos = ((uint32_t)0x01) << pinpos;
37
38 // 令pos 与输入参数GPIO_PIN 作位与运算
39 currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
40
41 //若currentpin=pos,则找到使用的引脚
42 if (currentpin == pos)
43 {
44 //pinpos 的值左移两位(乘以4),因为寄存器中4 个位配置一个引脚
45 pos = pinpos << 2;
46 //把控制这个引脚的4 个寄存器位清零,其它寄存器位不变
47 pinmask = ((uint32_t)0x0F) << pos;
48 tmpreg &= ~pinmask;
50 // 向寄存器写入将要配置的引脚的模式
51 tmpreg |= (currentmode << pos);
52
53 // 判断是否为下拉输入模式
54 if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
55 {
56 // 下拉输入模式,引脚默认置0,对BRR 寄存器写1 对引脚置0
57 GPIOx->BRR = (((uint32_t)0x01) << pinpos);
58 }
59 else
60 {
61 // 判断是否为上拉输入模式
62 if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
63 {
64 // 上拉输入模式,引脚默认值为1,对BSRR 寄存器写1 对引脚置1
65 GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
66 }
67 }
68 }
69 }
70 // 把前面处理后的暂存值写入到CRL 寄存器之中
71 GPIOx->CRL = tmpreg;
72 }
73 /*--------GPIO CRH 寄存器配置 CRH 寄存器控制着高8 位IO- -----*/
74 // 配置端口高8 位,即Pin8~Pin15
75 if (GPIO_InitStruct->GPIO_Pin > 0x00FF)
76 {
77 // // 先备份CRH 寄存器的值
78 tmpreg = GPIOx->CRH;
79
80 // 循环,从Pin8 开始配对,找出具体的Pin
81 for (pinpos = 0x00; pinpos < 0x08; pinpos++)
82 {
83 pos = (((uint32_t)0x01) << (pinpos + 0x08));
84
85 // pos 与输入参数GPIO_PIN 作位与运算
86 currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos);
87
88 //若currentpin=pos,则找到使用的引脚
89 if (currentpin == pos)
90 {
91 //pinpos 的值左移两位(乘以4),因为寄存器中4 个位配置一个引脚
92 pos = pinpos << 2;
93
94 //把控制这个引脚的4 个寄存器位清零,其它寄存器位不变
95 pinmask = ((uint32_t)0x0F) << pos;
96 tmpreg &= ~pinmask;
97
98 // 向寄存器写入将要配置的引脚的模式
99 tmpreg |= (currentmode << pos);
100
101 // 判断是否为下拉输入模式
102 if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
103 {
104 // 下拉输入模式,引脚默认置0,对BRR 寄存器写1 可对引脚置0
105 GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08));
106 }
107 // 判断是否为上拉输入模式
108 if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
109 {
110 // 上拉输入模式,引脚默认值为1,对BSRR 寄存器写1 可对引脚置1
111 GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08));
112 }
113 }
114 }
115 // 把前面处理后的暂存值写入到CRH 寄存器之中
116 GPIOx->CRH = tmpreg;
117 }
118 }
上一篇:STM32个人学习笔记-第二集(F4GPIO寄存器介绍)
下一篇:STM32F103 GPIO基本原理与寄存器
推荐阅读最新更新时间:2024-11-06 22:03