Timer 在SAM L21 Explained Pro中,FreeRTOS定时器滴答过快
当我打电话给vTaskDelay时,延迟持续了预期时间的一半。我已经追踪到了问题所在,我发现Tick rate值是configTICK\u rate\u HZ中定义的值的两倍。我使用勾号钩切换led并用示波器测量频率来检查这一点 我正在配置Atmel SAM L21 Explained pro A板(ATSAML21J18A),使用Atmel Studio 7和FreeRTOS v8.0.1,基于名为“FreeRTOS tickless demo using OLED1 Explained”的ASF示例文件 我的CPU时钟从系统时钟源OSC16M以12MHz的频率运行。从GLCK_O(CPU时钟)计时的计时器中,配置的滴答频率为100 Hz。然而,当我将CPU时钟频率改为4MHz而不是12MHz时,滴答声频率是正确的,因此我想我缺少运行OS滴答声的计时器的某些配置 以下是我在不同CPU时钟频率下得到的一些操作系统时钟频率值:Timer 在SAM L21 Explained Pro中,FreeRTOS定时器滴答过快,timer,embedded,atmel,freertos,atmelstudio,Timer,Embedded,Atmel,Freertos,Atmelstudio,当我打电话给vTaskDelay时,延迟持续了预期时间的一半。我已经追踪到了问题所在,我发现Tick rate值是configTICK\u rate\u HZ中定义的值的两倍。我使用勾号钩切换led并用示波器测量频率来检查这一点 我正在配置Atmel SAM L21 Explained pro A板(ATSAML21J18A),使用Atmel Studio 7和FreeRTOS v8.0.1,基于名为“FreeRTOS tickless demo using OLED1 Explained”的A
- CPU:4 MHz-滴答频率:100 Hz
- CPU:8 MHz-滴答频率:548 Hz
- CPU:12 MHz-滴答频率:218 Hz
- CPU:16 MHz-滴答频率:548 Hz
- CPU:48 MHz-滴答频率:2,25 kHz
#define configUSE_PREEMPTION 1
#define configUSE_TICKLESS_IDLE 0
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 1
#define configPRIO_BITS 2
#define configCPU_CLOCK_HZ ( system_gclk_gen_get_hz(GCLK_GENERATOR_0) )
#define configTICK_RATE_HZ ( ( portTickType ) 100 )
滴答定时器配置为:
void vPortSetupTimerInterrupt(void)
{
// Struct for configuring TC
struct tc_config tcconf;
// Set up configuration values
tc_get_config_defaults(&tcconf);
tcconf.clock_source = GCLK_GENERATOR_0;
tcconf.counter_size = TC_COUNTER_SIZE_32BIT;
tcconf.run_in_standby = true;
tcconf.clock_prescaler = TC_CLOCK_PRESCALER_DIV1;
tcconf.wave_generation = TC_WAVE_GENERATION_MATCH_FREQ;
// Initialize the TC
tc_init(&tc, TICK_TC, &tcconf);
// Register and enable callback for freeRTOS tick handler
tc_register_callback(&tc, (tc_callback_t) xPortSysTickHandler, TC_CALLBACK_CC_CHANNEL0);
tc_enable_callback(&tc, TC_CALLBACK_CC_CHANNEL0);
// Set top value equal to one os tick
tc_set_top_value(&tc, TIMER_RELOAD_VALUE_ONE_TICK);
// Enable the timer
tc_enable(&tc);
}
其中计时器\u重新加载\u值\u一个\u勾号来自:
//! Frequency of timer
#define TIMER_HZ ( configCPU_CLOCK_HZ )
//! Value per os tick of timer
#define TIMER_RELOAD_VALUE_ONE_TICK ( TIMER_HZ / configTICK_RATE_HZ )
//! Maximum value of timer
#define TIMER_MAX_COUNT ( 0xffffffff )
//! Maximum possible suppressed ticks with timer
#define TIMER_MAX_POSSIBLE_SUPPRESSED_TICKS ( TIMER_MAX_COUNT / TIMER_RELOAD_VALUE_ONE_TICK )
我将非常感谢任何关于这个计时器问题的见解,这让我陷入困境。我已经检查了与此相关的两个类似问题:
将计时器实例从TC4更改为TC2可以解决此问题
// Initialize the TC
tc_init(&tc, TICK_TC, &tcconf);
//! Timer/Counter instance to use as tick timer
//#define TICK_TC TC4
#define TICK_TC TC2
现在,它独立于配置的CPU时钟频率,生成正确的100 Hz滴答声
然而,当我激活低功耗模式时,我仍然必须看到这将产生的影响,因为似乎TC4是power Domain 0中唯一激活的计时器
(PD0)(最低功率域)。saml21有5个定时器/计数器TC0-TC4。计数寄存器为16位。您可以同时使用TC0和TC1(或TC2和TC3)使其成为32位。PDO中唯一的计时器TC4没有与之配对的另一个计时器。它不能用作32位计时器(尽管它允许您尝试)
将TIMER\u MAX\u COUNT更改为0xffff,将tcconf.counter\u size更改为TC\u counter\u size\u 16位,您将能够使用TC4而不是TC2。我投票将此问题作为主题外的问题来结束,因为:您有调试器-是什么阻止您检查计时器和系统寄存器的值?自己调试一下。若你们付出一些努力,回答这个问题很容易。是的,我完全同意。我一直在使用调试器,并尽我所能检查计时器和频率变量,我已经尝试了所有不同的组合来更改CPU时钟源和频率,以及计时器时钟源。我还检查了滴答声和滴答声模式。我已经查了好几天我能找到的所有记录,但我找不到原因,可能我遗漏了一些明显的东西。在尝试了我所能想到的一切之后,问是我最后的选择。如果您能给我一些建议,我将不胜感激。您确定您的时钟频率定义适合您的硬件吗?您的处理器似乎能够运行48 MHz,可能使用外部时钟的PLL乘法器。我想是的,我使用SYSTEM_clock_SOURCE_OSC16;通过GLCK_0为CPU计时,在SAM L21中,它允许4、8、12和16 MHz模式。使用DFLL或DPLL也可以获得48 MHz。我也尝试过这个CPU频率,滴答频率是2,25千赫。我编辑了问题,添加了一些结果。