关于STM32的CPU的使用率~裸机不带系统

1. 如果你不跑操作系统,CPU肯定一直都是100%使用的,哪怕你里面是延时等待,CPU也是一直在执行空语句nop,因为STM32里面是有一个CPU。

2.对于stm32总是百分百。只是有多少时间空闲,多少时间干活!

3.

楼主的意思是实际CPU用来干正事的时间,在整个时间里的比例,打个比方,如果工作50mS,再等待200mS,完成一个大循环,那么CPU的使用率就是20%。

如果楼主的程序是以大循环方式做的,那么在进入等待前把一个IO口拉低,等待结束,开始工作,把IO口拉高,那么占空比就是使用率,当然这是在各种中断不是很频繁,而且中断里处理的事情很少的情况下有用,我经常这么估算MCU的速率富余度的,然后据此设置一个合适的MCU工作频率,降低不仅仅是CPU的功耗那一点点电能,如果是线性降压,整个功耗下降很多的,发热就低了,而且工作频率下降,CPU稳定性也会增强。

4. 首先,我们知道Cortex有几种内核的低功耗工作状态,Sleep, Stop, Standby
这里我用到的是Sleep状态,即设计程序时,当程序的任务处理完后,使单片机进入WFE或WFI的Sleep状态:

使用操作系统时,直接在空闲任务中添加__WFI();或__WFE();即可
裸机程序时,设计程序结构为大main循环为中断或事件触发的形式,即main循环等待队列中的任务,当队列为空时,执行__WFI();或__WFE();。添加队列的操作在串口、按键、计时器中断中进行,等等。

然后,我们采用的是外设的低功耗状态,即STM32的外设可以在内核进入低功耗状态后,手动或自动停止外设的时钟,当退出低功耗状态时手动或自动恢复外设始终。
由于我这方法是在F4上面实现的,采用F1实现时,会显得臃肿一些,大家理解啥意思就行了,采用F4时会方便很多。
这是F1的外设低功耗特性,可见,外设在内核进入低功耗状态时,外设时钟只能手动打开和关闭。

这是F4的外设低功耗特性,可见,外设在内核进入低功耗状态时,外设时钟可以自动关闭。


在使用F4时,我们就可以采用如TIM6和TIM7两个计时器
配置如下
  1. void tim6_init(void)
  2. {
  3.         TIM_TimeBaseInitTypeDef TIM_InitStructure;

  4.         RCC_APB1PeriphClockCmd      (RCC_APB1Periph_TIM6, ENABLE );
  5.         RCC_APB1PeriphClockLPModeCmd(RCC_APB1Periph_TIM6, DISABLE);
  6.         
  7.         TIM_DeInit(TIM6);
  8.         TIM_InitStructure.TIM_Prescaler         = 180;
  9.         TIM_InitStructure.TIM_CounterMode       = TIM_CounterMode_Up;
  10.         TIM_InitStructure.TIM_Period            = 65535;
  11.         TIM_InitStructure.TIM_ClockDivision     = TIM_CKD_DIV1;
  12.         TIM_InitStructure.TIM_RepetitionCounter = 0;
  13.         TIM_TimeBaseInit(TIM6, &TIM_InitStructure);
  14.         TIM_SetCounter(TIM6, 0);
  15.         TIM_ITConfig(TIM6, TIM_IT_Update, DISABLE);
  16.         TIM_Cmd(TIM6, ENABLE);
  17. }
  18. void tim7_init(void)
  19. {
  20.         TIM_TimeBaseInitTypeDef TIM_InitStructure;
  21.         NVIC_InitTypeDef   NVIC_InitStructure;
  22.         
  23.         RCC_APB2PeriphClockCmd      (RCC_APB2Periph_SYSCFG, ENABLE);
  24.         RCC_APB1PeriphClockCmd      (RCC_APB1Periph_TIM7,   ENABLE);
  25.         RCC_APB1PeriphClockLPModeCmd(RCC_APB1Periph_TIM7,   ENABLE);
  26.         
  27.         TIM_DeInit(TIM7);
  28.         TIM_InitStructure.TIM_Prescaler         = 180;
  29.         TIM_InitStructure.TIM_CounterMode       = TIM_CounterMode_Up;
  30.         TIM_InitStructure.TIM_Period            = 65535;
  31.         TIM_InitStructure.TIM_ClockDivision     = TIM_CKD_DIV1;
  32.         TIM_InitStructure.TIM_RepetitionCounter = 0;
  33.         TIM_TimeBaseInit(TIM7, &TIM_InitStructure);
  34.         TIM_SetCounter(TIM7, 0);
  35.         TIM_ITConfig(TIM7, TIM_IT_Update, ENABLE);
  36.         
  37.         NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;
  38.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;
  39.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;
  40.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  41.         NVIC_Init(&NVIC_InitStructure);
  42.         
  43.         TIM_Cmd(TIM7, ENABLE);
  44. }
复制代码


TIM7中断代码如下:
  1. void TIM7_IRQHandler(void)
  2. {
  3.         TIM7->SR           = ~TIM_IT_Update;
  4.         CPU_TICK_USAGE     = TIM6->CNT;
  5.         TIM6->CNT          = 0;
  6. }
复制代码


计算CPU使用率(%)如下:
  1. CPULoad   = (float)CPU_TICK_USAGE*100.0f/65535.0f
复制代码


当采用F1时,那就需要在每个中断的入口处,手动添加代码,使能TIM6时钟
并在每个__WFE();或__WFI();前手动添加代码,关闭TIM6时钟
在每个__WFE();或__WFI();后手动添加代码,使能TIM6时钟

当然,采用F1时,不用__WFE();或__WFI();而只用while循环也是一样的。


5.

围观,个人觉得既然是裸机,就没必要考虑CPU的使用率了

6.
dwiller_ARM 发表于 2014-2-20 13:58
围观,个人觉得既然是裸机,就没必要考虑CPU的使用率了

在一般的应用中还是可以采用的,如现在我做的变频器项目,可以通过查看CPU的使用率考虑算法的复杂性,并根据CPU使用率确定最高的采样频率和PWM周期,同时确定CPU主频选取的是否合适。按我的感觉是,CPU使用率为75~85%时最合适。

猜你喜欢

转载自blog.csdn.net/anbaixiu/article/details/80029091