打印
[应用相关]

STM32的晶振脚(OSCIN和OSCOUT)当成普通IO来使用

[复制链接]
610|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

一不小心把模拟IIC放到OSCIN和OSCOUT脚上了,现在来说一下怎么把这两个脚当成普通IO来使用:

        首先这两个引脚是时钟引脚,于是我们先要把外部时钟关闭,改用内部的时钟。


使用特权

评论回复
沙发
xiaoqizi|  楼主 | 2021-6-4 14:40 | 只看该作者
也就是把HSE关闭,使用HSI。stm32的时钟初始化函数如下:

/** @addtogroup STM32F10x_System_Private_Functions
  * @{
  */
void RCC_Configuration(void)
{
    RCC_DeInit();                                           //重设RCC寄存器为缺省值
    RCC_HSICmd(ENABLE);                                           //使能HSI内部高速晶振
    while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);            //等待使能成功

    //配置AHB时钟频率与系统时钟频率一致   
    RCC_HCLKConfig(RCC_SYSCLK_Div1);  

    //配置APB1低速时钟频率为AHB时钟频率的1/2                            
    RCC_PCLK1Config(RCC_HCLK_Div2);  

    //配置APB2高速时钟频率与AHB时钟频率一致                     
    RCC_PCLK2Config(RCC_HCLK_Div1);  
                            
    //配置ADC时钟频率为APB2时钟频率的1/4
    RCC_ADCCLKConfig(RCC_PCLK2_Div4);                     

    //将内部晶振时钟2分频后作为PLL时钟源,倍频系数为10(即系统时钟为40MHz)  8MHz/2*10=40MHz
    RCC_PLLConfig(RCC_PLLSource_HSI_Div2,RCC_PLLMul_10);   

    //使能PLL(如果PLL被用于系统时钟,那么它不能被失能)               
    RCC_PLLCmd(ENABLE);     

    //等待指定的RCC标志位设置成功,等待PLL初始化成功
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);  
       
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);              //以PLL时钟作为系统时钟源

    //0x00:HSI作为系统时钟
    //0x04:HSE作为系统时钟
    //0x08:PLL作为系统时钟
    while(RCC_GetSYSCLKSource() != 0x08);                                  //等待PLL时钟成功作为系统时钟源
}

/**
  * @brief  Setup the microcontroller system
  *         Initialize the Embedded Flash Interface, the PLL and update the
  *         SystemCoreClock variable.
  * @NOTE   This function should be used only after reset.
  * @param  None
  * @retval None
  */
void SystemInit (void)
{
  /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
  /* Set HSION bit */
  RCC->CR |= (uint32_t)0x00000001;

  /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CL
  RCC->CFGR &= (uint32_t)0xF8FF0000;
#else
  RCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */   

  /* Reset HSEON, CSSON and PLLON bits */
  RCC->CR &= (uint32_t)0xFEF6FFFF;

  /* Reset HSEBYP bit */
  RCC->CR &= (uint32_t)0xFFFBFFFF;

  /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
  RCC->CFGR &= (uint32_t)0xFF80FFFF;

#ifdef STM32F10X_CL
  /* Reset PLL2ON and PLL3ON bits */
  RCC->CR &= (uint32_t)0xEBFFFFFF;

  /* Disable all interrupts and clear pending bits  */
  RCC->CIR = 0x00FF0000;

  /* Reset CFGR2 register */
  RCC->CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
  /* Disable all interrupts and clear pending bits  */
  RCC->CIR = 0x009F0000;

  /* Reset CFGR2 register */
  RCC->CFGR2 = 0x00000000;      
#else
  /* Disable all interrupts and clear pending bits  */
  RCC->CIR = 0x009F0000;
#endif /* STM32F10X_CL */

#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
  #ifdef DATA_IN_ExtSRAM
    SystemInit_ExtMemCtl();
  #endif /* DATA_IN_ExtSRAM */
#endif

  /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
  /* Configure the Flash Latency cycles and enable prefetch buffer */
//  SetSysClock();
  RCC_Configuration();       
#ifdef VECT_TAB_SRAM
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
}


使用特权

评论回复
板凳
xiaoqizi|  楼主 | 2021-6-4 14:41 | 只看该作者
  SystemInit函数是在进main函数之前就调用了的,因此进入main函数后就不用再调用了,直接编写自己的程序即可。

void ALL_GPIO_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
       
        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE );
        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_AFIO, ENABLE );       
       
        GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//关闭jtag,使能SWD,可以用SWD模式调试
        GPIO_PinRemapConfig(GPIO_Remap_PD01, ENABLE);           //OSCIN和OSCOUT重映射为PD0、PD1
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;  //端口配置
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;       //推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       //50Mhz速度
        GPIO_Init(GPIOC, &GPIO_InitStructure);       
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;    //端口配置
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;       //推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       //50Mhz速度
        GPIO_Init(GPIOD, &GPIO_InitStructure);
       
        GPIO_SetBits(GPIOD,GPIO_Pin_0);//SDA输出高       
        GPIO_SetBits(GPIOD,GPIO_Pin_1);//SCL输出高               
}

int main()  //进入main函数前,时钟就初始化完成了,此时主频是40M
{       
        ALL_GPIO_Init();
        while(1)
        {
                               
        }
}


使用特权

评论回复
地板
xiaoqizi|  楼主 | 2021-6-4 14:41 | 只看该作者


由手册可知,OSCIN和OSCOUT作为PD0和PD1是它的重映射功能,因此打开该功能即可。

        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_AFIO, ENABLE );       
        GPIO_PinRemapConfig(GPIO_Remap_PD01, ENABLE);           //OSCIN和OSCOUT重映射为PD0、PD1


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

95

主题

4129

帖子

3

粉丝