我希望(粗略地)用C模拟Atmega128的T / C1 这是一个16位计数器,时钟频率为20MHz(F_CPU)。我想要一个1024的预分频(CLOCK_PRESCALER)。
我目前的实施如下:
// 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 unsigned long。
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需要100万”,但我不确定这是否相关。
所以任何线索我做错了什么?我完全不确定。
答案 0 :(得分:0)
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);
}
}