OpenEdv-开源电子网

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

F103定时器频率自动计算分频系数

[复制链接]

1

主题

3

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
251
金钱
251
注册时间
2020-2-17
在线时间
133 小时
发表于 2023-2-17 16:41:14 | 显示全部楼层 |阅读模式
void TIM2_PWM_Init(uint16_t f)
{
        uint32_t period,perscaler;
        double timefloat0,timefloat1=0,timefloat_old;
        double temp=0,temp2;
     int i,j,k;
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
        TIM_OCInitTypeDef TIM_OCInitStructure;
        GPIO_InitTypeDef GPIO_InitStructure;
        //f=1000;
        timefloat0=1000000.0f/f;
        timefloat_old=100;
        for(i=0;i<65535;i++)
        {
                temp2=(double)(72*timefloat0)/(i+1);
                if(temp2<65535)
                {
                        if(temp2-(int)temp2!=0)
                        {
                                temp2-=1;
                                for(j=temp2;j<65535;j++)
                                {
                                        timefloat1=(double)((j+1)*(i+1))/72.0f;
                                        temp=timefloat0-10;
                                        if(timefloat1>timefloat0)break;
                                        temp=__fabs(timefloat1-timefloat0);
                                        if(temp<timefloat_old)
                                        {
                                                period=j;perscaler=i;
                                                LCD_ShowxNum(100,160,period,6,16,0);
                                                LCD_ShowxNum(100,180,perscaler,6,16,0);
                                                timefloat_old=temp;
                                                if(timefloat_old==0)break;
                                        }
                                }
                        }else
                        {
                                period=(int)temp2;perscaler=i;
                                break;
                               
                        }
                }
        }
       
        /* 开启时钟 */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
        //RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
       
        /*  配置GPIO的模式和IO口 */
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_2;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
        GPIO_Init(GPIOA,&GPIO_InitStructure);
       

       
        TIM_TimeBaseInitStructure.TIM_Period=period;   //自动装载值
        TIM_TimeBaseInitStructure.TIM_Prescaler=perscaler; //分频系数
        TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
        TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //设置向上计数模式
        TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);       
        TIM_OCInitStructure.TIM_Pulse=period/2;
        TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
        TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;
        TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
        TIM_OC2Init(TIM2,&TIM_OCInitStructure); //输出比较通道1初始化
       
        TIM_OC2PreloadConfig(TIM2,TIM_OCPreload_Enable); //使能TIMx在 CCR1 上的预装载寄存器
        TIM_OC3Init(TIM2,&TIM_OCInitStructure); //输出比较通道3初始化
        TIM_OC3PreloadConfig(TIM2,TIM_OCPreload_Enable); //使能TIMx在 CCR1 上的预装载寄存器
        TIM_ARRPreloadConfig(TIM2,ENABLE);//使能预装载寄存器
        //TIM_CCxCmd(TIM2, TIM_Channel_2, TIM_CCx_Enable);
        TIM_Cmd(TIM2,ENABLE); //使能定时器
       
}

//第一次分享,写法算法低级,别见笑,不知有没有更好的算法,目前这个10K时误差只有1.06HZ,(示波器)

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

使用道具 举报

3

主题

800

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3775
金钱
3775
注册时间
2017-3-7
在线时间
1645 小时
发表于 2023-2-20 09:06:17 | 显示全部楼层
回复 支持 反对

使用道具 举报

1

主题

3

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
251
金钱
251
注册时间
2020-2-17
在线时间
133 小时
 楼主| 发表于 2023-2-20 10:30:45 | 显示全部楼层
a5820736 发表于 2023-2-20 09:06
cubeMX直接就能生成了

公司没有函数发生器,所以自己做 了个输入想要的频率,输出波型做测试用,如果只是定频不改,哪就完全没必了,
回复 支持 反对

使用道具 举报

3

主题

800

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3775
金钱
3775
注册时间
2017-3-7
在线时间
1645 小时
发表于 2023-2-20 10:59:48 | 显示全部楼层
Rick1 发表于 2023-2-20 10:30
公司没有函数发生器,所以自己做 了个输入想要的频率,输出波型做测试用,如果只是定频不改,哪就完全没 ...

接口都是有的,想修改直接调用就行了
回复 支持 反对

使用道具 举报

3

主题

800

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3775
金钱
3775
注册时间
2017-3-7
在线时间
1645 小时
发表于 2023-2-20 11:00:54 | 显示全部楼层
a5820736 发表于 2023-2-20 10:59
接口都是有的,想修改直接调用就行了

也可以学习下人家的代码,你这里面好多定值,移植起来比较麻烦
回复 支持 反对

使用道具 举报

11

主题

2103

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4588
金钱
4588
注册时间
2015-1-10
在线时间
574 小时
发表于 2023-2-20 11:59:10 | 显示全部楼层
用HAL库写过一个,可以自动切换频率和占空比,基本能用
void TIM10_Config(uint32_t freq, uint8_t duty)
{
    TIM_OC_InitTypeDef TIM_OC_InitStructure;

    __HAL_RCC_TIM10_CLK_ENABLE();

    TIM10_Handler.Instance               = TIM10;

    uint32_t arr = 0;
    uint16_t psc = 0;
    do {
        arr=(SystemCoreClock/(psc+1))/freq;
        if (arr > 65500) {
            psc++;
        } else {
            break;
        }
    } while(1);

    TIM10_Handler.Init.Prescaler         = psc;
    TIM10_Handler.Init.Period            = arr - 1;
    TIM10_Handler.Init.ClockDivision     = TIM_CLOCKDIVISION_DIV1;
    TIM10_Handler.Init.CounterMode       = TIM_COUNTERMODE_UP;

    HAL_TIM_Base_Init(&TIM10_Handler);

    HAL_TIM_OC_Init(&TIM10_Handler);

    if (duty != 0) {
        TIM_OC_InitStructure.OCPolarity     = TIM_OCPOLARITY_LOW;
    } else {
        TIM_OC_InitStructure.OCPolarity     = TIM_OCPOLARITY_HIGH;
    }
    TIM_OC_InitStructure.OCMode         = TIM_OCMODE_PWM1;
    TIM_OC_InitStructure.OCFastMode     = TIM_OCFAST_DISABLE;
    TIM_OC_InitStructure.Pulse          = (uint32_t)(TIM10_Handler.Init.Period + 1)*duty/100 - 1;

    HAL_TIM_OC_ConfigChannel(&TIM10_Handler, &TIM_OC_InitStructure, TIM_CHANNEL_1);

    HAL_TIM_OC_Start(&TIM10_Handler, TIM_CHANNEL_1);
}
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-24 16:08

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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