STM32 定时器输出方波的频率与PSC以及CNT的关系

1.STM32F103的系统时钟最高频率是72MHZ
2.STM32F103的定时器TIM 的CNT计数值最大为65535
3.STM32F103的定时器TIM 的预分频 系数 PSC 的数值 = 72M / 定时器计数频率

因为CNT最大值为65535 所以, 这里有个问题, 当定时器计数频率太高的时候, 例如72M的计数频率.
1秒钟最多有72000000个计数, 当计数到65535个的时候是 0.0009102083秒 也就是 1098.65HZ
要想计数到1秒, 必须修改PSC,提高分频系数. 降低定时器计数频率

经过实际测量, STM32F103C8T6 最高输出方波的频率为18mhz. 再往上就无法输出了.
(有可能是我这个示波器的问题, 我的是pc虚拟示波器最大才20m的采样频率. )
后来实验确定最高确实只能达到18mhz, 因为ARR为1, PSC为0 已经是最高了. 不可能再高了.
估计STM32F4系列应该会更高一些吧.

下面列出了表格.

系统时钟频率 PSC 定时器计数频率
最高输出方波频率
定时器计数频率(MHZ) 最低输出方波频率
72000000 0 72000000.00 72.00 1098.65
72000000 1 36000000.00 36.00 549.32
72000000 3 18000000.00 18.00 274.66
72000000 5 12000000.00 12.00 183.11
72000000 7 9000000.00 9.00 137.33
72000000 11 6000000.00 6.00 91.55
72000000 23 3000000.00 3.00 45.78
72000000 35 2000000.00 2.00 30.52
72000000 71 1000000.00 1.00 15.26
72000000 719 100000.00 0.10 1.53
void ChangCLK(uint32_t fclk )
{  
      float rfclk = fclk * 2 ;   //pwm波的频率是一高一低,两个才是一个周期,所以必须是两倍才能正常输出.同样频率的方波. 
        //重复计算,MaxCOUNT 和 TIME4_PSC 直到满足条件
        while(1)
        {  
                //TIME4_PSC + 1// 预分配需要72 但是要填71. 因为STM32器件就是这么规定的. 
                //计数频率   =  时钟主频 / 预分频系数 
                JiShuPinLv = TIME_ZhuPinLv / (TIME4_PSC + 1.0);

                //目标频率   =  计数频率 * 计数个数MaxCOUNT;
                //目标周期   =  1/目标频率;
                //计数周期   =  1/计数频率;

                //计数个数MaxCOUNT   =  目标周期 / 计数周期 
                //得
                //计数个数MaxCOUNT   =  (1/目标频率)  / (1/计数频率) 
                //MaxCOUNT =   (1.0 / rfclk) /  (1 / JiShuPinLv); 

                //这种做法, 不适合程序执行, 耗时又不准,简化推导过程如下
                //x = (1/a) / (1/b)
                //x * a = a * (1/a) / (1/b)
                //x * a = 1 / (1/b)
                //x * a = b
                //x = b/a

                //代入简化后
                MaxCOUNT = JiShuPinLv / rfclk;  


                if(TIME4_PSC == 0 || TIME4_PSC >= 65535) 
                {
                    break; //到极限了,下面就不要再计算PSC了
                }

                if(MaxCOUNT <= 2) 
                {
                    //计数周期大于目标周期, 那么减少预分频数值,提高计数频率
                    TIME4_PSC  = TIME4_PSC / 10;
                    if(TIME4_PSC > 0)
                    {
                        continue; //下一循环再调整 ,并同时重新计算MaxCOUNT
                    }
                }
                else if( MaxCOUNT>=65535)
                {
                    //计数值的范围不够了.那么增加预分频数值,降低计数频率 
                    TIME4_PSC  = TIME4_PSC * 10;
                    if(TIME4_PSC < 65535)
                    {
                        continue; //下一循环再调整 ,并同时重新计算MaxCOUNT
                    }

                }else{
                    //一般情况下都是直接退出.
                    break;  
                }

        }

        if(MaxCOUNT <= 2) {
              MaxCOUNT =2;//ARR不能等于0 否则就没有频率输出了.
        }else if(TIME4_PSC > 65536) {
                MaxCOUNT = 65536; 
        }

        TIME4->PSC = TIME4_PSC;
        TIME4->ARR  =   MaxCOUNT - 1;  //-1是 STM32 器件本身的特点,填入MaxINT-1才是真正的按照MaxINT运行.   //Period == ARR
        //TIME4->CNT  =  0;
        //TIME4->CCR1 =  0 ; //输出比较模式下这个寄存器控制初相位应该都为0, pwm模式才是控制的高电平周期

}

你可能感兴趣的:(单片机)