OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 16946|回复: 8

测量stm32内部的LSI时钟的准确频率,为RTC提供时钟,大家帮我看看哪里出错了

[复制链接]

4

主题

8

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2015-3-10
在线时间
0 小时
发表于 2015-3-10 22:35:52 | 显示全部楼层 |阅读模式
5金钱
我想使用stm32f103ze内部LSI时钟作为RTC的计数时钟,但是根据文档上说的,LSI的频率只在40k左右,但是这个不是准确的频率,如果作为RTC时钟,需要进行校正。我调试时只能够监测到更新中断,而那个捕获中断却没有监测到。大家帮我看看是那个地方出了问题。
我的步骤是:1、使能LSI时钟,并等待其稳定。
                     2、初始化TIMER5。
                     3、计算LSI频率。

我使用的程序模板是战舰开发板例程  实验10输入捕获实验
主要代码如下
使能LSI时钟:
/* Enable the Internal Low Speed oscillator */
RCC_LSICmd(ENABLE);
while ((RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)&&temp<250)
{
temp++;
//delay_ms(10);
}
if(temp>=250)return 1;

初始化TIMER5:

void TIM5_Cap_Init(u16 arr,u16 psc)
{  
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM5_ICInitStructure; 

NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);

/* LSI connected to TIM5 Channel4 input capture for calibration */
GPIO_PinRemapConfig(GPIO_Remap_TIM5CH4_LSI, ENABLE);

TIM_TimeBaseStructure.TIM_Period = arr; 
TIM_TimeBaseStructure.TIM_Prescaler =psc; 
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); 


TIM5_ICInitStructure.TIM_Channel = TIM_Channel_4;
TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM5_ICInitStructure.TIM_ICFilter = 0x0;
TIM_ICInit(TIM5, &TIM5_ICInitStructure);

TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC4,ENABLE ); 


NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;  
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
NVIC_Init(&NVIC_InitStructure);  


TIM_Cmd(TIM5, ENABLE);  

}

中断处理函数
#define CAPTURE_FINISHED 0x80000000
#define CAPTURE_FIRST_RISING 0x40000000
#define CAPTURE_SECOND_RISING 0x20000000

u32  TIM5CH4_CAPTURE_STA = 0; 
u16 TIM5CH4_CAPTURE_VAL = 0;


void TIM5_IRQHandler(void)

//u16 temp;
//temp = TIM_GetFlagStatus(TIM5, TIM_FLAG_Update);

  if((TIM5CH4_CAPTURE_STA & CAPTURE_FINISHED)==0)
{  
if (TIM_GetFlagStatus(TIM5, TIM_FLAG_Update) == SET) 
{    
if(TIM5CH4_CAPTURE_STA & CAPTURE_FIRST_RISING)
{
if((TIM5CH4_CAPTURE_STA&0X3FFFFFFF)==0X3FFFFFFF)
{
TIM5CH4_CAPTURE_STA|=CAPTURE_FINISHED;
TIM5CH4_CAPTURE_VAL=0XFFFF;

}
else 
TIM5CH4_CAPTURE_STA++;
}  
}

//temp = TIM_GetFlagStatus(TIM5, TIM_FLAG_CC4OF);

// if(TIM_GetFlagStatus(TIM5, TIM_FLAG_CC4OF)==SET) 
// {
// TIM5CH4_CAPTURE_STA|=CAPTURE_FINISHED; 
// TIM5CH4_CAPTURE_VAL=TIM_GetCapture4(TIM5);
//
// TIM_Cmd(TIM5, DISABLE);
//
// }

//temp = TIM_GetFlagStatus(TIM5, TIM_FLAG_CC4);
//temp = TIM_GetITStatus(TIM5, TIM_IT_CC4);
//if ( (TIM_GetITStatus(TIM5, TIM_IT_CC4) == SET) && ((TIM5CH4_CAPTURE_STA & CAPTURE_FIRST_RISING)!=CAPTURE_FIRST_RISING))
if (TIM_GetITStatus(TIM5, TIM_IT_CC4) == SET)
{
TIM5CH4_CAPTURE_STA=0; //????
TIM5CH4_CAPTURE_VAL=0;
TIM_SetCounter(TIM5,0);
TIM5CH4_CAPTURE_STA|=CAPTURE_FIRST_RISING;
}
  }

    TIM_ClearITPendingBit(TIM5, TIM_IT_Update|TIM_IT_CC4);

/* Clear the TIM5 Capture Compare 1 flag */
//TIM_ClearFlag(TIM5, TIM_FLAG_Update);

}



实验10 输入捕获实验.zip

2.49 MB, 下载次数: 313

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-3-10 23:10:47 | 显示全部楼层
回复

使用道具 举报

4

主题

8

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2015-3-10
在线时间
0 小时
 楼主| 发表于 2015-3-10 23:21:36 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
深夜了,大部分都睡觉了。吃完泡面睡觉,明天起来再看看。
回复

使用道具 举报

4

主题

8

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2015-3-10
在线时间
0 小时
 楼主| 发表于 2015-3-11 21:48:13 | 显示全部楼层
那个好心人帮我看看timer5的初始化是否正确!我这么初始化为什么无法进入捕获中断,而只有更新中断呢!
回复

使用道具 举报

20

主题

143

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2015-8-28
在线时间
108 小时
发表于 2015-9-22 18:12:05 | 显示全部楼层
回复【3楼】wall_e:
---------------------------------
lz大神,我用了LSI做内部时钟,保证在stop模式下也能走,但是测出来时间误差太大,怎么进行校准啊??
看库函数有这个ErrorStatus RTC_SmoothCalibConfig(uint32_t RTC_SmoothCalibPeriod,
                                  uint32_t RTC_SmoothCalibPlusPulses,
                                  uint32_t RTC_SmouthCalibMinusPulsesValue)
但是好像是为32.768Hz准备的吗?不知道怎么设置这个参数啊?指点下吧
回复

使用道具 举报

2

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2014-4-15
在线时间
6 小时
发表于 2016-11-10 16:48:24 | 显示全部楼层
本帖最后由 hanter 于 2016-11-10 16:49 编辑

我借鉴别人的程序,调试可以使用,发出来参考一下:它是以72M的频率进行捕捉的,TIM_GetCapture4(TIM5)得到的值乘以周期就是当前波形的周期了
void TIM5_ConfigForLSI(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;
        TIM_ICInitTypeDef  TIM_ICInitStructure;

        /* Enable TIM5 clocks */
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);


        /* Deinitialize the TIM5 peripheral registers to their default reset values */
        TIM_DeInit(TIM5);

        /* Configure TIM5 prescaler */
        TIM_PrescalerConfig(TIM5, 0, TIM_PSCReloadMode_Immediate);//预分频系数:72M/(0+1) ,预分频值即刻装入

        /* Connect internally the TM5_CH4 Input Capture to the LSI clock output */
        GPIO_PinRemapConfig(GPIO_Remap_TIM5CH4_LSI, ENABLE);

        /* TIM5 configuration: Input Capture mode ---------------------
        The LSI oscillator is connected to TIM5 CH4
        The Rising edge is used as active edge,
        The TIM5 CCR4 is used to compute the frequency value
        ------------------------------------------------------------ */
        TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
        TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
        TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
        TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV8;
        TIM_ICInitStructure.TIM_ICFilter = 0;
        TIM_ICInit(TIM5, &TIM_ICInitStructure);

        /* Enable the TIM5 Interrupt */
        NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);

        /* TIM10 Counter Enable */
        TIM_Cmd(TIM5, ENABLE);

        /* Reset the flags */
        TIM5->SR = 0;

        /* Enable the CC4 Interrupt Request */
        TIM_ITConfig(TIM5, TIM_IT_CC4, ENABLE);
}


void TIM5_IRQHandler(void)
{
        if (TIM_GetITStatus(TIM5, TIM_IT_CC4) != RESET)
        {
                TIM_ClearITPendingBit(TIM5, TIM_IT_CC4);//清除中断
                TIM_SetCounter(TIM5, 0);

                //RunSetData.MCompile_Date = TIM_GetCapture4(TIM5);
                RunSetData.MCompile_Date = (72000000 * 8) / TIM_GetCapture4(TIM5);

                RunLed2;

        }
}
回复

使用道具 举报

74

主题

334

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
436
金钱
436
注册时间
2015-5-28
在线时间
144 小时
发表于 2017-1-25 13:28:13 | 显示全部楼层
帮顶,关于RTC LSI的校准问题
最近爱上了stm32
回复

使用道具 举报

8

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2015-9-22
在线时间
8 小时
发表于 2017-3-27 11:24:03 | 显示全部楼层
请问搞定了吗,是什么原因呢。
回复

使用道具 举报

9

主题

123

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1694
金钱
1694
注册时间
2014-7-8
在线时间
183 小时
发表于 2019-1-28 00:13:56 | 显示全部楼层
看起来,要参考你的程序了,要仔细研究一下了!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-23 14:58

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表