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

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 output

	GPX1.CON = GPX1.CON & (~0xF) | 0x1;                 //LED3 GPX1_0 output

	GPF3.CON = GPF3.CON & (~(0xF << 16)) | (0x1 << 16); //LED4 GPF3_4 output

	GPF3.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.kler.cn/a/158831.html

相关文章:

  • 深度学习:卷积神经网络的计算复杂度,顺序操作,最大路径长度
  • ZSTD 内存泄漏问题
  • 数据科学与SQL:如何计算排列熵?| 基于SQL实现
  • 自动化运维(k8s):一键获取指定命名空间镜像包脚本
  • 面试经典 150 题:20、2、228、122
  • 基于Java Springboot编程语言在线学习平台
  • LeetCode22. 括号生成
  • 从一个简单的实际例子看并行处理
  • Python文件打包成exe可执行文件
  • Netty网络编程
  • [Java][项目][战斗逻辑]基于JFrame的文字游戏
  • centos7.5常见的mysql方式
  • springboot075电影评论网站系统设计与实现
  • Python的海龟 turtle 库使用详细介绍(画任意多边形,全网最详细)
  • Oracle:左连接、右连接、全外连接、(+)号详解
  • 实现Linux SSH免密码登录:使用密钥对进行身份验证
  • Python高级数据结构——树(Tree)
  • File类—递归文件搜索执行脚本文件
  • DFT(离散傅里叶变换)的通俗理解
  • NumPy中,数组的类型是 numpy.ndarray
  • YOLOv5项目实战(5)— 算法模型优化和服务器部署
  • Linux进程间通信之共享内存
  • 【C语言:自定义类型(结构体、位段、共用体、枚举)】
  • 语义分割网络-FCN全卷积网络
  • 安装获取mongodb
  • 【原创】提升MybatisPlus分页便捷性,制作一个属于自己的分页插件,让代码更加优雅