SAM4E的可以计数的时钟很多,其中有个RTT(Real-time Timer)实时时钟,它是32位的计数器,他可以可编程的16位的预分频器,有两个时钟源选择,分别是慢时钟SCLK(32.768K)和RTC_1HZ(1HZ),分别就是系统时钟和1HZ的RTC。还有闹钟中断的功能,相当的强大。如手册部分截图概要:
下图是RTT的大概框图:
这个图可以很直观的看出他的时钟来源有两部分:SCLK和RTC1HZ,一旦选择RTC1HZ,计一次数就是1s了。
在RTT有几个比较重要的寄存器,一个是RTT_VR(Real-time Timer Value Register);从手册的说明可以知道,这个寄存器是要读取两次的,这是为了读取的数据稳定和正确。如下手册的截图:
还有RTT_VR寄存器是一个32位的,所以就可以说明这个计数器可以从0一直计数到2的32次方,这个数字是个天文数字了,如果按照一秒计数一次来算,可以计数超过136年,我也是醉了,还有一点要注意的是RTT_MR这个寄存器的复位值是0x8000,十进制就是32.768K,刚好这个值就是低RTT_MR的低十六位的值,也就是预分频寄存器(RTPRES)的值,这就是一上电时啥也不做,RTT的时钟源(如果RTT的时钟源选择SCLK)SCLK(32.768K)进行32768分频,刚好就是1HZ,效果等同于RTC1HZ,所以要避免这种写法RTT->RTT_MR | = RTT_MR_RTTRST | 24;这样一写原想24分频的目的就达不到了,反而变成了32768+24分频了,正确的写法是RTT->RTT_MR = RTT_MR_RTTRST | 24;写法还有其他,反正就是要把RTT_MR的第15位的影响要去除。如手册截图下的说明:
还有一个是时选择控制在RTT_MR寄存器中的RTC1HZ位,如下手册的说明:
还有下面的提示这个RTC1HZ这能写,不可以读,RTT_MR寄存器其他位均可读写。
下面我用寄存器的方式配置下RTT时钟,代码很简单。首先我这里用寄存器写个利用RTT实现一个定时器。
- int32_t value;
- void RTT_Init()
- {
-
- RTT->RTT_MR = RTT_MR_RTTRST | 32 ;
-
- }
- void RTT_1HZ_Init()
- {
-
-
- RTT->RTT_MR = RTT_MR_RTTRST;
- RTT->RTT_MR = RTT_MR_RTC1HZ;
-
- }
- int32_t Get_RTT_Value()
- {
- int32_t value;
- value = RTT->RTT_VR;
- while(value == RTT->RTT_VR);
- return value;
- }
- void Clear_RTT_Value()
- {
- RTT->RTT_MR = RTT_MR_RTTRST | 32 ;
- }
- void delayms(int32_t ms)
- {
-
- while(value < ms)
- {
- value = Get_RTT_Value();
-
- }
- value = 0;
- Clear_RTT_Value();
- }
- int main (void)
- {
-
-
-
- sysclk_init();
-
- board_init();
- RTT_Init();
-
- value = Get_RTT_Value();
- while (1)
- {
-
- delayms(100);
- ioport_toggle_pin_level(PIO_PD22_IDX);
-
- }
- }
复制代码附上源代码:
附上视频链接: