产品设计方案:在HSE故障时切换至HSI,2分频后给PLL再16倍频(手册说可以到64M),在LSE故障时优先切换至HSE时钟,HSE故障时切换至LSI,暂时只考虑故障后复位重启,未修改CSS中断代码,可实际代码怎么也调不通(有晶振时可以),始终卡在“等待RTC寄存器同步”位置,大伙帮我看看问题在哪:(硬件:先加上HSE和LSE晶振,后都取消) 代码如下: void RCC_Configuration(void) { //复位RCC外部设备寄存器到默认值 RCC_DeInit(); //打开外部高速晶振 RCC_HSEConfig(RCC_HSE_ON); //等待外部高速时钟准备好 HSEStartUpStatus = RCC_WaitForHSEStartUp(); if(HSEStartUpStatus == SUCCESS) //外部高速时钟已经准别好 { FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //开启FLASH的预取功能 FLASH_SetLatency(FLASH_Latency_2); //FLASH延迟2个周期 RCC_HCLKConfig(RCC_SYSCLK_Div1); //配置AHB(HCLK)时钟=SYSCLK RCC_PCLK2Config(RCC_HCLK_Div1); //配置APB2(PCLK2)钟=AHB时钟 RCC_PCLK1Config(RCC_HCLK_Div2); //配置APB1(PCLK1)钟=AHB 1/2时钟 RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //配置PLL时钟 == 外部高速晶体时钟*9 PLLCLK = 8MHz * 9 = 72 MHz RCC_PLLCmd(ENABLE); //使能PLL时钟 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){} //等待PLL时钟就绪 //配置系统时钟 = PLL时钟 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //检查PLL时钟是否作为系统时钟 while(RCC_GetSYSCLKSource() != 0x08){}// 0x00:HSI 作为系统时钟,0x04:HSE作为系统时钟,0x08:PLL作为系统时钟 } else //如果外部时钟不成功 { RCC_HSICmd(ENABLE); // while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET){ } FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); FLASH_SetLatency(FLASH_Latency_2); RCC_HCLKConfig(RCC_SYSCLK_Div1); //AHB时钟为系统时钟SYSCLK RCC_PCLK2Config(RCC_HCLK_Div1); //APB1时钟为HCLK/2,其中HCLK为AHB时钟 RCC_PCLK1Config(RCC_HCLK_Div2); //APB2时钟为HCLK RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_16); //设置 PLL 时钟源=HSI2分频,及倍频系数16倍 RCC_PLLCmd(ENABLE);//如果PLL被用于系统时钟,那么它不能被失能 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){} //等待指定的 RCC 标志位设置成功 等待PLL初始化成功 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //设置系统时钟(SYSCLK) 设置PLL为系统时钟源 while(RCC_GetSYSCLKSource() != 0x08){ } //等待PLL成功用作于系统时钟的时钟源 } RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG | RCC_APB2Periph_AFIO, ENABLE); } //如果外部低速晶振失效,则使用外部HSE128分频后作为RTC时钟,如果也没有HSE,则使用LSI时钟,不能使用HSI作为RTC时钟 u8 RTC_Init(void) { u8 temp=0; RCC->APB1ENR |= 3<<27; //使能电源时钟和备份时钟 PWR->CR |=1<<8; //取消备份区写保护 RCC->BDCR|=1<<15; //RTC时钟使能,取消该句无影响 //检查是否首次配置RTC if(BKP->DR1!=0x5AA5)//第一次配置 { RCC->BDCR|=1<<16; //备份区域软复位 RCC->BDCR&=~(1<<16); //备份区域软复位结束 RCC->BDCR|=1<<0; //开启外部低速振荡器 while((!(RCC->BDCR&0X02))&&temp<250)//等待外部时钟就绪 { temp++; msDelay(10); }; if(temp>=250) //LSE故障,切换至HSE或LSI { RCC->BDCR &= ~(1<<0); //关闭LSE if( RCC->CR & 0x20000) //如果HSE准备就绪 { RCC->BDCR |=3<<8; //HSE/128作为RTC时钟 8M/128=62.5Khz } else { RCC->BDCR &= ~(3<<8); //RTC时钟选择清零 RCC->BDCR |= 2<<8; //使用LSI作为RTC时钟,40KHz } } else { RCC->BDCR &= ~(3<<8); //RTC时钟选择清零 RCC->BDCR|=1<<8; //LSE作为RTC时钟 } RCC->BDCR|=1<<15; //RTC时钟使能 while(!(RTC->CRL&(1<<5))){}; //等待RTC寄存器操作完成 while(!(RTC->CRL&(1<<3))); //等待RTC寄存器同步,总是死在此处 RTC->CRL|=1<<4; //允许配置 if(temp>=250) { if( RCC->CR & 0x20000) //如果HSE正常工作,则使用HSE/128作为RTC时钟 { RTC->PRLH=0X0000; RTC->PRLL=62500-1; //HSE/128=62500,取62500-1 } else //使用LSI作为RTC时钟 { RTC->PRLH=0X0000; RTC->PRLL=40000-1; //时钟周期设置,内部LSI时钟偏差很大,需要经常校准,理论值:40K } } else { RTC->PRLH=0X0000; RTC->PRLL=32768-1; //时钟周期设置(有待观察,看是否跑慢了?)理论值:32767 } RTC_Set(2016,8,8,8,8,8); //设置时间 RTC->CRL&=~(1<<4); //配置更新 while(!(RTC->CRL&(1<<5))); //等待RTC寄存器操作完成 BKP->DR1=0x5AA5; } else//系统继续计时 { //while(!(RTC->CRL&(1<<3)));//等待RTC寄存器同步 } // RTC->CRH |=0X01; //允许秒中断 // while(!(RTC->CRL&(1<<5))); //等待RTC寄存器操作完成 // RTC_NVIC_Config();//RTC中断分组设置,使用秒中断时需要 RTC_Get();//更新时间,填写calendar结构体初始值 return 0; //ok } 调试读取的寄存器值如下: RCC->CR = 0x03015083 RCC->CFGR = 0x0038840A RCC->BDCR = 0x00008201 RCC->APB1ENR = 0x38064036 RCC->CIR = 0x00000000 RTC->CRL = 0x0020 BKP->DR1 = 0x0000 |
使用SysTick_Config函数写延时函数,但显示SysTick_Config无法被调用,怎么解决呢?
头文件找不到
stm32进入stop模式被莫名其妙唤醒(应该是systick)但是无法被WKUP引脚唤醒。
软件为keil5,头文件未找到
通过FATFS文件系统读写SD卡创建文件可以了,但加入MSC,一直显示一个没有格式化的U盘盘符,也不能格式化,这是什么问题导致的
stm32f103汇编求助
cubemx 生成的freertos代码 在keil ac6下不能编译,有什么解决的方法吗
报错Could not determine GDB version using command: arm-none-eabi-gdb --version
stm32f107vct6配RTL8201例程
STM32F103VGT6 能代替 STM32F103VFT6 吗?
领导要求如此实现,因为原来产品多次出现过仅外部晶振故障导致产品不能使用的问题,所以要寻求软件解决方案,可怎么都实现不了呢,理论上应该可以啊,难道从来没人这么做过吗?
涉及到以下函数:
RTC_LSE_Check、RTC_LSI_Check、RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE)、RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
请问STC的单片机如何选择控制和切换内外时钟呢?
整篇也没有找到内部和外部时钟是如何选择切换的!!!
总不能内部时钟和外部时钟一起同时工作吧?
比如,我已经外接(焊接)了晶振,这时内部和外部时钟是如何选择切换的!!!
我在网上找遍了,没找到!