当前位置: 首页 > news >正文

lv11 嵌入式开发 RTC 17

目录

1 RTC简介

​编辑2 Exynos4412下的RTC控制器

2.1 概述

2.2 特征

2.3 功能框图

3 寄存器介绍

3.1 概述

3.2 BCD格式的年月日寄存器

3.3 INTP中断挂起寄存器

3.4 RTCCON控制寄存器 

3.5 CURTICCNT 作为嘀嗒定时器使用的寄存器

4 RTC编程

5 练习


1 RTC简介

RTC(Real Time Clock)即实时时钟,它是一个可以为系统提供精确的时间基准的元器件,RTC一般采用精度较高的晶振作为时钟源,有些RTC为了在主电源掉电时还可以工作,需要外加电池供电

2 Exynos4412下的RTC控制器

2.1 概述

实时时钟(RTC)单元可以在系统断电时使用备用电池进行运行。尽管电源关闭,备用电池可以存储秒、分钟、小时、星期几、日期、月份和年份的时间数据。RTC单元与外部32.768 kHz晶体一起工作,并执行报警功能。 

2.2 特征

 

  •  支持BCD数字,即秒、分钟、小时、星期几、日期、月份和年份。
  •  支持闰年生成器。
  •  支持报警功能,即报警中断或从电源关闭模式唤醒。电源关闭模式有:空闲、深度空闲、停止、深度停止和睡眠。
  •  支持计时器功能,即计时器中断或从电源关闭模式(空闲、深度空闲、停止、深度停止和睡眠)唤醒。
  •  支持独立电源引脚(RTCVDD)。
  •  支持毫秒级滴答时间中断,以供RTOS内核时间滴答使用。 

注:BCD码 即4位二进制表示一位十进制数。如12,0001 0010

2.3 功能框图

clock divider分配器,分频系数是2^15=32768正好提供1hz,相当于1秒给秒使用。

其余内容不详细介绍,主要是对晶振、引脚、瑞年计数器等介绍。

3 寄存器介绍

3.1 概述

INTP 中断挂起计时器

RTCCON 控制寄存器

TICCNT 作为嘀嗒定时器时使用的寄存器(主要是RTOS时候会使用,其余不太用)

RTCALM 闹铃控制寄存器

ALM寄存器是主要闹钟的寄存器

BCD寄存器是最主要的使用时间的寄存器。

CURTICCNT 作为嘀嗒定时器使用的寄存器(一般不太使用)

3.2 BCD格式的年月日寄存器

注意:芯片手册中星期与日的寄存器地址写反了,需要兑换一下,闹钟与时钟的寄存器一样不详细介绍

星期:2位标识1-7

 例

日:[5:4]位标识日的十位,[3:0]位表示日的个位

月:[4]位表示月份十位,[3:0]位表示月份个位 

年:例2023中,寄存器只可记录023即最大到百位,对应[11:0]位,3个BCD码二进制数。

3.3 INTP中断挂起寄存器

3.4 RTCCON控制寄存器 

 

CTLEN:1使能RTC,0关闭RTC。要去修改时间,需要先使能RTC,否则修改不了时间。

3.5 CURTICCNT 作为嘀嗒定时器使用的寄存器

4 RTC编程

interface.c

#include "exynos_4412.h"int main()
{unsigned int OldSec = 0, NewSec = 0;/*使能RTC控制*/RTCCON = RTCCON | 1;/*校准时间信息*/RTC.BCDYEAR = 0x023;RTC.BCDMON  = 0x12;RTC.BCDDAY  = 0x7;RTC.BCDWEEK = 0x31;RTC.BCDHOUR = 0x23;RTC.BCDMIN  = 0x59;RTC.BCDSEC  = 0x50;/*禁止RTC控制*/RTCCON = RTCCON &  (~(1));while(1){NewSec = RTC.BCDSEC;if(OldSec != NewSec){printf("20%x-%x-%x %x %x:%x:%x\n",RTC.BCDYEAR, RTC.BCDMON, RTC.BCDWEEK, RTC.BCDDAY, RTC.BCDHOUR, RTC.BCDMIN, RTC.BCDSEC);	OldSec = NewSec;}}return 0;
}

注:改进部分,可以写一个int int_to_bcd(int time)格式的函数

5 练习

编程实现通过LED状态显示当前电压范围,并打印产生低压警报时的时间

注:
电压在1501mv~1800mv时,LED2、LED3、LED4、LED5点亮
电压在1001mv~1500mv时,LED2、LED3、LED4点亮
电压在501mv~1000mv时,LED2、LED3点亮
电压在0mv~500mv时,LED2闪烁,且每隔一秒钟向终端打印一次当前的电压值及当前的时间

代码

#include "exynos_4412.h"void Delay(unsigned int Time){while(Time--);}void Led_init(void)
{GPX2.CON = GPX2.CON & (~(0xF << 28)) | (0x1 << 28); //LED2 GPX2_7 outputGPX1.CON = GPX1.CON & (~0xF) | 0x1;                 //LED3 GPX1_0 outputGPF3.CON = GPF3.CON & (~(0xF << 16)) | (0x1 << 16); //LED4 GPF3_4 outputGPF3.CON = GPF3.CON & (~(0xF << 20)) | (0x1 << 20); //LED5 GPF3_5 output
}void Led_on(int num){switch(num){case 2:GPX2.DAT = GPX2.DAT | (1 << 7);case 3:GPX1.DAT = GPX1.DAT | (1 << 0);case 4:GPF3.DAT = GPF3.DAT | (1 << 4);case 5:GPF3.DAT = GPF3.DAT | (1 << 5);default:break;}}void Adc_init(void)
{/*设置ADC精度为12bit*/ADCCON = ADCCON | (1 << 16);/*使能ADC分频器*/ADCCON = ADCCON | (1 << 14);/*设置ADC分频值 ADC时钟频率=PLCK/(19+1)=5MHZ ADC转换频率=5MHZ/5=1MHZ*/ADCCON = ADCCON & (~(0xFF << 6)) | (19 << 6);/*关闭待机模式,使能正常模式*/ADCCON = ADCCON & (~(1 << 2));/*关闭通过读使能AD转换*/ADCCON = ADCCON & (~(1 << 1));/*选择转换通道,3通道*/ADCMUX = 3;
}void Led_off(int num){switch(num){case 2:GPX2.DAT = GPX2.DAT & ~(1 << 7);case 3:GPX1.DAT = GPX1.DAT & ~(1 << 0);case 4:GPF3.DAT = GPF3.DAT & ~(1 << 4);case 5:GPF3.DAT = GPF3.DAT & ~(1 << 5);default:break;}}int main(){unsigned int AdcValue;unsigned int OldSec = 0, NewSec = 0;Adc_init();Led_init();/*使能RTC控制*/RTCCON = RTCCON | 1;/*校准时间信息*/RTC.BCDYEAR = 0x023;RTC.BCDMON  = 0x12;RTC.BCDDAY  = 0x7;RTC.BCDWEEK = 0x31;RTC.BCDHOUR = 0x23;RTC.BCDMIN  = 0x59;RTC.BCDSEC  = 0x50;/*禁止RTC控制*/RTCCON = RTCCON &  (~(1));while(1){/*开始转换*/ADCCON = ADCCON | 1;/*等待转换完成*/while(!(ADCCON & (1 << 15)));/*读取转换结果*/AdcValue = ADCDAT & 0xFFF;/*将结果转换成实际的电压值mv*/AdcValue = AdcValue * 0.44;NewSec = RTC.BCDSEC;if((AdcValue >= 0) && (AdcValue <= 500)){Led_on(2);Led_off(3);Led_off(4);Led_off(5);/*打印转换结果*/if(OldSec != NewSec){printf("20%x-%x-%x %x %x:%x:%x,AdcValue = %dmv\n",RTC.BCDYEAR, RTC.BCDMON, RTC.BCDWEEK, RTC.BCDDAY, RTC.BCDHOUR, RTC.BCDMIN, RTC.BCDSEC,AdcValue);	OldSec = NewSec;}}else if ((AdcValue > 500) && (AdcValue <= 1000)){Led_on(2);Led_on(3);Led_off(4);Led_off(5);}else if ((AdcValue > 1000) && (AdcValue <= 1500)){Led_on(2);Led_on(3);Led_on(4);	Led_off(5);	}else if((AdcValue > 1500) && (AdcValue <= 1800)){Led_on(2);Led_on(3);Led_on(4);	Led_on(5);}}return 0;}

实验效果

http://www.lryc.cn/news/253216.html

相关文章:

  • c语言指针详解(上)
  • 如何删除mac苹果电脑上面的流氓软件?
  • WordPress(11)给文章添加预计阅读时长
  • 周周爱学习之快速排序
  • 国产接口测试工具APIpost
  • MySQL电商管理系统练习题及答案
  • 每日3道PWN(第二天)
  • SAP STMS传输请求
  • L1-009:N个数求和
  • 当发送“Hello,World”时,channel发生了什么?
  • 服务器运行情况及线上排查问题常用命令
  • Hadoop学习笔记(HDP)-Part.18 安装Flink
  • LeetCode56. 合并区间
  • 解决typescript报错:找不到名称xxx
  • UVM中封装成agent
  • OSI七层模型与TCP/IP四层模型
  • QT 中 QProgressDialog 进度条窗口 备查
  • 学习ShardingSphere前置知识
  • 读书笔记-《数据结构与算法》-摘要3[选择排序]
  • Arduino驱动MLX90614红外测温传感器(温湿度传感器)
  • Ubuntu上传文件到SMB共享文件夹
  • 【Linux】基础IO--重定向理解Linux下一切皆文件缓冲区
  • RINEX介绍
  • ROS-ROS通信机制-服务通信
  • chown和chmod
  • 【GPU】linux 安装、卸载 nvidia 显卡驱动、cuda 的官方文档、推荐方式(runfile)
  • 6页手写笔记总结信号与系统常考知识大题知识点
  • Qt-QSplitter正确设置比例
  • 一篇吃透大厂面试题,2024找工作一帆风顺。
  • 【1day】用友 U8 Cloud系统TaskTreeQuery接口SQL注入漏洞学习