簡體   English   中英

在C語言中使用20Mhz時鍾和1024個預分頻器實現/模擬16位計數器

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM