用STM32跑主循环,72M的频率只剩1M

2020-01-01 17:42发布

本帖最后由 delphiliu 于 2012-5-22 17:06 编辑

最近用STM32做全彩的LED显示屏,总是出现画面的闪烁,怀疑是速度太慢了,今天测试,用STM32跑主循环,主循环只有一条翻转指令,结果用示波器测量发现频率只有1M多点。下面是我的时钟设置,8M的外部晶振,DLL作为系统时钟72M。PCLK2是72M,PCLK1是36M。问题出在哪里呢?第一次使用STM32,还请高手指点一二。

void RCC_Configuration(void)
{
   ErrorStatus HSEStartUpStatus;
   RCC_DeInit();                                            //将外设RCC寄存器重设为默认值
   RCC_HSEConfig(RCC_HSE_ON);                               //设置外部高速晶振HSE
   HSEStartUpStatus=RCC_WaitForHSEStartUp();                //等待HSE起振
   if(HSEStartUpStatus==SUCCESS)
   {
     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);  //预取指缓存使能
         FLASH_SetLatency(FLASH_Latency_2);                                     //设置代码延时值 2 延时周期
         RCC_HCLKConfig(RCC_SYSCLK_Div1);                            //设置AHB时钟(HCLK)RCC_HCLK_Div1 APB时钟=系统时钟
     RCC_PCLK2Config(RCC_HCLK_Div1);                        //设置高速AHB时钟(PCLK2)RCC_HCLK_Div1 APB时钟=HCLK  
         RCC_PCLK1Config(RCC_HCLK_Div2);                        //设置低速AHB时钟(PCLK1)RCC_HCLK_Div2 APB1时钟=HCLK/2
     RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);    //设置PLL时钟源及倍频系数
         RCC_PLLCmd(ENABLE);                                    //使能或失能PLL
         while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)       //等待指定的RCC标志位设置成功,等待PLL初始化成功
         {
         }
            RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);             //设置系统时间(SYSCLK),设置PLL为系统时钟源
         while(RCC_GetSYSCLKSource()!=0x08)                     //等待PLL成功用于系统时钟的时钟源
         {                                                                                                                //0x00:HSI作为系统时钟
         }                                                                                                                //0x04:HSE作为系统时钟
                                                                                                                    //0x08:PLL作为系统时钟
   }
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
85条回答
delphiliu
1楼-- · 2020-01-08 10:29
yyts 发表于 2012-5-22 21:06
你按25楼的程序试一下就有接近18M.

while(1)
   {
     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;
   
     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

      GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;
   
     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;
   
     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

      GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;
   
     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;
   
     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

      GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;

     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;
   
     GPIOE->BRR  |=  0x0040;
     GPIOE->BSRR |=  0x0040;
     
            
   }
我是这样设置的,不知道跟25楼的是不是一个道理,因为我用25楼的方法编译不过。
wye11083
2楼-- · 2020-01-08 16:26
LPC系列的寄存器IOA有一组是高速IO,具体多高我不知道,我没法试。跟片子有关了。各大厂商均不兼容,所以我认为ARM之类只能算是不入流的货 {MOD}。只有统一了才有更好的发展。。。。。。。。。。。。。。。。。
delphiliu
3楼-- · 2020-01-08 21:47
wye11083 发表于 2012-5-22 21:57
LPC系列的寄存器IOA有一组是高速IO,具体多高我不知道,我没法试。跟片子有关了。各大厂商均不兼容,所以我 ...

嗯。各有各的优点吧。从目前的发展来看,统一的可能性比较小吧。
severewinner
4楼-- · 2020-01-09 00:14
delphiliu 发表于 2012-5-22 20:59
恩恩,我设置的频率为502M,这个属于总线的频率。也就是访问的频率吧。

GPIOx_CRL

MODEy[1:0]:端口x的模式位(y = 0…7)
软件通过这些位配置相应的I/O端口,请参考表11端口位配置表。
00:输入模式(复位后的状态)
01:输出模式,最大速度10MHz
10:输出模式,最大速度2MHz
11:输出模式,最大速度50MHz



这个配置之后就是对应的速度, 翻转速度,
这个设置为50M
然后程序执行需要时间,算一下,72M的代码执行时间 基本就是IO翻转时间

顺便问一下你是要做时钟大小的判断?
推荐用定时器 按照 72M 算个 1MS的 定时器,进中断翻转,这样可以由中断时间算出主频,(因为计数值没变)

还有时钟输出(功耗比较高,需要电源不能太差劲)

还有主时钟中断,一般专门用来计数中断,ST的FAE推荐用它来测时钟(其实就相当于TIMER 就是级别比较高)
delphiliu
5楼-- · 2020-01-09 02:48
 精彩回答 2  元偷偷看……
ming180
6楼-- · 2020-01-09 07:49
delphiliu 发表于 2012-5-22 21:15
while(1)
   {
     GPIOE->BRR  |=  0x0040;

楼主把
GPIOE->BRR   |=  0x0040;
GPIOE->BSRR  |=  0x0040;
改成
GPIOE->BRR   =  0x0040;
GPIOE->BSRR  =  0x0040;
就接近18MHz了

一周热门 更多>