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

2019-07-21 05:30发布

我想使用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);

}



友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
8条回答
正点原子
1楼-- · 2019-07-21 09:42
帮顶.....
wall_e
2楼-- · 2019-07-21 11:55
回复【2楼】正点原子:
---------------------------------
深夜了,大部分都睡觉了。吃完泡面睡觉,明天起来再看看。
wall_e
3楼-- · 2019-07-21 14:26
那个好心人帮我看看timer5的初始化是否正确!我这么初始化为什么无法进入捕获中断,而只有更新中断呢!
无帝老三
4楼-- · 2019-07-21 17:21
 精彩回答 2  元偷偷看……
hanter
5楼-- · 2019-07-21 18:11
本帖最后由 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;

        }
}
带我足够强大
6楼-- · 2019-07-21 20:08
帮顶,关于RTC LSI的校准问题

一周热门 更多>