×
嵌入式 > 技术百科 > 详情

STM8s在利用库配置端口的小问题

发布时间:2024-05-19 发布时间:
|

在应用的时候PA2口需要设置成推挽输出,控制一个外部电源开关,端口初始化程序如下:

GPIO_DeInit(GPIOA);

GPIO_Init(GPIOA,GPIO_PIN_2,GPIO_MODE_OUT_PP_HIGH_SLOW);

在设置完后,端口会马上输出高电平,于是又加了一句:

GPIO_WriteLow(GPIOA,GPIO_PIN_2);

完成之后,发现被供电的器件在第一次上电的时候会被触发,而程序并没有在PA2输出高电平。这个被供电器件配有供电电池如果检测到端口有高电平就会启动,

用示波器观察PA2口,发现在上电瞬间会有一个短脉冲,看来就是这个问题。查看了一下库函数的源代码:

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, GPIO_Mode_TypeDef GPIO_Mode)
{

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));
}
}

从源码看来,是先把CR2清零了。然后写DDR方向寄存器1是输出,0是输入,然后是CR1。这个配合DDR可以确定4中方式:DDR为0的时候CR1为0的时候是:悬浮输入,CR1为1的时候是上拉输入,DDR为1的时候CR1为0的时候是:开漏输出,CR1为1的时候是:推挽输出。CR1在DDR为0的时候是外部中断的开关,1是开,0是关,DDR为1的时候是控制摆率的,如果需要比较陡峭的边沿可以设置成1。

不知道为什么会出现这个,硬件仿真发现CR1置位之后就会被拉高,后来我用寄存器方式设置有正常了,代码如下:

GPIOA->CR2 |= 0x04;
GPIOA->DDR |= 0x04;
GPIOA->CR1 |= 0x04;



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ADI 高精度低功耗精密放大器