STM32-- 扩展 while(1)

本文详细解释了单片机编程中while(1)的两种主要用途及其应用场景,包括作为死循环防止程序跑飞及在主程序中循环执行特定任务。

摘抄自--优快云

单片机中while(1)有两种用途,

while(1);

意义:这是一个死循环,代码不再向下执行。

用途:

1.让主函数只循环一次

2.一般在调试代码时,为了检测一部分代码是否OK,防止后面的代码干扰执行结果,会在观测点加上while(1);

3. 有些代码检测到运行错误时,会抛出错误(打印、设置错误码),然后进入while(1);

4.  机器需要复位时,停止喂看门狗,进入while(1); 迫使看门狗超时,产生硬件复位

while( 1 ) { 代码 }

意义:这里将会重复执行{}中的代码

用途:

1.  单片机在不使用操作系统时,主程序一般都使用这种架构

2. 操作系统中的进程,执行任务时,有些也会使用这种架构

3. {}中的代码不停地检测某个条件,当条件符合时,跳出该循环,继续向下执行

我们在单片机中使用while(1),大部分还是为了防止程序跑飞,因为很多时候执行完某段程序后单片机的程序指针PC(就是程序指针)并不会停止,仍然会继续从ROM中读取指令并执行,这样一来可能会出现程序跑飞的情况,进而出现不确定的结果,我们加个while(1)就能让程序在执行完后在原地循环,相当于停在原地,防止跑飞。

原则上来讲,如果程序中没有加结尾的话,程序计数器会继续累加,从而执行正常程序后面的ROM空间里面的指令,不过一般这个指令都是0XFF,这就要看这条指令的含义了,如果是空的话就会一直执行到最后,直到程序计数器溢出,只是不知道程序计数器发生溢出是一个什么状态,有可能回到复位状态值,也有可能直接就让单片机死在这里不工作,这个就要看单片机的具体设计了。

在主程序里应当有

while(1)

{

  ..;

}

否则单片机的程序会继续按地址运行下去,到0ffffh后-》00000h。

如果不加while(1)语句,单片机依然正常运行,就是后面的地址里恰好有什么东西使得程序形成死循环,没有飞跑,那也是凑巧。

<think>好的,用户想了解如何测量STM32while循环的执行速度。首先,我需要回忆一下STM32的性能分析方法。通常,测量代码执行时间可以使用定时器或者示波器。 首先,使用定时器的方法。STM32内部有多个定时器,比如通用定时器或SysTick定时器。可以配置一个定时器,在进入while循环前启动,在循环结束后停止,然后计算经过的时间。不过,while循环如果是无限循环,这种方法可能不太适用,因为循环不会结束。所以可能需要让循环执行固定次数,然后测量总时间,再取平均值。例如,让循环执行1000次,用定时器记录开始和结束的时间戳,差值除以次数得到单次循环时间。 接下来,考虑使用GPIO和示波器的方法。在进入循环前翻转一个GPIO引脚的电平,循环结束后再次翻转,通过示波器测量两个边沿之间的时间差。这种方法更直接,但需要硬件设备支持。需要注意的是,GPIO操作本身会消耗时间,可能会引入误差,因此要确保翻转操作尽可能快,或者将循环体设计成包含多个迭代,以减小测量误差。 另外,还要考虑编译器的优化问题。编译器可能会优化掉空循环,导致测量不准确。因此,在代码中可能需要使用volatile变量来防止优化。例如,在循环条件中使用volatile变量,确保循环不被移除。 还有,时钟频率的影响。STM32的CPU频率决定了指令执行速度。如果系统时钟配置不正确,测量结果会有偏差。需要确认MCU的实际运行频率,比如STM32F103通常运行在72MHz,而其他型号可能有不同的频率。时钟配置是否正确会影响定时器的计时精度。 用户可能还想知道如何分析性能,比如查看反汇编代码来估算指令周期。但这种方法比较复杂,需要了解处理器的指令集和流水线结构。对于大多数应用,使用定时器或示波器的方法更实际。 总结一下,常用的方法有:使用定时器测量固定次数的循环时间,用GPIO和示波器捕捉时间差,以及防止编译器优化的措施。同时,需要确保系统时钟配置正确,避免测量误差。 现在,根据参考的引用内容,引用[1]提到STM32系列有很好的兼容性,学习F103后容易掌握其他系列,所以这里的方法可能适用于其他型号。引用[3]提到DMA的高效性,但这个问题不涉及DMA,可能暂时用不上。不过,在提到减少CPU负载时,可以联想到使用定时器中断或DMA来辅助测量,但用户的问题是关于while循环本身的执行速度,因此重点还是在直接测量方法上。</think>### STM32 while循环执行速度的测量方法 #### 1. **定时器测量法** **步骤:** 1. 配置一个高精度定时器(如通用定时器TIM2或SysTick)。 2. 在进入循环前记录定时器计数值$T_1$。 3. 执行固定次数的循环(如1000次)。 4. 循环结束后记录计数值$T_2$。 5. 计算单次循环时间: $$ \text{单次时间} = \frac{(T_2 - T_1) \times \text{时钟周期}}{\text{循环次数}} $$ **注意:** - 使用`volatile`修饰循环变量,防止编译器优化[^3]。 - 定时器时钟需与系统时钟同步(如STM32F103的72MHz主频)。 #### 2. **GPIO + 示波器法** **步骤:** 1. 配置一个GPIO引脚为输出模式。 2. 进入循环前拉高引脚电平。 3. 在循环体内插入空操作或特定代码。 4. 循环结束后拉低引脚电平。 5. 通过示波器测量高电平持续时间,直接得到循环执行时间。 **优势:** - 直观且误差较小,适合测量短时间间隔[^1]。 #### 3. **性能分析工具(如STM32CubeIDE)** - 使用调试模式中的**性能计数器**(Performance Counter)功能,直接统计循环占用的CPU周期数。 - 结合反汇编代码分析单条指令的时钟周期,估算循环耗时[^2]。 #### 示例代码(定时器法) ```c volatile uint32_t i; HAL_TIM_Base_Start(&htim2); // 启动定时器 uint32_t start = __HAL_TIM_GET_COUNTER(&htim2); for (i = 0; i < 1000; i++); // 被测循环 uint32_t end = __HAL_TIM_GET_COUNTER(&htim2); uint32_t elapsed_time = end - start; // 总计时钟周期数 ``` #### 关键影响因素 1. **编译器优化等级**:高优化等级可能删除空循环,需使用`volatile`变量。 2. **CPU主频**:STM32F103默认72MHz,时钟周期约13.89ns。 3. **循环体复杂度**:循环内代码的指令数量和类型直接影响速度。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值