在应用的时候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;
上一篇:STM8s窗口看门狗
下一篇:STM8S103F3--EEPROM
推荐阅读最新更新时间:2024-10-31 13:13
设计资源 培训 开发板 精华推荐
- TCK402G MOSFET驱动IC应用及电路
- 使用 Analog Devices 的 LT1317BIS8 的参考设计
- 激光测距,导线测长(相位式)演示板 硬件+软件 源码
- 基于混合信号控制处理器 (DSP) 的 ADZS-CM403F-EZLITE、ADSP-CM40x EZ-KIT Lite 评估系统
- RD-334,适用于 LCD 显示器的 40W、5V、13V AC 到 DC 多输出电源的参考设计
- TM4642IY 3.3V 输入到 1V 和 1.8V 各 4A 的典型应用电路,1V 排序 1.8V 使用 PGOOD1 启用 RUN2
- LTC3624IMSE-3.3 3.3V 输出电压、2A 同步降压稳压器、同步至 500kHz、强制连续模式的典型应用
- 使用 Microchip Technology 的 MIC2774H-XXBM5 的参考设计
- 使用 Diodes Incorporated 的 ZXCP330 的参考设计
- SPC584B-DISP:在eTQFP144中具有SPC58 4B线MCU的探索套件
- 有奖直播 | 迈来芯为您详解:半导体研发功能安全的实现与技术支持
- 免费申请| Microchip WBZ451 Curiosity
- 逛安富利新能源技术创新云会展 赢好礼!
- 免费下载|PathWave帮您迎接高速数字设计复杂性的挑战
- 联想栗子工业智能开发板抢先首发!免费申请进行时~另有12 月 22 日深圳技术沙龙邀您莅临!
- TE有奖活动|如何有效应对当下测试测量领域的挑战
- 德州仪器9月10日直播
- 1月22日下午14:00Mouser携手Maxim邀您观看有奖直播:深入浅出可穿戴健康监测
- 有奖直播|堵车路上听什么?新世代车载音频系统及软件定义汽车
- 一起哇:基于国产芯、便携烙铁系统IronOS(FreeRTOS)的智能烙铁