STM32 特殊引脚作为普通IO口使用的问题

开发平台:Keil5
硬件平台:STM32F103RCT6

之前有有弄过的东西,因为没有记录忘记了,所以还得重新找资料寻找答案,所以说,博客还是得写啊,不然搞过的东西,又得重新再来一遍。(-_-||)

1. OSC_IN 引脚接有源晶振,OSC_OUT 做普通IO口使用

原理图如下:
在这里插入图片描述在这里插入图片描述
原理图中,我们将 OSC_IN 引脚接了有源晶振,OSC_OUT引脚需要采集DS18B20数据(也就是做普通IO使用),那么我们需要如何配置:

在手册中,由讲解到:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意,再这里提到过,“当不适用主振荡器HSE时,PD0 和PD1 可以映射到 OSC_IN 和 OSC_OUT引脚 ”。

再这里,由于我们使用了外部高速时钟 HSE,所以,是不是不能使用了呢?再这里我也有疑问。

在这里我们既要引出 STM32 时钟部分

HSE时钟

高速外部时钟信号(HSE)由以下两种时钟源产生:

  • HSE外部晶体/陶瓷谐振器 (也就是我们所说的无源晶振)
  • HSE用户外部时钟 (有源晶振)

为了减少时钟输出的失真和缩短启动稳定时间,晶体/陶瓷谐振器和负载电容器必须尽可能地靠
近振荡器引脚。负载电容值必须根据所选择的振荡器来调整。

在这里插入图片描述

外部时钟源(HSE旁路)

在这个模式里,必须提供外部时钟。它的频率最高可达50MHz。用户可通过设置在时钟控制寄存器中的 HSEBYP 和 HSEON 位选择这一模式。外部时钟信号(50%占空比的方波、正弦波或三角波)必须连到SOC_IN引脚,同时保证OSC_OUT引脚悬空。 见图12。

外部晶体/陶瓷谐振器(HSE晶体)

3~25Mz外部振荡器可为系统提供非常精确的主时钟。相关的硬件配置可参考图12,进一步信息可参考数据手册的电气特性部分。
在时钟控制寄存器(RCC_CR)中的 HSERDY 位用来指示 高速外部振荡器是否稳定。在启动时,直到这一位被硬件置’1’,时钟才被释放出来。如果在时钟中断寄存器(RCC_CIR)中允许产生中断,将会产生相应中断。HSE晶体可以通过设置时钟控制寄存器(RCC_CR)中的 HSEON 位被启动和关闭。


PS: 在这里,我们使用了有源晶振,但是之前我没有细看原理图,我的代码里面还是按照无源晶振配置,发现也是可以运行的,于是去寻找二者的配置区别,发现:有源晶振的配置就是多了一句:

  /* Enable HSE and HSE BYPASS */
  RCC->CR |= ((uint32_t)RCC_CR_HSEON | RCC_CR_HSEBYP);

无源晶振则是:

  /* Enable HSE */
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);

于是,我在想,是不是有源晶振,上电了就输出50%占空比的正弦波,然后系统直接检测到了时钟就绪标志(RCC_CR_HSERDY)系统运行。

RCC_CR_HSEBYP : 定义是 HSE晶振被外部时钟旁路。指将芯片内部的用于外部晶体起振和功率驱动等的部分电路和XTAL_OUT引脚断开。这时使用的外部时钟是:有源时钟或者其他STM32提供的CCO输出等时钟信号,直接单线从XTAL_IN输入。

这样,就算是外部接了晶体(无源晶振)也不会起振。
在这里插入图片描述

因此:使用无源晶振的时钟代码配置适用于有源晶振,但是,有源晶振的代码配置就不适用了无源晶振,OCS_OUT引脚断开而导致晶振不起振。

回归上面的问题:将OSC_OUT 配置为普通IO口使用:
上面说 “当不使用主振荡器HSE时,PD0 和PD1 可以映射到 OSC_IN 和 OSC_OUT引脚”,那么我们使用了有源晶振,只接了OSC_IN,还有一个脚 OSC_OUT 还能不能使用呢?

实践是检验真理的唯一标准。

配置如下:

/**
  * @brief  初始化DS18B20的IO口 DQ 同时检测DS的存在
  * @param  Despition
  * @retval NULL
  */
void bsp_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);//使能PORTA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//使能复用功能
    
    //使能重映射
    GPIO_PinRemapConfig(GPIO_Remap_PD01,ENABLE);
	//引脚配置
    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
	
    GPIO_ResetBits(GPIOD,GPIO_Pin_1);    //输出0
}  

发现是可以输出的。。

这就很尴尬。。

不过,再STM32H7的一份手册里,我看到了这样一句话:
在这里插入图片描述
也就是说,其实刚刚说的, OSC_IN使用外部时钟模式,第二个引脚充当一个IO引脚是可以的。

2. STM32F1系列PB3,PB4,PA13,PA14,PA15用作普通IO口的特殊配置

这里这个老哥比我写的详细,可参考:
STM32F1系列PB3,PB4,PA13,PA14,PA15用作普通IO口的特殊配置

STM32 HAL库是一种高级硬件抽象层,它为STM32微控制器提供了一种统一的方式来管理设备和外设,包括GPIO(通用输入输出)。如果你想要使用普通的GPIO模拟PWM(脉冲宽度调制)输出,你可以按照以下步骤操作: 1. 首先,你需要初始化GPIO:通过`HAL_GPIO_Init()`函数配置GPIO引脚为AF(Alternate Function)模式,通常用于PWM输出。设置GPIO的速度到最高,例如50MHz。 ```c HAL_GPIO_Init(GPIOx, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_x; // 替换为你的GPIO引脚 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; // Push-Pull输出 GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; HAL_GPIO_EXTI_Config(GPIOx, EXTI_PIN_x, EXTI_Mode_ Falling, EXTI_Trigger_RISING, EXTI_LineState_SET); // 初始化EXTI(外部中断) ``` 2. 然后,启用GPIO的PWM功能并配置时钟分频器:例如,可以使用`HAL_TIM_PWM_Init()`初始化TIMx Timer用于生成PWM信号,设置适当的通道和周期。 ```c HAL_TIM_PWM_Init(&htim1); HAL_TIM_PWM_MspInit(&htim1); htim1.Instance = TIMx; // 替换为你使用的TIM实例 htim1.Init.Pulsewidth一方面 = PWM_PrescalerValue * (uint16_t)CyclePeriod; // 计算周期 htim1.Init.Mode = TIM_MODE_ONE Pulse Width Modulation; htim1.Init.OutputState = TIM_OutputState_Enable; ``` 3. 启动定时器:`HAL_TIM_Base_Start_IT(&htim1);` 开始PWM计时,并设置中断服务程序处理输出波形。 4. 当需要改变PWM频率或占空比时,修改相关的定时参数即可。 注意:实际使用时,可能需要添加相应的中断服务程序(ISRs),以便在PWM周期内控制输出占空比。此外,还要确保所选的GPIO引脚支持PWM功能并且你的STM32芯片的固件库支持这一特性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值