打印
[MM32硬件]

mm32f0010 mm32f0020 测LSI时钟频率

[复制链接]
509|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
可以看到这个种方法可以精确到小数点后一位

  本方法主要思想为用正常的定时器测得准确的时间,然后用准确的时间,根据看门狗定时器时间计算公式反推频率
代码写的太乱仅写出主要代码

正常的定时器中断设置 由于我采用2分频来计算时间所有一个周期肯定是不够的所以我们把每次定时器溢出的次数加起来

使用特权

评论回复
沙发
狗啃模拟|  楼主 | 2022-10-18 23:48 | 只看该作者
void TIM3_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
    {
        time_num++;//定时器溢出计数
    }
    TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
}


void WWDG_IWDG_IRQHandler(void)
{
   
// static u16 iii;


//    printf("%d ",IWDG->SR);

TIM_Cmd(TIM3,0);//关掉定时器读取定时器的值
   
        if(IWDG->SR){//由于我配置的这个看门狗中断会连续进入两次所以给了个判断实际用处不大可以删除

//    if(++iii==2)
//    {
        iii = 0;
    LSI_HZ= TIM3->CNT;//读取定时器的值
    TIM3->CNT= 0;    //定时器数据清0
    TIM_Cmd(TIM3,1);
        
//    }
}
               
    EXTI_ClearFlag(EXTI_Line17);
    IWDG_WriteAccessCmd(0x5555);
    IWDG->CR |= 0x02;
    IWDG->KR = 0xAAAA;
//   

}

使用特权

评论回复
板凳
狗啃模拟|  楼主 | 2022-10-18 23:49 | 只看该作者
看门狗配置
void Iwdg_Irq_ON(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;

    EXTI_DeInit();
    EXTI_StructInit(&EXTI_InitStructure);
    EXTI_InitStructure.EXTI_Line = EXTI_Line17 ;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt ;
    EXTI_InitStructure.EXTI_Trigger =   EXTI_Trigger_Rising_Falling  ;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
    EXTI_ClearITPendingBit(EXTI_Line17);

    NVIC_InitStructure.NVIC_IRQChannel = WWDG_IWDG_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}


#define IWDG_FLAG_IVU               ((uint16_t)0x0004)
void IVU_CheckStatus(void)
{
    while(1) {
        if(IWDG_GetFlagStatus(IWDG_FLAG_IVU) == RESET) {
            break;
        }
    }
}
void Write_Iwdg_ON(u16 IWDG_Prescaler, u16 Reload)
{
    RCC_LSICmd(ENABLE);
    while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);

    PVU_CheckStatus();
    IWDG_WriteAccessCmd(0x5555);
    IWDG_SetPrescaler(IWDG_Prescaler);

    RVU_CheckStatus();
    IWDG_WriteAccessCmd(0x5555);
    IWDG_SetReload(Reload & 0xfff);

    IVU_CheckStatus();
    IWDG_WriteAccessCmd(0x5555);
    IWDG->IGEN = 0x50;

    IWDG_ReloadCounter();
    IWDG_WriteAccessCmd(0x5555);
    IWDG->CR |= 1;
    IWDG_Enable();
}

void PWR_STOP_iwdg_Init(void)
{
    u16 i;
    RCC_APB1PeriphClockCmd(RCC_APB1ENR_PWREN, ENABLE);
//    deleyNop(10000);
//    for(i = 0; i < 10; i++) {
//        LED1_TOGGLE();
//        deleyNop(1000);
//    }
    Iwdg_Irq_ON();
    Write_Iwdg_ON(IWDG_Prescaler_4, 2500+0x50);//计算方法 time = Reload/40000*IWDG_Prescaler   s


}


void my_delay_ms(u16 m)    ;
u16 low=0;


int main(void)
{GPIO_InitTypeDef  GPIO_InitStructure;
    u16 time_y;
        float HZ;
    //mco输出LSI时钟 PA7迎角
      RCC_LSICmd(ENABLE);
    while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1ENR_SYSCFG, ENABLE);

    GPIO_StructInit(&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed =  GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_PinAFConfig( GPIOA, GPIO_PinSource7, GPIO_AF_3);
    RCC_MCOConfig(RCC_MCO_LSI);
   
    USART1_Init();

    time_x = 2; //用处不大可以删除
    time_y = time_x; //用处不大可以删除
    PWR_STOP_iwdg_Init();

    TIM3_Int_Init(0xffff-1,time_y-1);//2分频
    printf("ok");
   
    while(1)
    {
        if(LSI_HZ!=low )//频率不同时重新计算 实际用处不大可以删除
        {
            HZ=48000000/time_y;//得到分频频率
            HZ=(LSI_HZ+0xffff*time_num)/HZ; //实际时间
            time_num = 0;//定时器溢出计数
            printf("%f",HZ);  //输出实际时间      
            HZ =4/HZ*2500;  //得到实际时间按看门狗公式反推频率
            printf("   %.2f\r\n",HZ);//输出实际频率
        low =LSI_HZ ;
        }
//    printf("%d ",aaa);
//        my_delay_ms(1000);
    }
}

使用特权

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

本版积分规则

63

主题

803

帖子

2

粉丝