一、STM8S单片机GPIO.C的组成
实际上,STM8S 系列单片机需要使用的stm8s_gpio.c由以下几个部分组成:
void GPIO_DeInit(GPIO_TypeDef* GPIOx)
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, GPIO_Mode_TypeDef GPIO_Mode)
void GPIO_Write(GPIO_TypeDef* GPIOx, uint8_t PortVal)
void GPIO_WriteHigh(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins)
void GPIO_WriteLow(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins)
void GPIO_WriteReverse(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins)
uint8_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
uint8_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
BitStatus GPIO_ReadInputPin(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin)
void GPIO_ExternalPullUpConfig(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, FunctionalState NewState)
二、各部分功能详解
1. void GPIO_DeInit(GPIO_TypeDef* GPIOx)
该函数的全文如下:
void GPIO_DeInit(GPIO_TypeDef* GPIOx)
{
GPIOx->ODR = GPIO_ODR_RESET_VALUE; /* Reset Output Data Register */
GPIOx->DDR = GPIO_DDR_RESET_VALUE; /* Reset Data Direction Register */
GPIOx->CR1 = GPIO_CR1_RESET_VALUE; /* Reset Control Register 1 */
GPIOx->CR2 = GPIO_CR2_RESET_VALUE; /* Reset Control Register 2 */
}
下面是函数的解释:
//定义一个名为GPIO_DeInit()的函数,该函数是对GPIO进行复位操作,例如对GPIOB/GPIOC等的操作。
void GPIO_DeInit(GPIO_TypeDef* GPIOx)
{
GPIOx->ODR = GPIO_ODR_RESET_VALUE; /* 复位输出数据寄存器 */
GPIOx->DDR = GPIO_DDR_RESET_VALUE; /* 复位数据方向寄存器*/
GPIOx->CR1 = GPIO_CR1_RESET_VALUE; /* 复位控制寄存器1 */
GPIOx->CR2 = GPIO_CR2_RESET_VALUE; /* 复位控制寄存器2 */
}
2. void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, GPIO_Mode_TypeDef GPIO_Mode)
该函数的全文如下:
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, GPIO_Mode_TypeDef GPIO_Mode)
{
/*----------------------*/
/* Check the parameters */
/*----------------------*/
assert_param(IS_GPIO_MODE_OK(GPIO_Mode));
assert_param(IS_GPIO_PIN_OK(GPIO_Pin));
/* Reset corresponding bit to GPIO_Pin in CR2 register */
GPIOx->CR2 &= (uint8_t)(~(GPIO_Pin));
/*-----------------------------*/
/* Input/Output mode selection */
/*-----------------------------*/
if ((((uint8_t)(GPIO_Mode)) & (uint8_t)0x80) != (uint8_t)0x00) /* Output mode */
{
if ((((uint8_t)(GPIO_Mode)) & (uint8_t)0x10) != (uint8_t)0x00) /* High level */
{
GPIOx->ODR |= (uint8_t)GPIO_Pin;
}
else /* Low level */
{
GPIOx->ODR &= (uint8_t)(~(GPIO_Pin));
}
/* Set Output mode */
GPIOx->DDR |= (uint8_t)GPIO_Pin;
}
else /* Input mode */
{
/* Set Input mode */
GPIOx->DDR &= (uint8_t)(~(GPIO_Pin));
}
/*------------------------------------------------------------------------*/
/* Pull-Up/Float (Input) or Push-Pull/Open-Drain (Output) modes selection */
/*------------------------------------------------------------------------*/
if ((((uint8_t)(GPIO_Mode)) & (uint8_t)0x40) != (uint8_t)0x00) /* Pull-Up or Push-Pull */
{
GPIOx->CR1 |= (uint8_t)GPIO_Pin;
}
else /* Float or Open-Drain */
{
GPIOx->CR1 &= (uint8_t)(~(GPIO_Pin));
}
/*-----------------------------------------------------*/
/* Interrupt (Input) or Slope (Output) modes selection */
/*-----------------------------------------------------*/
if ((((uint8_t)(GPIO_Mode)) & (uint8_t)0x20) != (uint8_t)0x00) /* Interrupt or Slow slope */
{
GPIOx->CR2 |= (uint8_t)GPIO_Pin;
}
else /* No external interrupt or No slope control */
{
GPIOx->CR2 &= (uint8_t)(~(GPIO_Pin));
}
}
下面是函数的解释:
//定义一个名为GPIO_Init()的函数,该函数用来指定单片机每个引脚的功能,该函数需要三个变量,分别是
//1.GPIO_TypeDef* GPIOx ——
//2.GPIO_Pin_TypeDef GPIO_Pin——
//3.GPIO_Mode_TypeDef GPIO_Mode——
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, GPIO_Mode_TypeDef GPIO_Mode)
{
/*----------------------*/
/* Check the parameters */
/*----------------------*/
assert_param(IS_GPIO_MODE_OK(GPIO_Mode));
assert_param(IS_GPIO_PIN_OK(GPIO_Pin));
/* Reset corresponding bit to GPIO_Pin in CR2 register */
GPIOx->CR2 &= (uint8_t)(~(GPIO_Pin));
/*-----------------------------*/
/* Input/Output mode selection */
/*-----------------------------*/
if ((((uint8_t)(GPIO_Mode)) & (uint8_t)0x80) != (uint8_t)0x00) /* Output mode */
{
if ((((uint8_t)(GPIO_Mode)) & (uint8_t)0x10) != (uint8_t)0x00) /* High level */
{
GPIOx->ODR |= (uint8_t)GPIO_Pin;
}
else /* Low level */
{
GPIOx->ODR &= (uint8_t)(~(GPIO_Pin));
}
/* Set Output mode */
GPIOx->DDR |= (uint8_t)GPIO_Pin;
}
else /* Input mode */
{
/* Set Input mode */
GPIOx->DDR &= (uint8_t)(~(GPIO_Pin));
}
/*------------------------------------------------------------------------*/
/* Pull-Up/Float (Input) or Push-Pull/Open-Drain (Output) modes selection */
/*------------------------------------------------------------------------*/
if ((((uint8_t)(GPIO_Mode)) & (uint8_t)0x40) != (uint8_t)0x00) /* Pull-Up or Push-Pull */
{
GPIOx->CR1 |= (uint8_t)GPIO_Pin;
}
else /* Float or Open-Drain */
{
GPIOx->CR1 &= (uint8_t)(~(GPIO_Pin));
}
/*-----------------------------------------------------*/
/* Interrupt (Input) or Slope (Output) modes selection */
/*-----------------------------------------------------*/
if ((((uint8_t)(GPIO_Mode)) & (uint8_t)0x20) != (uint8_t)0x00) /* Interrupt or Slow slope */
{
GPIOx->CR2 |= (uint8_t)GPIO_Pin;
}
else /* No external interrupt or No slope control */
{
GPIOx->CR2 &= (uint8_t)(~(GPIO_Pin));
}
}