对GPIO进行未绑定,好处:加快对位操作的速度。
1、位绑定公式(操作不同地址区域的位,用下面不同的公式)
2、下面以GPIOA端口的配置进行讲解:
3、对少量位进行绑定的程序例举:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185/************************************************************************************************** * 硬件平台:STM32F103VC * 学习重点:GPIOx的位绑定 * 实现功能:对于GPIOA端口的第八位输出 跟随 高八位的输入 **************************************************************************************************/ /*============================================================================= * 位绑定公式: * 1、SRAM区域 :0X2200 0000 ----0X200F FFFF * Aliasaddr = 0X22000000 + ( A -0X20000000 )*32 + n*4 * 2、片上外设区域 :0X4200 0000 ----0X400F FFFF * Aliasaddr = 0X42000000 + ( A -0X40000000 )*32 + n*4 * 参数解释: * Aliasaddr : 设置“端口GPIOx的第n位”的寄存器_相应位的实际地址 * A : 端口GPIOx的基地址(GPIOx_BASE) + 相应寄存器的偏移地址 * n : 配置的是相应寄存器的第n位 * 寄存器的偏移地址 :CRL CRH IDR ODR BSRR BRR LCKR * 00H 04H 08H 0CH 10H 14H 18H =============================================================================*/ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x_lib.h" //包含了所有的头文件 它是唯一一个用户需要包括在自己应用中的文件,起到应用和库之间界面的作用。 #include "stm32f10x_map.h" /*----------------------------------------------------------------------------------------------------------- *将GPIOA的第3位作为输出引脚,寄存器ODR的偏移地址为0X0C * A = GPIOA_BASE + 0X0C = (APB2PERIPH_BASE + 0X0800) + 0X0C = ((PERIPR_BASE + 0X1000) + 0X0800) + 0X0C * = ((0X40000000 + 0X1000) + 0X0800) + 0X0C = 0X4001080C * n = 3 (设置寄存器ODR的第3位) * 将GPIOA的第11位作为输入引脚,寄存器IDR的偏移地址为0X08 * A = GPIOA_BASE + 0X08 = (APB2PERIPH_BASE + 0X0800) + 0X08 = ((PERIPR_BASE + 0X1000) + 0X0800) + 0X08 * = ((0X40000000 + 0X1000) + 0X0800) + 0X08 = 0X40010808 * n = 11 (设置寄存器IDR的第11位) ------------------------------------------------------------------------------------------------------------*/ u32 *PAO0 = (u32 *)(0X42000000 + (0X4001080C - 0X40000000)*32 + 0*4) ; u32 *PAO1 = (u32 *)(0X42000000 + (0X4001080C - 0X40000000)*32 + 1*4) ; u32 *PAO2 = (u32 *)(0X42000000 + (0X4001080C - 0X40000000)*32 + 2*4) ; u32 *PAO3 = (u32 *)(0X42000000 + (0X4001080C - 0X40000000)*32 + 3*4) ; u32 *PAO4 = (u32 *)(0X42000000 + (0X4001080C - 0X40000000)*32 + 4*4) ; u32 *PAO5 = (u32 *)(0X42000000 + (0X4001080C - 0X40000000)*32 + 5*4) ; u32 *PAO6 = (u32 *)(0X42000000 + (0X4001080C - 0X40000000)*32 + 6*4) ; u32 *PAO7 = (u32 *)(0X42000000 + (0X4001080C - 0X40000000)*32 + 7*4) ; u32 *PAI8 = (u32 *)(0X42000000 + (0X40010808 - 0X40000000)*32 + 8*4) ; u32 *PAI9 = (u32 *)(0X42000000 + (0X40010808 - 0X40000000)*32 + 9*4) ; u32 *PAI10 = (u32 *)(0X42000000 + (0X40010808 - 0X40000000)*32 + 10*4) ; u32 *PAI11 = (u32 *)(0X42000000 + (0X40010808 - 0X40000000)*32 + 11*4) ; u32 *PAI12 = (u32 *)(0X42000000 + (0X40010808 - 0X40000000)*32 + 12*4) ; u32 *PAI13 = (u32 *)(0X42000000 + (0X40010808 - 0X40000000)*32 + 13*4) ; u32 *PAI14 = (u32 *)(0X42000000 + (0X40010808 - 0X40000000)*32 + 14*4) ; u32 *PAI15 = (u32 *)(0X42000000 + (0X40010808 - 0X40000000)*32 + 15*4) ; /* Private functions -----------------------------------------------------------------------------*/ /************************************************************************************************** * Function Name : main * Description : 从GPIOA.8-.16输入一个电平信号,GPIOA.0-.7口分别将对应引脚输入的电平信号输出 * Input : None * Output : None * Return : None ****************************************************************************************************/ int main(void) { /*--------控制STM32引脚GPIOA.0 GPIOA.1推挽输出高电平--------*/ //1、设置GPIOA的引脚的工作模式,即配置寄存器GPIOA_CRL 、 GPIOA_CRH //GPIOA.0-.7推挽输出,速度50MHZ , GPIOA.8-.16浮空输入 GPIOA->CRL = 0x33333333 ; // CNF0 = 00 MODE0 = 11 GPIOA->CRH = 0x44444444 ; // CNF0 = 01 MODE0 = 00 //2、配置寄存器GPIOA_ODR、GPIOA_IDR ,实现GPIOA.0输出 跟随 GPIOA.8的输入 while(1) { /*----------------------第0位----------------------*/ if( *PAI8 == 1) //寄存器GPIOA->IDR的第8位为1,表示从在GPIOA.8口输入了高电平 { *PAO0 = 1 ; //对寄存器GPIOA->ODR的第0位置一 } else { *PAO0 = 0 ; //对寄存器GPIOA->ODR的第0位清零 } /*----------------------第1位----------------------*/ if( *PAI9 == 1) //寄存器GPIOA->IDR的第9位为1,表示从在GPIOA.9口输入了高电平 { *PAO1 = 1 ; //对寄存器GPIOA->ODR的第1位置一 } else { *PAO1 = 0 ; //对寄存器GPIOA->ODR的第1位清零 } /*----------------------第2位----------------------*/ if( *PAI10 == 1) //寄存器GPIOA->IDR的第10位为1,表示从在GPIOA.10口输入了高电平 { *PAO2 = 1 ; //对寄存器GPIOA->ODR的第2位置一 } else { *PAO2 = 0 ; //对寄存器GPIOA->ODR的第2位清零 } /*----------------------第3位----------------------*/ if( *PAI11 == 1) //寄存器GPIOA->IDR的第11位为1,表示从在GPIOA.11口输入了高电平 { *PAO3 = 1 ; //对寄存器GPIOA->ODR的第3位置一 } else { *PAO3 = 0 ; //对寄存器GPIOA->ODR的第3位清零 } /*----------------------第4位----------------------*/ if( *PAI12 == 1) //寄存器GPIOA->IDR的第12位为1,表示从在GPIOA.12口输入了高电平 { *PAO4 = 1 ; //对寄存器GPIOA->ODR的第4位置一 } else { *PAO4 = 0 ; //对寄存器GPIOA->ODR的第4位清零 } /*----------------------第5位----------------------*/ if( *PAI13 == 1) //寄存器GPIOA->IDR的第13位为1,表示从在GPIOA.13口输入了高电平 { *PAO5 = 1 ; //对寄存器GPIOA->ODR的第5位置一 } else { *PAO5 = 0 ; //对寄存器GPIOA->ODR的第5位清零 } /*----------------------第6位----------------------*/ if( *PAI14 == 1) //寄存器GPIOA->IDR的第14位为1,表示从在GPIOA.14口输入了高电平 { *PAO6 = 1 ; //对寄存器GPIOA->ODR的第6位置一 } else { *PAO6 = 0 ; //对寄存器GPIOA->ODR的第6位清零 } /*----------------------第7位----------------------*/ if( *PAI15 == 1) //寄存器GPIOA->IDR的第15位为1,表示从在GPIOA.15口输入了高电平 { *PAO7 = 1 ; //对寄存器GPIOA->ODR的第7位置一 } else { *PAO7 = 0 ; //对寄存器GPIOA->ODR的第7位清零 } } return 1 ; }
4、利用宏定义函数对大量的位进行位绑定的步骤:
5、对大量的位进行位绑定的程序例举:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214/************************************************************************************************** * 硬件平台:STM32F103VC * 学习重点:GPIOx的位绑定 * 实现功能:对于GPIOA端口的第八位输出 跟随 高八位的输入 **************************************************************************************************/ /*============================================================================= * 位绑定公式: * 1、SRAM区域 :0X2200 0000 ----0X200F FFFF * Aliasaddr = 0X22000000 + ( A -0X20000000 )*32 + n*4 * 2、片上外设区域 :0X4200 0000 ----0X400F FFFF * Aliasaddr = 0X42000000 + ( A -0X40000000 )*32 + n*4 * 参数解释: * Aliasaddr : 设置“端口GPIOx的第n位”的寄存器_相应位的实际地址 * A : 端口GPIOx的基地址(GPIOx_BASE) + 相应寄存器的偏移地址 * n : 配置的是相应寄存器的第n位 * 寄存器的偏移地址 :CRL CRH IDR ODR BSRR BRR LCKR * 00H 04H 08H 0CH 10H 14H 18H =============================================================================*/ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x_lib.h" //包含了所有的头文件 它是唯一一个用户需要包括在自己应用中的文件,起到应用和库之间界面的作用。 #include "stm32f10x_map.h" ///*----------------------------------------------------------------------------------------------------------- // *将GPIOA的第3位作为输出引脚,寄存器ODR的偏移地址为0X0C // * A = GPIOA_BASE + 0X0C = (APB2PERIPH_BASE + 0X0800) + 0X0C = ((PERIPR_BASE + 0X1000) + 0X0800) + 0X0C // * = ((0X40000000 + 0X1000) + 0X0800) + 0X0C = 0X4001080C // * n = 3 (设置寄存器ODR的第3位) // * 将GPIOA的第11位作为输入引脚,寄存器IDR的偏移地址为0X08 // * A = GPIOA_BASE + 0X08 = (APB2PERIPH_BASE + 0X0800) + 0X08 = ((PERIPR_BASE + 0X1000) + 0X0800) + 0X08 // * = ((0X40000000 + 0X1000) + 0X0800) + 0X08 = 0X40010808 // * n = 11 (设置寄存器IDR的第11位) // ------------------------------------------------------------------------------------------------------------*/ // //u32 *PAO0 = (u32 *)(0X42000000 + (0X4001080C - 0X40000000)*32 + 0*4) ; //u32 *PAO1 = (u32 *)(0X42000000 + (0X4001080C - 0X40000000)*32 + 1*4) ; //u32 *PAO2 = (u32 *)(0X42000000 + (0X4001080C - 0X40000000)*32 + 2*4) ; //u32 *PAO3 = (u32 *)(0X42000000 + (0X4001080C - 0X40000000)*32 + 3*4) ; //u32 *PAO4 = (u32 *)(0X42000000 + (0X4001080C - 0X40000000)*32 + 4*4) ; //u32 *PAO5 = (u32 *)(0X42000000 + (0X4001080C - 0X40000000)*32 + 5*4) ; //u32 *PAO6 = (u32 *)(0X42000000 + (0X4001080C - 0X40000000)*32 + 6*4) ; //u32 *PAO7 = (u32 *)(0X42000000 + (0X4001080C - 0X40000000)*32 + 7*4) ; // //u32 *PAI8 = (u32 *)(0X42000000 + (0X40010808 - 0X40000000)*32 + 8*4) ; //u32 *PAI9 = (u32 *)(0X42000000 + (0X40010808 - 0X40000000)*32 + 9*4) ; //u32 *PAI10 = (u32 *)(0X42000000 + (0X40010808 - 0X40000000)*32 + 10*4) ; //u32 *PAI11 = (u32 *)(0X42000000 + (0X40010808 - 0X40000000)*32 + 11*4) ; //u32 *PAI12 = (u32 *)(0X42000000 + (0X40010808 - 0X40000000)*32 + 12*4) ; //u32 *PAI13 = (u32 *)(0X42000000 + (0X40010808 - 0X40000000)*32 + 13*4) ; //u32 *PAI14 = (u32 *)(0X42000000 + (0X40010808 - 0X40000000)*32 + 14*4) ; //u32 *PAI15 = (u32 *)(0X42000000 + (0X40010808 - 0X40000000)*32 + 15*4) ; /******************************快速位绑定**********************************************************/ /*----------------1、宏定义要操作的寄存器地址---------------------------------------------*/ #define GPIOA_ODR (GPIOA_BASE + 0X0C) #define GPIOA_IDR (GPIOA_BASE + 0X08) #define GPIOB_ODR (GPIOB_BASE + 0X0C) #define GPIOB_IDR (GPIOB_BASE + 0X08) #define GPIOC_ODR (GPIOC_BASE + 0X0C) #define GPIOC_IDR (GPIOC_BASE + 0X08) #define GPIOD_ODR (GPIOD_BASE + 0X0C) #define GPIOD_IDR (GPIOD_BASE + 0X08) #define GPIOE_ODR (GPIOE_BASE + 0X0C) #define GPIOE_IDR (GPIOE_BASE + 0X08) /*----------------2、获取端口GPIOx(A-E)的对应寄存器的某一操作位的位地址-------------------*/ // #define BitBand(Addr , BitNum) *( (volatile unsigned long *)(Addr & 0xf0000000) + 0x2000000 + ((Addr&0xfffff)*32) + (BitNum*4) ) // 因为 左移、右移 语句的执行速度比乘除法语句的运动速度快,所以将上述语句改成如下方式 #define BitBand(Addr , BitNum) *( (volatile unsigned long *)( (Addr & 0xf0000000) + 0x2000000 + ((Addr&0xfffff)<<5) + (BitNum<<2) ) ) /*----------------3、宏定义函数,对固定的位绑定 进行功能封装------------------------------*/ #define PAout(n) BitBand(GPIOA_ODR , n) #define PAin(n) BitBand(GPIOA_IDR , n) #define PBout(n) BitBand(GPIOB_ODR , n) #define PBin(n) BitBand(GPIOB_IDR , n) #define PCout(n) BitBand(GPIOC_ODR , n) #define PCin(n) BitBand(GPIOC_IDR , n) #define PDout(n) BitBand(GPIOD_ODR , n) #define PDin(n) BitBand(GPIOD_IDR , n) #define PEout(n) BitBand(GPIOE_ODR , n) #define PEin(n) BitBand(GPIOE_IDR , n) /* Private functions -----------------------------------------------------------------------------*/ /************************************************************************************************** * Function Name : main * Description : 从GPIOA.8-.16输入一个电平信号,GPIOA.0-.7口分别将对应引脚输入的电平信号输出 * Input : None * Output : None * Return : None ****************************************************************************************************/ int main(void) { /*--------控制STM32引脚GPIOA.0 GPIOA.1推挽输出高电平--------*/ //1、设置GPIOA的引脚的工作模式,即配置寄存器GPIOA_CRL 、 GPIOA_CRH //GPIOA.0-.7推挽输出,速度50MHZ , GPIOA.8-.16浮空输入 GPIOA->CRL = 0x33333333 ; // CNF0 = 00 MODE0 = 11 GPIOA->CRH = 0x44444444 ; // CNF0 = 01 MODE0 = 00 //2、配置寄存器GPIOA_ODR、GPIOA_IDR ,实现GPIOA.0输出 跟随 GPIOA.8的输入 while(1) { /*----------------------第0位----------------------*/ if( PAin(8) == 1) //寄存器GPIOA->IDR的第8位为1,表示从在GPIOA.8口输入了高电平 { PAout(0) = 1 ; //对寄存器GPIOA->ODR的第0位置一 } else { PAout(0) = 0 ; //对寄存器GPIOA->ODR的第0位清零 } /*----------------------第1位----------------------*/ if( PAin(9) == 1) //寄存器GPIOA->IDR的第9位为1,表示从在GPIOA.9口输入了高电平 { PAout(1) = 1 ; //对寄存器GPIOA->ODR的第1位置一 } else { PAout(1) = 0 ; //对寄存器GPIOA->ODR的第1位清零 } /*----------------------第2位----------------------*/ if( PAin(10) == 1) //寄存器GPIOA->IDR的第10位为1,表示从在GPIOA.10口输入了高电平 { PAout(2) = 1 ; //对寄存器GPIOA->ODR的第2位置一 } else { PAout(2) = 0 ; //对寄存器GPIOA->ODR的第2位清零 } /*----------------------第3位----------------------*/ if( PAin(11) == 1) //寄存器GPIOA->IDR的第11位为1,表示从在GPIOA.11口输入了高电平 { PAout(3) = 1 ; //对寄存器GPIOA->ODR的第3位置一 } else { PAout(3) = 0 ; //对寄存器GPIOA->ODR的第3位清零 } /*----------------------第4位----------------------*/ if( PAin(12) == 1) //寄存器GPIOA->IDR的第12位为1,表示从在GPIOA.12口输入了高电平 { PAout(4) = 1 ; //对寄存器GPIOA->ODR的第4位置一 } else { PAout(4) = 0 ; //对寄存器GPIOA->ODR的第4位清零 } /*----------------------第5位----------------------*/ if( PAin(13) == 1) //寄存器GPIOA->IDR的第13位为1,表示从在GPIOA.13口输入了高电平 { PAout(5) = 1 ; //对寄存器GPIOA->ODR的第5位置一 } else { PAout(5) = 0 ; //对寄存器GPIOA->ODR的第5位清零 } /*----------------------第6位----------------------*/ if( PAin(14) == 1) //寄存器GPIOA->IDR的第14位为1,表示从在GPIOA.14口输入了高电平 { PAout(6) = 1 ; //对寄存器GPIOA->ODR的第6位置一 } else { PAout(6) = 0 ; //对寄存器GPIOA->ODR的第6位清零 } /*----------------------第7位----------------------*/ if( PAin(15) == 1) //寄存器GPIOA->IDR的第15位为1,表示从在GPIOA.15口输入了高电平 { PAout(7) = 1 ; //对寄存器GPIOA->ODR的第7位置一 } else { PAout(7) = 0 ; //对寄存器GPIOA->ODR的第7位清零 } } return 1 ; }
最后
以上就是诚心鞋垫最近收集整理的关于STM32F10x GPIO配置 之 位绑定对GPIO进行未绑定,好处:加快对位操作的速度。的全部内容,更多相关STM32F10x内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复