IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 使用外部时钟,通过TIM21_CH1对STM32L0XX内部的RC时钟(HSI/MSI等)进行校准 -> 正文阅读

[嵌入式]使用外部时钟,通过TIM21_CH1对STM32L0XX内部的RC时钟(HSI/MSI等)进行校准

前言:

在有些应用中,无法使用外部晶振来获取准确的时钟,不得已使用STM32内部的RC时钟。HSI以及MSI等。虽然这些时钟在出厂时,已经进行了校准。但是随着环境温度变化,RC时钟会有所改变,这在对时钟敏感的场合下,是不可接受的。幸好STM32提供了一个再校准的机会。利用外部精准时钟信号,对内部时钟进行校准。? ? ? ? ? ?

??????????????

官方文件:AN4631: How to calibrate an STM32L0xx internal RC oscillator

???????本文只展示对HSI的校准例程,MSI等方法相同。

正文:

一、使用TIM21_CH1通道

?以上为数据手册介绍的方法,本文使用4096Hz的标准信号,通过GPIO引脚输入TIM21_CH1中,内部TIM21会有输入4分频,因此TIM21需要测量的周期应为(1/1024Hz)?,使用HSI的16MHz主时钟进行测量,得到的理论精确数值应为16MHz*(1/1024Hz)=15625

下面为TIM21配置函数

/*函数名:TIM21_Configuration
 *函数描述: 定时器配置 TIM21用来对HSI进行修正
 *输入参数:无
 *输出结果:无
 *返回值:无
***************************************/	
void	  TIM21_Configuration(void)
{
	 LL_TIM_InitTypeDef LL_TIM21_InitStruct;
	 LL_TIM_IC_InitTypeDef LL_TIM21_IC_InitStruct;
	
     LL_TIM_DeInit (TIM21);
  
	 LL_TIM21_InitStruct .Autoreload =0xffff;
	 LL_TIM21_InitStruct .ClockDivision= LL_TIM_CLOCKDIVISION_DIV1;
	 LL_TIM21_InitStruct .CounterMode =LL_TIM_COUNTERMODE_UP;
	 LL_TIM21_InitStruct .Prescaler =0;
	
	
	 LL_TIM_Init(TIM21,&LL_TIM21_InitStruct);
	 
	 LL_TIM21_IC_InitStruct .ICActiveInput =LL_TIM_ACTIVEINPUT_DIRECTTI;//CH1连接IC1
	 LL_TIM21_IC_InitStruct .ICFilter =LL_TIM_IC_FILTER_FDIV1;//无滤波器
	 LL_TIM21_IC_InitStruct .ICPolarity =LL_TIM_IC_POLARITY_FALLING;//下降沿
	 LL_TIM21_IC_InitStruct .ICPrescaler =LL_TIM_ICPSC_DIV4;//输入4分频
	
	 LL_TIM_IC_Init(TIM21,LL_TIM_CHANNEL_CH1,&LL_TIM21_IC_InitStruct );
	 LL_TIM_EnableIT_TRIG(TIM21);
     LL_TIM_EnableIT_CC1(TIM21);
	  
	 NVIC_EnableIRQ(TIM21_IRQn);
}

其中LL_TIM21_InitStruct .Autoreload =0xffff;表示从0数到最大值,在中间进行捕获一段,即输入周期。因为已知输入的周期核算成数值在15625左右,所以不用再对TIM21进行分频。65536(0xffff)足矣。

二、配置TIM21_CH1对应的GPIO

由于使用的是TIM21_CH1功能,是复用功能,所以需要在GPIO配置中设置

LL_GPIO_SetAFPin_0_7 (GPIOA,LL_GPIO_PIN_2,LL_GPIO_AF_0 ); /*使用PA2的AF0功能:TIM21_CH1*/

三、校准程序

根据官方文件给的流程图,可以进行编写相应的程序。

/*************************************
 *函数名:HSI_Measurement
 *函数描述: 通过TIM21采集外部时钟信号
           参考AN4631中 《FIGURE 12. HSI16/MSI OSCILLATOR FREQUENCY MEASUREMENT FLOWCHART》
 *输入参数:无
 *输出结果:无
 *返回值:uint16_t
 
***************************************/	
uint16_t HSI_Measurement(void)
{
	uint8_t NUMER_OF_LOOPS;
	uint32_t Measure_Val=0;

	for(NUMER_OF_LOOPS=0;NUMER_OF_LOOPS<10;NUMER_OF_LOOPS++)//采集10次取平均值
	{
		Capture_state =CAPTURE_START;	  //标志位设置为START
		LL_TIM_SetCounter(TIM21,0);
        LL_TIM_EnableCounter(TIM21);
	    LL_TIM_EnableIT_CC1(TIM21);
		
		while(Capture_state!=CAPTURE_COMPLETED ); //等待捕获周期
		Measure_Val+= Capture_Period;      //捕获到的周期累加
   }
   LL_TIM_DisableIT_CC1(TIM21);
   LL_TIM_DisableCounter(TIM21);
   return (Measure_Val/10);           //取平均
}

/*************************************
 *函数名:CALC_HSI
 *函数描述: 根据外部时钟信号,对HSI进行微调
            进入单片机频率为4096Hz
            经过预分频1/4,使得IC1PS变为1024Hz
            而TIM21采集到的数据应该为【15625】16MHz*(1/1024Hz)=15625
 *输入参数:无
 *输出结果:无
 *返回值:无
 
***************************************/	
void CALC_HSI(void)
{
  uint16_t HSI_Measured_Val,HSI_Trimming_Val=0,HSI_Frequency_Error=0,HSI_Optimum_Error=20,HSI_Optimum_Trimming_Val=0xf;

	TIM21_CLK_ENABLE;//打开TIM21时钟	
	//RCC
	//GPIO
	TIM21_Configuration();

	for(HSI_Trimming_Val=0;HSI_Trimming_Val<32;HSI_Trimming_Val++)  //历遍32个trimming值,查找最佳值
	{
	 LL_RCC_HSI_SetCalibTrimming(HSI_Trimming_Val );    //设置当前trimming值
		
	 HSI_Measured_Val=HSI_Measurement();  //测量输入周期
     HSI[HSI_Trimming_Val]=HSI_Measured_Val;
	 if(HSI_Measured_Val>15625)  HSI_Frequency_Error = HSI_Measured_Val-15625; //计算误差值
	 else HSI_Frequency_Error = 15625-HSI_Measured_Val;
	
	 if(HSI_Frequency_Error <HSI_Optimum_Error ) //如果误差值比最佳值还好,那么取代最佳值
	 {
	   HSI_Optimum_Error =HSI_Frequency_Error ;
	   HSI_Optimum_Trimming_Val=HSI_Trimming_Val ; 
	 
	 }
	}
	
	LL_RCC_HSI_SetCalibTrimming(HSI_Optimum_Trimming_Val );
	RCC_Configuration();								  /*重新对RCC基本设置*/	
	
}

其中TIM21时钟打开的宏如下

#define TIM21_CLK_ENABLE                 LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM21)

另外

HSI[HSI_Trimming_Val]=HSI_Measured_Val;

这个数组是用来保存,在各个Trimming_Val下(HSI校准一共32个),测量到的周期值,后面会贴出来实测数据。这个值理想情况下应该就是前面计算得到的15625。也就是说,测到的数值越接近这个数,那么时钟此时越精准。我们的目的也就是找到这个最佳值。

中断程序

void TIM21_IRQHandler(void)
{
    if (Capture_state==CAPTURE_ONGOING)/*在使用TIM21测量频率时,用来表示当前状态,第一次进入中断为CAPTURE_START=0,第二次为CAPTURE_ONGOING=1*/
		{
			IC1ReadValue2= LL_TIM_IC_GetCaptureCH1(TIM21); //保存捕获的值RV2
			LL_TIM_DisableIT_CC1(TIM21);
			Capture_Period=IC1ReadValue2 -IC1ReadValue1 ;  //RV2-RV1差值为测量到的周期
			Capture_state=CAPTURE_COMPLETED ;

		}
		else 
    {
		    IC1ReadValue1= LL_TIM_IC_GetCaptureCH1(TIM21);//保存捕获的值RV1
			Capture_state=CAPTURE_ONGOING;
		}

}

四、经过上述程序的校准,我们如愿找到了最佳Trimming Value

这个校准值默认为16.??

?而我们找到的最佳值是15,在此参数下,HSI测量值为15622,最接近15625

结论:

从上面的数据可知,不同的校准值下,测量出的周期数值相差很大。虽说是微调,但是正所谓“差之毫厘谬以千里”,时钟的精准度是非常重要的。在温度变化较大的情况下,对HSI微调是必不可少的。

自此,完成了对HSI的校准

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-07-05 23:38:13  更:2022-07-05 23:38:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 15:03:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码