[英]Implementing/simulating 16bit counter with 20Mhz clock and 1024 prescaler in C
我希望(大致)在C中模擬Atmega128的Timer / Counter1。這是一個16位計數器,時鍾運行在20MHz(F_CPU)。 我想要預分頻(CLOCK_PRESCALER)為1024。
我目前的實施如下:
// Simulate 16bit counter with a 16MHz clock and prescale of 1024 (as mega128)
// The counter overflows every 65 536* 1024/20M= 3.3554432s or 3355.4432 ms or 3355443.2us or 3 355 443 200 ns
UInt32 getClock(void){
UInt32 curr_clock_time_us;
UInt32 diff;
UInt32 unscaled_clock;
UInt32 scaled_clock;
struct timespec temp;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &temp);
curr_clock_time_us = temp.tv_nsec/1000;
diff = curr_clock_time_us - prev_clock_time_us;
//represents timer overflows, which happens every 4194304000 ns.
if(diff > ((UInt32)3355443)){
prev_clock_time_us = curr_clock_time_us; // on overflow the counter (here the diff) should be 0 if we asked it immediately again.
unscaled_clock = (diff % ((UInt32)3355443));
} else {
unscaled_clock = diff;
}
//Scale to count value: time
scaled_clock = unscaled_clock * F_CPU / CLOCK_PRESCALER * 1/1000 * 1/1000;
return scaled_clock;
}
Uint32是一個無符號長的typedef。
prev_clock_time_us在board_init()初始化為
//Starts the clock by registering current time, down to microseconds
struct timespec temp;
clock_gettime(CLOCK_MONOTONIC, &temp);
prev_clock_time_us = temp.tv_nsec/1000;
為了測試此代碼,我不斷地將其打印出來。 我期望或希望看到的是時鍾從0-> 65536-> 0大約在3.355s內變化。
相反,我的打印輸出顯示的是時鍾從0->〜20000->0。這很奇怪。 例如,僅打印時,curr_clock_time_us似乎該值從0-> 1.000.000-> 0開始。
觀察發現“ CLOCKS_PER_SEC必須是一百萬”,但我不確定這是否相關。
那么有什么線索我做錯了嗎? 我不確定。
curr_clock_time_us = tv_nsec / 1000以微秒為單位的時間,並且始終小於或等於1.000.000 us = 1 s
您雖然必須使用tv_sec來計算一秒內的時間差。
#include <iostream>
#include <time.h>
#include <unistd.h>
#define F_CPU 16000000
#define CLOCK_PRESCALER 1024
using namespace std;
time_t prev_clock_time_s;
long prev_clock_time_us;
uint32_t getCounter(void){
long diff;
struct timespec temp;
clock_gettime(CLOCK_REALTIME, &temp);
diff = ((temp.tv_sec - prev_clock_time_s) * 1000000) + ((temp.tv_nsec/1000) - prev_clock_time_us);
return (diff % 3355443l) * 65536l / 3355443l;
}
int main()
{
struct timespec temp;
clock_gettime(CLOCK_REALTIME, &temp);
prev_clock_time_s = temp.tv_sec;
prev_clock_time_us = temp.tv_nsec/1000;
for (int i = 0; i < 20; i++)
{
uint32_t cnt = getCounter();
std::cout << "counter_value: " << cnt << " time: " << (cnt * 3.3554432 / 65536) << std::endl;
usleep(300000);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.