如何测量单片机程序的运行时间
开发单片机程序的时候,我们经常需要测量一段程序的运行时间,并不断地优化它。那么实际项目中该如何精确地测量一段程序的运行时间呢?一般有两种方法。
1. 使用单片机内部定时器测量,在待测程序段的开始启动定时器,在待测程序段的结尾关闭定时器。为了测量的准确性,要进行多次测量,并进行平均取值。但是该方法在待测程序运行时间极短的情况下,准确性不高。
void Delay_us(uint32_t nCount)
{
/* 清零计数器并开启滴答定时器 */
SysTick->VAL = 0;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
for( ; nCount > 0 ; nCount --)
{
while(SysTick_GetFlagStatus() != SET);
}
/* 关闭滴答定时器 */
SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}
2.借助示波器的测量方法是:在待测程序段的开始阶段使单片机的一个GPIO输出高电平,在待测程序段的结尾阶段再令这个GPIO输出低电平。用示波器通过检查高电平的时间长度,就知道了这段代码的运行时间。显然,借助于示波器的方法更为简便,而且,对于运行时间极短的情况测量准确性更高。
void Delay_us(uint32_t nCount)
{
GPIO_SetBits(GPIOB,GPIO_Pin_0);
for( ; nCount > 0 ; nCount --)
{
while(SysTick_GetFlagStatus() != SET);
}
GPIO_ResetBits(GPIOB,GPIO_Pin_0);
}
单片机之路—通过时间片轮询法解决按键失灵问题
1、概述
(迟到的同学需要先看一下我上一篇独立按键操作的文章哦)上次文章中我们通过按键去控制流水灯的流水花式,我们发现按键会出现失灵的情况。原因是我们把按键扫描的执行任务优先级和执行流水灯的任务优先级放在一起了,互不能相互打断,但是,在我们的理解来说按键扫描的任务要比流水灯的任务优先级高才对。好比说,你正在写作业,你妈妈叫你写完作业后烧一壶开水。我们先要去听取并记住妈妈的指令,然后写完作业后才去执行烧开水的任务。在我们的程序中,妈妈下达的烧开水的指令就是用户按下按键通知程序执行完这次流水灯操作后去执行另外一种样式的流水灯。这个过程中程序需要先获取到按键的指令,并且记录下来,等执行完当前的任务后,再去执行新的任务。否则任务紧急任务(扫描按键)出现延时执行的情况,导致执行结果不是我们想要的。
2、时间片轮询法
显然的,按键扫描任务是一个要求实时性高的任务,所以在按键按下时,我们需要立即去查询当前的按键状态,并记录当前的按键状态。现在我们问题就是执行一次循环时间太长了,有没有办法使得执行一次循环更快,在很短的时间就能执行完一次循环,每个循环中都去检查一下按键的状态,这样就不会错过扫描按键的时机了。每一个时间片进行计数,计数到设定数值时,再去执行实时性要求不高的任务,比如流水灯切换任务。
时间片轮询法流程图
3、时间片轮询法在按键检测中的应用
我们开看在按键切换流水灯流水花式的程序中,怎么使用时间片轮询法。首先,在主循环之前定义一个按键状态记录的寄存器
unsigned char KeyNum = 0;
将主循环分成5ms每次的小循环,并且定义一个循环计数寄存器
void main()
{
unsigned char i;
unsigned char KeyNum = 0;
unsigned char Count = 0;
for(;;)
{
Count++;
if(Count >=250)
{
Count = 0; //防止溢出操作
}
delay_ms(5);
}
}
对计数进行判断,到设定计数执行对应的任务
void main()
{
unsigned char KeyNum = 0;//按键状态记录
unsigned char Count = 0;//计数记录
unsigned char LEDStatus= 1; //流水灯状态记录
for(;;)
{
Count++;
if(Count >200)
{
Count = 0; //计数清零
}
if((Count == 100)||(Count == 200))
{
if(KeyNum == 1)
{
//闪烁花式
if(Count == 100)
{
LedDisplay(0xAA);
}
else if(Count == 200)
{
LedDisplay(0x55);
}
}
else if(KeyNum == 2)
{
//流水花式
LedDisplay(~dat);
dat = 0x01<<LEDStatus;
LEDStatus++;
if(LEDStatus>=8)
{
LEDStatus = 0;
}
}
else
{
LedDisplay(0x00);
}
}
delay_ms(5);
}
}
4、总结
虽然这样能够实现功能,但是我们发现程序中需要定义很多的寄存器变量来保存程序的执行状态,搞得程序很繁琐,不够清爽。是否有一种方法可以让单片机在检测到触发事件时,自动记录程序的执行状态,并且去执行事件。执行完成事件后回来继续执行程序。实际是有的,那就是单片机的中断机制,我们可以通过单片机的中断机制实现程序的前后台系统。关注我,下次文章我带大家学习51单片机的外部中断。
相关问答
单片机 监控电流和充电 时间 -ZOL问答用放大器把电阻上的电压放大后给单片机的ADC作为电流计算的参数;由于取电端是USB的DC5V,所以单片机的供电甚至可以不用稳压,但是得选一个内部有ADC基准电压的单...
8位 单片机 系统运行 时间 ?8位单片机的系统运行时间取决于多个因素,包括但不限于以下几点。首先,系统运行时间取决于单片机的时钟频率。时钟频率越高,单片机每秒钟执行的指令数量就越多...
51系列 单片机 的最小 时间 单位?MCS—51时序中最小的时间单位是机器周期。时序是用定时单位来描述的,MCS-51的时序单位有四个,它们分别是节拍、状态、机器周期和指令周期,接下来我们分别加...
单片机 的延时10ms是多长 时间 啊?-ZOL问答延时10毫秒在电子领域中是指一个时间单位,表示为1/1000秒。在计算机系统中,10毫秒相当于0.01秒。延时10毫秒的计算方法是将1秒钟除以10,即1000/10=10。延时是...
...工作方式0、方式1、方式2下,其最大的定时 时间 为多少】作业帮[最佳回答]Z,则振荡周期Tosc=1/6uS。工作方式0:此时为13位定时/计数器,则最大计数值为2的13次方(即8192)工作方式1:为16位定时/计数器,则最大计数...工作方...
单片机时间 参数是什么?单片机时间参数是指单片机中用来计算时间的参数。它通常由内部时钟、外部晶体振荡器或RTC实时时钟等组成。单片机可以通过时间参数来实现定时、延时、计数等功...
51 单片机 MCS-51,如果采用的晶振的频率为3MHz,定时器/计数器...[最佳回答]方式0:2^13/3M*12=0.032768s;方式1:2^16/3M*12=0.262144s;方式2:2^8/3M*12=0.001024s;方式0:2^13...
单片机 定时的 时间 怎么改变?现在很多单片机有溢出自动赋初值功能,比较方便。二、向下定时计数器举例当放入155毫升水时,就能流出155毫升水。放入200毫升水,能流出200毫升水。水越多定时...
单片机 中的延时程序的延时 时间 怎样计算的?比如说:voiddelay(){intx;chary;for(x=1000;x>0;x--){for(y=100;y>0;y--)};}x每减一次,y减100次,x一共减...
如何实现 单片机 通过WIFI获取 时间 和天气数据?如果是arm的开发板,很简单,能够直接实现获取互联网上的数据,编个程序提取网站上的信息就行(wifi的驱动如果已经有了最好,没有就要自己写驱动了……),,如果...