1 /******************************************************************************************************************************************
2 * 文件名称: SWM320_gpio.c
3 * 功能说明: SWM320单片机的通用输入输出功能驱动库
4 * 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
5 * 注意事项:
6 * 版本日期: V1.1.0      2017年10月25日
7 * 升级记录:
8 *
9 *
10 *******************************************************************************************************************************************
11 * @attention
12 *
13 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
14 * REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
15 * FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
16 * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
17 * -ECTION WITH THEIR PRODUCTS.
18 *
19 * COPYRIGHT 2012 Synwit Technology
20 *******************************************************************************************************************************************/
21 #include "SWM320.h"
22 #include "SWM320_gpio.h"
23 
24 
25 /******************************************************************************************************************************************
26 * 函数名称: GPIO_Init()
27 * 功能说明: 引脚初始化,包含引脚方向、上拉电阻、下拉电阻
28 * 输    入: GPIO_TypeDef * GPIOx      指定GPIO端口,有效值包括GPIOA、GPIOB、GPIOC、GPIOM、GPION、GPIOP
29 *           uint32_t n             指定GPIO引脚,有效值包括PIN0、PIN1、PIN2、... ... PIN22、PIN23
30 *           uint32_t dir           引脚方向,0 输入        1 输出
31 *           uint32_t pull_up       上拉电阻,0 关闭上拉    1 开启上拉
32 *           uint32_t pull_down     下拉电阻,0 关闭下拉    1 开启下拉
33 * 输    出: 无
34 * 注意事项: GPIOA、GPIOC、GPIOM、GPIOP只有上拉,GPIOB、GPION只有下拉(PN0、PN1、PN2三个引脚有上拉没下拉)
35 ******************************************************************************************************************************************/
GPIO_Init(GPIO_TypeDef * GPIOx,uint32_t n,uint32_t dir,uint32_t pull_up,uint32_t pull_down)36 void GPIO_Init(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t dir, uint32_t pull_up, uint32_t pull_down)
37 {
38     switch((uint32_t)GPIOx)
39     {
40     case ((uint32_t)GPIOA):
41         SYS->CLKEN |= (0x01 << SYS_CLKEN_GPIOA_Pos);
42 
43         PORT_Init(PORTA, n, 0, 1);          //PORTA.PINn引脚配置为GPIO功能,数字输入开启
44         if(dir == 1)
45         {
46             GPIOA->DIR |= (0x01 << n);
47         }
48         else
49         {
50             GPIOA->DIR &= ~(0x01 << n);
51         }
52 
53         if(pull_up == 1)
54             PORT->PORTA_PULLU |= (0x01 << n);
55         else
56             PORT->PORTA_PULLU &= ~(0x01 << n);
57         break;
58 
59     case ((uint32_t)GPIOB):
60         SYS->CLKEN |= (0x01 << SYS_CLKEN_GPIOB_Pos);
61 
62         PORT_Init(PORTB, n, 0, 1);          //PORTB.PINn引脚配置为GPIO功能,数字输入开启
63         if(dir == 1)
64         {
65             GPIOB->DIR |= (0x01 << n);
66         }
67         else
68         {
69             GPIOB->DIR &= ~(0x01 << n);
70         }
71 
72         if(pull_down == 1)
73             PORT->PORTB_PULLD |= (0x01 << n);
74         else
75             PORT->PORTB_PULLD &= ~(0x01 << n);
76         break;
77 
78     case ((uint32_t)GPIOC):
79         SYS->CLKEN |= (0x01 << SYS_CLKEN_GPIOC_Pos);
80 
81         PORT_Init(PORTC, n, 0, 1);          //PORTC.PINn引脚配置为GPIO功能,数字输入开启
82         if(dir == 1)
83         {
84             GPIOC->DIR |= (0x01 << n);
85         }
86         else
87         {
88             GPIOC->DIR &= ~(0x01 << n);
89         }
90 
91         if(pull_up == 1)
92             PORT->PORTC_PULLU |= (0x01 << n);
93         else
94             PORT->PORTC_PULLU &= ~(0x01 << n);
95         break;
96 
97     case ((uint32_t)GPIOM):
98         SYS->CLKEN |= (0x01 << SYS_CLKEN_GPIOM_Pos);
99 
100         PORT_Init(PORTM, n, 0, 1);          //PORTM.PINn引脚配置为GPIO功能,数字输入开启
101         if(dir == 1)
102         {
103             GPIOM->DIR |= (0x01 << n);
104         }
105         else
106         {
107             GPIOM->DIR &= ~(0x01 << n);
108         }
109 
110         if(pull_up == 1)
111             PORT->PORTM_PULLU |= (0x01 << n);
112         else
113             PORT->PORTM_PULLU &= ~(0x01 << n);
114         break;
115 
116     case ((uint32_t)GPION):
117         SYS->CLKEN |= (0x01 << SYS_CLKEN_GPION_Pos);
118 
119         PORT_Init(PORTN, n, 0, 1);          //PORTN.PINn引脚配置为GPIO功能,数字输入开启
120         if(dir == 1)
121         {
122             GPION->DIR |= (0x01 << n);
123         }
124         else
125         {
126             GPION->DIR &= ~(0x01 << n);
127         }
128 
129         if(pull_down == 1)
130             PORT->PORTN_PULLD |= (0x01 << n);
131         else
132             PORT->PORTN_PULLD &= ~(0x01 << n);
133         break;
134 
135     case ((uint32_t)GPIOP):
136         SYS->CLKEN |= (0x01 << SYS_CLKEN_GPIOP_Pos);
137 
138         PORT_Init(PORTP, n, 0, 1);          //PORTP.PINn引脚配置为GPIO功能,数字输入开启
139         if(dir == 1)
140         {
141             GPIOP->DIR |= (0x01 << n);
142         }
143         else
144         {
145             GPIOP->DIR &= ~(0x01 << n);
146         }
147 
148         if(pull_up == 1)
149             PORT->PORTP_PULLU |= (0x01 << n);
150         else
151             PORT->PORTP_PULLU &= ~(0x01 << n);
152         break;
153     }
154 }
155 
156 /******************************************************************************************************************************************
157 * 函数名称: GPIO_SetBit()
158 * 功能说明: 将参数指定的引脚电平置高
159 * 输    入: GPIO_TypeDef * GPIOx      指定GPIO端口,有效值包括GPIOA、GPIOB、GPIOC、GPIOM、GPION、GPIOP
160 *           uint32_t n             指定GPIO引脚,有效值包括PIN0、PIN1、PIN2、... ... PIN22、PIN23
161 * 输    出: 无
162 * 注意事项: 无
163 ******************************************************************************************************************************************/
GPIO_SetBit(GPIO_TypeDef * GPIOx,uint32_t n)164 void GPIO_SetBit(GPIO_TypeDef * GPIOx, uint32_t n)
165 {
166     *((volatile uint32_t *)(0x42000000 + ((uint32_t)&GPIOx->DATA - 0x40000000)*32 + n*4)) = 1;
167 }
168 
169 /******************************************************************************************************************************************
170 * 函数名称: GPIO_ClrBit()
171 * 功能说明: 将参数指定的引脚电平置低
172 * 输    入: GPIO_TypeDef * GPIOx      指定GPIO端口,有效值包括GPIOA、GPIOB、GPIOC、GPIOM、GPION、GPIOP
173 *           uint32_t n             指定GPIO引脚,有效值包括PIN0、PIN1、PIN2、... ... PIN22、PIN23
174 * 输    出: 无
175 * 注意事项: 无
176 ******************************************************************************************************************************************/
GPIO_ClrBit(GPIO_TypeDef * GPIOx,uint32_t n)177 void GPIO_ClrBit(GPIO_TypeDef * GPIOx, uint32_t n)
178 {
179     *((volatile uint32_t *)(0x42000000 + ((uint32_t)&GPIOx->DATA - 0x40000000)*32 + n*4)) = 0;
180 }
181 
182 /******************************************************************************************************************************************
183 * 函数名称: GPIO_InvBit()
184 * 功能说明: 将参数指定的引脚电平反转
185 * 输    入: GPIO_TypeDef * GPIOx      指定GPIO端口,有效值包括GPIOA、GPIOB、GPIOC、GPIOM、GPION、GPIOP
186 *           uint32_t n             指定GPIO引脚,有效值包括PIN0、PIN1、PIN2、... ... PIN22、PIN23
187 * 输    出: 无
188 * 注意事项: 无
189 ******************************************************************************************************************************************/
GPIO_InvBit(GPIO_TypeDef * GPIOx,uint32_t n)190 void GPIO_InvBit(GPIO_TypeDef * GPIOx, uint32_t n)
191 {
192     *((volatile uint32_t *)(0x42000000 + ((uint32_t)&GPIOx->DATA - 0x40000000)*32 + n*4)) = 1 - *((volatile uint32_t *)(0x42000000 + ((uint32_t)&GPIOx->DATA - 0x40000000)*32 + n*4));
193 }
194 
195 /******************************************************************************************************************************************
196 * 函数名称: GPIO_GetBit()
197 * 功能说明: 读取参数指定的引脚的电平状态
198 * 输    入: GPIO_TypeDef * GPIOx      指定GPIO端口,有效值包括GPIOA、GPIOB、GPIOC、GPIOM、GPION、GPIOP
199 *           uint32_t n             指定GPIO引脚,有效值包括PIN0、PIN1、PIN2、... ... PIN22、PIN23
200 * 输    出: 参数指定的引脚的电平状态  0 低电平   1 高电平
201 * 注意事项: 无
202 ******************************************************************************************************************************************/
GPIO_GetBit(GPIO_TypeDef * GPIOx,uint32_t n)203 uint32_t GPIO_GetBit(GPIO_TypeDef * GPIOx, uint32_t n)
204 {
205     return ((GPIOx->DATA >> n) & 0x01);
206 }
207 
208 /******************************************************************************************************************************************
209 * 函数名称: GPIO_SetBits()
210 * 功能说明: 将参数指定的从n开始的w位连续引脚的电平置高
211 * 输    入: GPIO_TypeDef * GPIOx      指定GPIO端口,有效值包括GPIOA、GPIOB、GPIOC、GPIOM、GPION、GPIOP
212 *           uint32_t n             指定GPIO引脚,有效值包括PIN0、PIN1、PIN2、... ... PIN22、PIN23
213 *           uint32_t w             指定要将引脚电平置高的引脚的个数
214 * 输    出: 无
215 * 注意事项: 无
216 ******************************************************************************************************************************************/
GPIO_SetBits(GPIO_TypeDef * GPIOx,uint32_t n,uint32_t w)217 void GPIO_SetBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w)
218 {
219     uint32_t bits;
220 
221     bits = 0xFFFFFF >> (24 - w);
222 
223     GPIOx->DATA |= (bits << n);
224 }
225 
226 /******************************************************************************************************************************************
227 * 函数名称: GPIO_ClrBits()
228 * 功能说明: 将参数指定的从n开始的w位连续引脚的电平置低
229 * 输    入: GPIO_TypeDef * GPIOx      指定GPIO端口,有效值包括GPIOA、GPIOB、GPIOC、GPIOM、GPION、GPIOP
230 *           uint32_t n             指定GPIO引脚,有效值包括PIN0、PIN1、PIN2、... ... PIN22、PIN23
231 *           uint32_t w             指定要将引脚电平置低的引脚的个数
232 * 输    出: 无
233 * 注意事项: 无
234 ******************************************************************************************************************************************/
GPIO_ClrBits(GPIO_TypeDef * GPIOx,uint32_t n,uint32_t w)235 void GPIO_ClrBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w)
236 {
237     uint32_t bits;
238 
239     bits = 0xFFFFFF >> (24 - w);
240 
241     GPIOx->DATA &= ~(bits << n);
242 }
243 
244 /******************************************************************************************************************************************
245 * 函数名称: GPIO_InvBits()
246 * 功能说明: 将参数指定的从n开始的w位连续引脚的电平反转
247 * 输    入: GPIO_TypeDef * GPIOx      指定GPIO端口,有效值包括GPIOA、GPIOB、GPIOC、GPIOM、GPION、GPIOP
248 *           uint32_t n             指定GPIO引脚,有效值包括PIN0、PIN1、PIN2、... ... PIN22、PIN23
249 *           uint32_t w             指定要将引脚电平反转的引脚的个数
250 * 输    出: 无
251 * 注意事项: 无
252 ******************************************************************************************************************************************/
GPIO_InvBits(GPIO_TypeDef * GPIOx,uint32_t n,uint32_t w)253 void GPIO_InvBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w)
254 {
255     uint32_t bits;
256 
257     bits = 0xFFFFFF >> (24 - w);
258 
259     GPIOx->DATA ^= (bits << n);
260 }
261 
262 /******************************************************************************************************************************************
263 * 函数名称: GPIO_GetBits()
264 * 功能说明: 读取参数指定的从n开始的w位连续引脚的电平状态
265 * 输    入: GPIO_TypeDef * GPIOx      指定GPIO端口,有效值包括GPIOA、GPIOB、GPIOC、GPIOM、GPION、GPIOP
266 *           uint32_t n             指定GPIO引脚,有效值包括PIN0、PIN1、PIN2、... ... PIN22、PIN23
267 *           uint32_t w             指定要将引脚电平置高的引脚的个数
268 * 输    出: 参数指定的从n开始的w位连续引脚的电平状态 0 低电平   1 高电平
269 *           返回值的第0位表示引脚n的电平状态、返回值的第1位表示引脚n+1的电平状态... ...返回值的第w位表示引脚n+w的电平状态
270 * 注意事项: 无
271 ******************************************************************************************************************************************/
GPIO_GetBits(GPIO_TypeDef * GPIOx,uint32_t n,uint32_t w)272 uint32_t GPIO_GetBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w)
273 {
274     uint32_t bits;
275 
276     bits = 0xFFFFFF >> (24 - w);
277 
278     return ((GPIOx->DATA >> n) & bits);
279 }
280 
281 /******************************************************************************************************************************************
282 * 函数名称: GPIO_AtomicSetBits()
283 * 功能说明: 将参数指定的从n开始的w位连续引脚的电平置高,确保引脚”读-改-写“操作的原子性(不被中断ISR打断)
284 * 输    入: GPIO_TypeDef * GPIOx      指定GPIO端口,有效值包括GPIOA、GPIOB、GPIOC、GPIOD
285 *           uint32_t n             指定GPIO引脚,有效值包括PIN0、PIN1、PIN2、... ... PIN14、PIN15
286 *           uint32_t w      指定要将引脚电平置高的引脚的个数
287 * 输    出: 无
288 * 注意事项: 当GPIOx的16个引脚中,有些在主循环中操作,有些在中断ISR中操作时,GPIOx的引脚必须都用GPIO_Atomic类型函数操作
289 ******************************************************************************************************************************************/
GPIO_AtomicSetBits(GPIO_TypeDef * GPIOx,uint32_t n,uint32_t w)290 void GPIO_AtomicSetBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w)
291 {
292     uint32_t bits;
293 
294     bits = 0xFFFFFF >> (24 - w);
295 
296     __disable_irq();
297     GPIOx->DATA |= (bits << n);
298     __enable_irq();
299 }
300 
301 /******************************************************************************************************************************************
302 * 函数名称: GPIO_AtomicClrBits()
303 * 功能说明: 将参数指定的从n开始的w位连续引脚的电平置低,确保引脚”读-改-写“操作的原子性(不被中断ISR打断)
304 * 输    入: GPIO_TypeDef * GPIOx      指定GPIO端口,有效值包括GPIOA、GPIOB、GPIOC、GPIOD
305 *           uint32_t n             指定GPIO引脚,有效值包括PIN0、PIN1、PIN2、... ... PIN14、PIN15
306 *           uint32_t w             指定要将引脚电平置低的引脚的个数
307 * 输    出: 无
308 * 注意事项: 当GPIOx的16个引脚中,有些在主循环中操作,有些在中断ISR中操作时,GPIOx的引脚必须都用GPIO_Atomic类型函数操作
309 ******************************************************************************************************************************************/
GPIO_AtomicClrBits(GPIO_TypeDef * GPIOx,uint32_t n,uint32_t w)310 void GPIO_AtomicClrBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w)
311 {
312     uint32_t bits;
313 
314     bits = 0xFFFFFF >> (24 - w);
315 
316     __disable_irq();
317     GPIOx->DATA &= ~(bits << n);
318     __enable_irq();
319 }
320 
321 /******************************************************************************************************************************************
322 * 函数名称: GPIO_AtomicInvBits()
323 * 功能说明: 将参数指定的从n开始的w位连续引脚的电平反转,确保引脚”读-改-写“操作的原子性(不被中断ISR打断)
324 * 输    入: GPIO_TypeDef * GPIOx      指定GPIO端口,有效值包括GPIOA、GPIOB、GPIOC、GPIOD
325 *           uint32_t n             指定GPIO引脚,有效值包括PIN0、PIN1、PIN2、... ... PIN14、PIN15
326 *           uint32_t w             指定要将引脚电平反转的引脚的个数
327 * 输    出: 无
328 * 注意事项: 当GPIOx的16个引脚中,有些在主循环中操作,有些在中断ISR中操作时,GPIOx的引脚必须都用GPIO_Atomic类型函数操作
329 ******************************************************************************************************************************************/
GPIO_AtomicInvBits(GPIO_TypeDef * GPIOx,uint32_t n,uint32_t w)330 void GPIO_AtomicInvBits(GPIO_TypeDef * GPIOx, uint32_t n, uint32_t w)
331 {
332     uint32_t bits;
333 
334     bits = 0xFFFFFF >> (24 - w);
335 
336     __disable_irq();
337     GPIOx->DATA ^= (bits << n);
338     __enable_irq();
339 }
340