ATtiny817 中的时钟控制器负责处理所有与时钟相关的操作。以下是时钟控制器的一些功能
我将使用 20MHz 和 32.768KHz 的内部振荡器(如果某些功能需要)。预分频器可用于根据需要划分时钟。
时钟图如下所示
蓝线用于内部20MHz时钟源,绿线用于内部32.768KHz CLK源。我们可以使用这 2 个振荡器对一切进行计时。
在今天的教程中,我们将闪烁 LED,因此我将使用内部 20MHz 振荡器。
时钟控制部分的第一个寄存器是主时钟控制 A (MCLKCTRLA)
要设置内部20MHz振荡器,我们需要将0写入MCLKCTRLA寄存器的CLKSL (1:0)位。此外,寄存器的第 7 位会配置是否需要 CLKOUT 引脚上的时钟输出。我保持它为 0,因为我不需要时钟输出。
此寄存器具有配置更改保护 (CCP)。这意味着我们不能将数据直接写入寄存器。我们需要使用 _PROTECTED_WRITE 函数进行编写,如下图所示。
void clkInit(void)
{
_PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, 0); // Internal 20MHz OSC, CLKOUT=0
我为时钟配置创建了一个新函数 clkInit。此外,我正在配置值为 0 的 MCLKCTRLA 寄存器。
下一个寄存器是主时钟控制 B (MCLKCTRLB)。该寄存器可用于控制主时钟的预分频器。预分频器进一步将时钟与振荡器分开,并根据用户的要求进行设置。
此寄存器的第 0 位 (PEN) 启用/禁用预分频器。我通过将位设置为 1 来启用预分频器。
PDIV 位 (4:1) 用于设置预分频器值。我们内部振荡器的主时钟为20MHz。我正在使用 4 的预分频器将主时钟降低到 20/4=5MHz。
要将预分频器设置为 4,我们需要将 0x1 写入 PDIV 位,要启用预分频器,我们需要将 1 写入 PEN 位。我们该寄存器的最终数据是 0 0 0 1 1(0x03)。
_PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, 0x03); // PEN=1, DIV=4
接下来,我们对主时钟状态寄存器(MCLKSTATUS)感兴趣。该寄存器可用于检查各种振荡器的状态。
对于20MHz的内部振荡器,位OSC20MS(位4)指示振荡器是否稳定。 我们将等待此位设置为 1,以确保振荡器稳定。 while ((CLKCTRL.MCLKSTATUS & (1<<4)) == 0); // wait for the osc to stabilize.
}
|