秒表计时器开始计时代码_如何计时代码

秒表计时器开始计时代码

There is often more than one way to accomplish a particular coding task and one of the criteria that can be used to determine which method to use is to determine which one is the fastest.  But how do you do that? You could try using displays of Visual Basic's Now() or Time() functions, and doing that will get you some results but they won't be very accurate since the accuracy of those functions is only about 1 second and that is huge compared to the time it takes to run a line, or even in most cases, thousands of lines of code. To improve on that you'll need to use an API. Some of the API possibilities are GetTickCount, TimeGetTime and QueryPerformanceCounter. Here's a chart of the commonly used methods and their accuracy.

通常,完成特定编码任务的方法不止一种,并且可以用来确定使用哪种方法的标准之一就是确定哪种方法最快。 但是,你是怎么做的? 您可以尝试使用Visual Basic的Now()或Time()函数的显示,这样做将获得一些结果,但是它们将不会非常准确,因为这些函数的准确性仅为1秒左右,与运行一行,甚至在大多数情况下,数千行代码所花费的时间。 要改善这一点,您需要使用API​​。 API的某些功能包括GetTickCount,TimeGetTime和QueryPerformanceCounter。 这是常用方法及其准确性的图表。

Accuracy

As you can see, GetTickCount and TimeGetTime are a hundred times more accurate than the VB functions and 10 ms is likely fine enough for any code that you want to time. QueryPerformanceCounter is much more accurate than that in that it can measure actual CPU cycles but most programmers will never need to do that.

如您所见,GetTickCount和TimeGetTime的精度比VB函数高100倍,对于任何您想计时的代码,10 ms可能就足够了。 QueryPerformanceCounter比它可以测量实际CPU周期的精度要高得多,但是大多数程序员都不需要这样做。

Here's a VB6 example that uses GetTickCount. In this case a comparison is done between 'Test1' where the Array function to fill an array, and 'Test2' where a more manual approach is used.  

这是一个使用GetTickCount的VB6示例。 在这种情况下,将在“ Test1”(使用数组函数填充数组)和“ Test2”(使用更手动的方法)之间进行比较。

Each test uses a loop that repeats an action the same, large, number of times. The use of the large number of loops magnifies the results of the test and that is necessary because an individual line of code can be almost too fast to measure. It also helps smooth out small differences caused by random processes going on in the background.

每个测试都使用一个循环,该循环重复执行一次相同的,较大的次数。 大量循环的使用放大了测试的结果,这是必须的,因为单个代码行可能几乎太快而无法测量。 它还有助于消除由后台进行的随机过程引起的微小差异。

When you run this example you'll find the second method is faster than the first and that's because Test1's Array function requires that the target array be of type Variant, and Variants are slow (and large). Some people would still use the first because it requires less coding. In my opinion that's short-sighted because while you only write code once, the code may get executed thousands of times.

运行此示例时,您会发现第二种方法比第一种方法快,这是因为Test1的Array函数要求目标数组的类型为Variant,而Variants较慢(且较大)。 有些人仍然会使用第一个,因为它需要较少的编码。 我认为这是短视的,因为虽然您只编写一次代码,但是该代码可能被执行数千次。

Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Sub Command1_Click()
    ' Place this code in any Sub or Function
    Dim lngStart As Long
    Dim lngFinish As Long
    Dim lngCounter As Long
    Dim varArr As Variant
    Dim strArr(2) As String
    
    'TEST1
    ' Record the start "time"
    lngStart = GetTickCount()
    
    ' Some process that you want to time
    For lngCounter = 1 To 100000
        varArr = Array("A", "B", "C")
    Next
    
    ' Record the finish "time"
    lngFinish = GetTickCount()
    
    ' Display the difference
    Debug.Print "Test 1: " & CStr(lngFinish - lngStart)
    
    'TEST2
    ' Record the start "time"
    lngStart = GetTickCount()
    
    ' Some process that you want to time
    For lngCounter = 1 To 100000
        strArr(0) = "A"
        strArr(1) = "B"
        strArr(2) = "C"
    Next
    
    ' Record the finish "time"
    lngFinish = GetTickCount()
    
    ' Display the difference
    Debug.Print "Test 2: " & CStr(lngFinish - lngStart)

End Sub

And here is an example using VBA in Excel where a comparison is made between two different ways to fill a range.

这是一个在Excel中使用VBA的示例,其中比较了两种不同的方式来填充范围。

Private Sub CommandButton1_Click()

    ' Place this code in any Sub or Function
    Dim lngStart As Long
    Dim lngFinish As Long
    Dim lngCounter As Long
    
    'TEST1
    ' Record the start "time"
    lngStart = GetTickCount()
    
    ' Some process that you want to time
    For lngCounter = 1 To 30000
        Range("A" & lngCounter).Value = lngCounter
    Next
    
    ' Record the finish "time"
    lngFinish = GetTickCount()
    
    ' Display the difference
    Debug.Print "Test1: " & CStr(lngFinish - lngStart)
    
        
    'TEST2
    ' Record the start "time"
    lngStart = GetTickCount()
    
    ' Some process that you want to time
    For lngCounter = 1 To 30000
        Cells(lngCounter, 1).Value = lngCounter
    Next
    
    ' Record the finish "time"
    lngFinish = GetTickCount()
    
    ' Display the difference
    Debug.Print "Test2: " & CStr(lngFinish - lngStart)

End Sub

Finally, I never actually use it, but here's a QueryPerformanceCounter example.

最后,我从未真正使用过它,但是这里有一个QueryPerformanceCounter示例。

Option Explicit
Private Declare Function QueryPerformanceCounter Lib "Kernel32" (X As Currency) As Boolean
Private Declare Function QueryPerformanceFrequency Lib "Kernel32" (X As Currency) As Boolean

Private Sub CommandButton1_Click()
Dim frequency As Currency
Dim curStart As Currency
Dim curFinish As Currency
Dim lngCounter As Long
Dim varArr As Variant
' Get the frequency counter
' Return zero if hardware doesn't support high-res performance counters
If QueryPerformanceFrequency(frequency) = 0 Then
    MsgBox "This computer doesn't support QueryPerformanceCounter"
    Exit Sub
End If
' start timing
QueryPerformanceCounter curStart
' Code to be timed
For lngCounter = 1 To 100000
    varArr = Array("A", "B", "C")
Next
' end timing
QueryPerformanceCounter curFinish

Debug.Print (curFinish - curStart) / frequency

End Sub

If you find that this article has been helpful, please click the “thumb’s up” button below. Doing so lets me know what is valuable for EE members and provides direction for future articles. It also provides me with positive feedback in the form of a few points. Thanks!

如果您发现本文对您有所帮助,请单击下面的“竖起大拇指”按钮。 这样做可以让我知道对EE成员有价值的内容,并为以后的文章提供指导。 它还以几点的形式为我提供了积极的反馈。 谢谢!

翻译自: https://www.experts-exchange.com/articles/10592/How-to-Time-Code.html

秒表计时器开始计时代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM单片机秒表计时器代码可以通过使用STM32CubeMX和Keil MDK等开发工具实现。下面是一个简单的示例代码: 首先,需要在STM32CubeMX中配置TIMER模块。选择一个可用的TIMx定时器,并使能中断。选择计数模式为向上计数,在高级定时器设置中将自动重载预装载器选择为使能,以便在计时器到达计数数值时自动重新开始。 接下来,定义一个起始时间变量,并在主函数中初始化计时器和中断。在中断服务函数中读取计时器的计数值,并将其转换为秒和毫秒,然后将其显示在LCD屏幕上。最后,更新起始时间变量以便下次计时始于上一次计时结束的时间点。 示例代码如下: #include "stm32f1xx_hal.h" #include "lcd.h" TIM_HandleTypeDef htim; uint32_t start_time = 0; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_TIM_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_TIM_Init(); lcd_init(); // 初始化LCD屏幕 HAL_TIM_Base_Start_IT(&htim); // 启动计时器和中断 while (1) {} } void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim == &htim) { // 判断是否为本计时器的中断 uint32_t elapsed_time = HAL_TIM_ReadCounter(&htim); // 读取计数值 uint32_t seconds = elapsed_time / 1000; // 计算秒数和毫秒数 uint32_t milliseconds = elapsed_time % 1000; lcd_printf("%d.%03d seconds", start_time + seconds, milliseconds); // 显示时间 start_time += seconds; // 更新起始时间 HAL_TIM_Base_Start_IT(&htim); // 重新启动计时器 } } static void MX_TIM_Init(void) { TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; htim.Instance = TIM2; // 使用TIM2计时器 htim.Init.Prescaler = 7200 - 1; // 分频器将时钟频率减少7200倍 htim.Init.CounterMode = TIM_COUNTERMODE_UP; // 向上计数 htim.Init.Period = 1000 - 1; // 计数器将从0到999计数 htim.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; // 自动重载 if (HAL_TIM_Base_Init(&htim) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim, &sMasterConfig) != HAL_OK) { Error_Handler(); } } void Error_Handler(void) { while (1) {} } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } } static void MX_GPIO_Init(void) { __HAL_RCC_GPIOC_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值