1. 如果你不跑操作系统,CPU肯定一直都是100%使用的,哪怕你里面是延时等待,CPU也是一直在执行空语句nop,因为STM32里面是有一个CPU。
2.对于stm32总是百分百。只是有多少时间空闲,多少时间干活!
3.
楼主的意思是实际CPU用来干正事的时间,在整个时间里的比例,打个比方,如果工作50mS,再等待200mS,完成一个大循环,那么CPU的使用率就是20%。 如果楼主的程序是以大循环方式做的,那么在进入等待前把一个IO口拉低,等待结束,开始工作,把IO口拉高,那么占空比就是使用率,当然这是在各种中断不是很频繁,而且中断里处理的事情很少的情况下有用,我经常这么估算MCU的速率富余度的,然后据此设置一个合适的MCU工作频率,降低不仅仅是CPU的功耗那一点点电能,如果是线性降压,整个功耗下降很多的,发热就低了,而且工作频率下降,CPU稳定性也会增强。 |
这里我用到的是Sleep状态,即设计程序时,当程序的任务处理完后,使单片机进入WFE或WFI的Sleep状态:
使用操作系统时,直接在空闲任务中添加__WFI();或__WFE();即可
裸机程序时,设计程序结构为大main循环为中断或事件触发的形式,即main循环等待队列中的任务,当队列为空时,执行__WFI();或__WFE();。添加队列的操作在串口、按键、计时器中断中进行,等等。
然后,我们采用的是外设的低功耗状态,即STM32的外设可以在内核进入低功耗状态后,手动或自动停止外设的时钟,当退出低功耗状态时手动或自动恢复外设始终。
由于我这方法是在F4上面实现的,采用F1实现时,会显得臃肿一些,大家理解啥意思就行了,采用F4时会方便很多。
这是F1的外设低功耗特性,可见,外设在内核进入低功耗状态时,外设时钟只能手动打开和关闭。
这是F4的外设低功耗特性,可见,外设在内核进入低功耗状态时,外设时钟可以自动关闭。
在使用F4时,我们就可以采用如TIM6和TIM7两个计时器
配置如下
- void tim6_init(void)
- {
- TIM_TimeBaseInitTypeDef TIM_InitStructure;
- RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM6, ENABLE );
- RCC_APB1PeriphClockLPModeCmd(RCC_APB1Periph_TIM6, DISABLE);
-
- TIM_DeInit(TIM6);
- TIM_InitStructure.TIM_Prescaler = 180;
- TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_InitStructure.TIM_Period = 65535;
- TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
- TIM_InitStructure.TIM_RepetitionCounter = 0;
- TIM_TimeBaseInit(TIM6, &TIM_InitStructure);
- TIM_SetCounter(TIM6, 0);
- TIM_ITConfig(TIM6, TIM_IT_Update, DISABLE);
- TIM_Cmd(TIM6, ENABLE);
- }
- void tim7_init(void)
- {
- TIM_TimeBaseInitTypeDef TIM_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
-
- RCC_APB2PeriphClockCmd (RCC_APB2Periph_SYSCFG, ENABLE);
- RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM7, ENABLE);
- RCC_APB1PeriphClockLPModeCmd(RCC_APB1Periph_TIM7, ENABLE);
-
- TIM_DeInit(TIM7);
- TIM_InitStructure.TIM_Prescaler = 180;
- TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_InitStructure.TIM_Period = 65535;
- TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
- TIM_InitStructure.TIM_RepetitionCounter = 0;
- TIM_TimeBaseInit(TIM7, &TIM_InitStructure);
- TIM_SetCounter(TIM7, 0);
- TIM_ITConfig(TIM7, TIM_IT_Update, ENABLE);
-
- NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
-
- TIM_Cmd(TIM7, ENABLE);
- }
TIM7中断代码如下:
- void TIM7_IRQHandler(void)
- {
- TIM7->SR = ~TIM_IT_Update;
- CPU_TICK_USAGE = TIM6->CNT;
- TIM6->CNT = 0;
- }
计算CPU使用率(%)如下:
- CPULoad = (float)CPU_TICK_USAGE*100.0f/65535.0f
当采用F1时,那就需要在每个中断的入口处,手动添加代码,使能TIM6时钟
并在每个__WFE();或__WFI();前手动添加代码,关闭TIM6时钟
在每个__WFE();或__WFI();后手动添加代码,使能TIM6时钟
当然,采用F1时,不用__WFE();或__WFI();而只用while循环也是一样的。
5.
围观,个人觉得既然是裸机,就没必要考虑CPU的使用率了 |
dwiller_ARM 发表于 2014-2-20 13:58 在一般的应用中还是可以采用的,如现在我做的变频器项目,可以通过查看CPU的使用率考虑算法的复杂性,并根据CPU使用率确定最高的采样频率和PWM周期,同时确定CPU主频选取的是否合适。按我的感觉是,CPU使用率为75~85%时最合适。 |