📄 stm32f10x_gpio.c
字号:
/**
******************************************************************************
* @文件 stm32f10x_gpio.c
* @作者 MCD 应用程序组
* @版本 V3.1.0
* @日期 06/19/2009
* @简述 这个文件 提供所有 GPIO 固件函数.
* @翻译 ANSON/sweet1985 Email:airanson110@126.com
* @日期 02/07/2009
******************************************************************************
* @复件
*
* 这个固件仅仅是提供给客户作为设计产品而编写程序的参考目的使客户节约时间。由于
* 客户使用本固件在开发产品编程上产生的结果意法半导体公司不承担任何直接的和间接
* 的责任,也不承担任何损害而引起的赔偿。
*
* <h2><center>&复制; 版权所有 2009 意法半导体公司</center></h2>
* 翻译版本仅供学习,如与英文原版有出入应以英文原版为准。
*/
/* 包含 ------------------------------------------------------------------*/
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
/* 自用类型 -----------------------------------------------------------*/
/* 自用定义 ------------------------------------------------------------*/
/* ------------ RCC registers bit address in the alias region ----------------*/
#define AFIO_OFFSET (AFIO_BASE - PERIPH_BASE)
/* --- EVENTCR Register -----*/
/* Alias word address of EVOE bit */
#define EVCR_OFFSET (AFIO_OFFSET + 0x00)
#define EVOE_BitNumber ((uint8_t)0x07)
#define EVCR_EVOE_BB (PERIPH_BB_BASE + (EVCR_OFFSET * 32) + (EVOE_BitNumber * 4))
/* --- MAPR Register ---*/
/* Alias word address of MII_RMII_SEL bit */
#define MAPR_OFFSET (AFIO_OFFSET + 0x04)
#define MII_RMII_SEL_BitNumber ((u8)0x17)
#define MAPR_MII_RMII_SEL_BB (PERIPH_BB_BASE + (MAPR_OFFSET * 32) + (MII_RMII_SEL_BitNumber * 4))
#define EVCR_PORTPINCONFIG_MASK ((uint16_t)0xFF80)
#define LSB_MASK ((uint16_t)0xFFFF)
#define DBGAFR_POSITION_MASK ((uint32_t)0x000F0000)
#define DBGAFR_SWJCFG_MASK ((uint32_t)0xF0FFFFFF)
#define DBGAFR_LOCATION_MASK ((uint32_t)0x00200000)
#define DBGAFR_NUMBITS_MASK ((uint32_t)0x00100000)
/* 自用宏 -------------------------------------------------------------*/
/* 自用变量 ---------------------------------------------------------*/
/* 自用函数原型 -----------------------------------------------*/
/* 自用函数 ---------------------------------------------------------*/
/**
* @简述 将GPIO部件的寄存器复位为默认值
* @参数 GPIOx:x可为A到G来选择特定的GPIO设备
* @返回 没有
*/
void GPIO_DeInit(GPIO_TypeDef* GPIOx)
{
/* 检查核对参数*/
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
if (GPIOx == GPIOA)
{
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, DISABLE);
}
else if (GPIOx == GPIOB)
{
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE);
}
else if (GPIOx == GPIOC)
{
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC, DISABLE);
}
else if (GPIOx == GPIOD)
{
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOD, ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOD, DISABLE);
}
else if (GPIOx == GPIOE)
{
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOE, ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOE, DISABLE);
}
else if (GPIOx == GPIOF)
{
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOF, ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOF, DISABLE);
}
else
{
if (GPIOx == GPIOG)
{
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOG, ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOG, DISABLE);
}
}
}
/**
* @简述 将备用功能(重映射,事件控制及EXTI配置)寄存器复位为默认值
* @参数 没有
* @返回 没有
*/
void GPIO_AFIODeInit(void)
{
RCC_APB2PeriphResetCmd(RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_AFIO, DISABLE);
}
/**
* @简述 按照GPIO_InitStruct(结构体)的特定参数初始化GPIO部件
* @参数 GPIOx:x可为A到G来选择特定的GPIO设备,
* GPIO_InitStruct: 指向GPIO_InitTypeDef结构的指针,它包含特定GPIO部件的配置信息.
* @返回 没有
*/
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
{
uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;
uint32_t tmpreg = 0x00, pinmask = 0x00;
/* 检查参数 */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));
/*---------------------------- GPIO 模式配置 --------------------------------*/
currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);
if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)
{
/* Check the parameters */
assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));
/* Output mode */
currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;
}
/*-------------------- GPIO CRL(端口控制寄存器低字节) 配置 -------------------*/
/* 配置低8位端口管脚 */
if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00)
{
tmpreg = GPIOx->CRL;
for (pinpos = 0x00; pinpos < 0x08; pinpos++)
{
pos = ((uint32_t)0x01) << pinpos;
/* 取得端口引脚的位置 */
currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
if (currentpin == pos)
{
pos = pinpos << 2;
/* 清空相应的低位控制寄存器 */
pinmask = ((uint32_t)0x0F) << pos;
tmpreg &= ~pinmask;
/* 写相应的模式配置位 */
tmpreg |= (currentmode << pos);
/* 复位相应的输出数据寄存器 (ODR) 位 */
if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
{
GPIOx->BRR = (((uint32_t)0x01) << pinpos);
}
else
{
/* 置位相应的输出数据寄存器 (ODR) 位 */
if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
{
GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
}
}
}
}
GPIOx->CRL = tmpreg;
}
/*-------------------- GPIO CRH(端口控制寄存器高字节) 配置 -------------------*/
/* 配置高8位端口引脚 */
if (GPIO_InitStruct->GPIO_Pin > 0x00FF)
{
tmpreg = GPIOx->CRH;
for (pinpos = 0x00; pinpos < 0x08; pinpos++)
{
pos = (((uint32_t)0x01) << (pinpos + 0x08));
/* 取得端口引脚的位置 */
currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos);
if (currentpin == pos)
{
pos = pinpos << 2;
/* 清空相应的低位控制寄存器 */
pinmask = ((uint32_t)0x0F) << pos;
tmpreg &= ~pinmask;
/* 写相应的模式配置位 */
tmpreg |= (currentmode << pos);
/* 复位相应的输出数据寄存器 (ODR) 位 */
if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
{
GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08));
}
/* 置位相应的输出数据寄存器 (ODR) 位 */
if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
{
GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08));
}
}
}
GPIOx->CRH = tmpreg;
}
}
/**
* @简述 把GPIO_InitStruct中的每一个参数按缺省值填入.
* @参数 GPIO_InitStruct : 指向GPIO_InitTypeDef结构,该结构将被初始化
* @返回 没有
*/
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct)
{
/* 复位GPIO初始化结构参数值 */
GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All;
GPIO_InitStruct->GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN_FLOATING;
}
/**
* @简述 读取指定端口管脚的输入.
* @参数 GPIOx: x可为A到G来选择特定的GPIO设备.
* GPIO_Pin: 被读取的引脚位.
* 这个参数GPIO_Pin_x可以选择0至15.
* @返回 指定端口管脚的输入值.
*/
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
uint8_t bitstatus = 0x00;
/* 检查参数 */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET)
{
bitstatus = (uint8_t)Bit_SET;
}
else
{
bitstatus = (uint8_t)Bit_RESET;
}
return bitstatus;
}
/**
* @简述 从特定的GPIO输入数据端口读取.
* @参数 GPIOx: x可为A到G来选择特定的GPIO设备.
* @返回 指定的 GPIO 端口管脚的输入值.
*/
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
{
/* 检查参数 */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
return ((uint16_t)GPIOx->IDR);
}
/**
* @简述 读取指定端口管脚的输出(位).
* @参数 GPIOx: x可为A到G来选择特定的GPIO设备.
* GPIO_Pin: 需要读取的端口位.
* 这个参数GPIO_Pin_x可以选择0至15.
* @返回 输出端口的输出值.
*/
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
uint8_t bitstatus = 0x00;
/* 检查参数 */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
if ((GPIOx->ODR & GPIO_Pin) != (uint32_t)Bit_RESET)
{
bitstatus = (uint8_t)Bit_SET;
}
else
{
bitstatus = (uint8_t)Bit_RESET;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -