Exynos_4412——RTC实验

目录

一、ADC小作业

二、RTC简介

三、Exynos_4412下的RTC控制器

四、RTC中的寄存器

五、RTC编程

六、RTC小作业


一、ADC小作业

电压在1501mv~1800mv时,LED2、LED3、LED4、LED5点亮
电压在1001mv~1500mv时,LED2、LED3、LED4点亮
电压在501mv~1000mv时,LED2、LED3点亮
电压在0mv~500mv时,LED2闪烁

LED电路图和寄存器:

C工程与寄存器封装_宇努力学习的博客-CSDN博客

ADC电路图和寄存器:

Exynos_4412——ADC实验_宇努力学习的博客-CSDN博客

#include "exynos_4412.h"


void delay(unsigned int time)
{
	while(time --);
}

int main()
{
    unsigned int adc_value;
	unsigned int n = 0;
    //12
    ADCCON = ADCCON | (1 << 16);
    //使能ADC分频器
    ADCCON = ADCCON | (1 << 14);
    //100/(19+1)=5MHz 5 / 5 = 1MHz
    ADCCON = ADCCON & (~(0xFF << 6)) | (19 << 6);
    //关闭待机模式
    ADCCON = ADCCON & (~(1 << 2));
    //关闭通过读使能AD转换
    ADCCON = ADCCON & (~(1 << 1));

    ADCMUX = 3;

	GPX2.CON = GPX2.CON & (~(0xF << 28)) | (0x1 << 28);
	GPX1.CON = GPX1.CON & (~(0xF)) | (0x1);
	GPF3.CON = GPF3.CON & (~(0xFF << 16)) | (0x11 << 16);

    while(1)
    {
        //开始
        ADCCON = ADCCON | 1;
        while(!(ADCCON & (1 << 15)));
        //读取
        adc_value = ADCDAT & 0xFFF;
        // 1800mV/2^12=1800/4096=0.44
        adc_value = adc_value * 0.44;
		if(adc_value >= 0 & adc_value <= 500)
			n = 1;
		if(adc_value >= 501 & adc_value <= 1000)
			n = 2;
		if(adc_value >= 1001 & adc_value <= 1500)
			n = 3;
		if(adc_value >= 1501 & adc_value <= 1800)
			n = 4;
		switch(n)
		{
			case 1:
				GPX2.DAT = GPX2.DAT | (1 << 7);//LED2_ON
				delay(1000000);
				GPX2.DAT = GPX2.DAT & (~(1 << 7));//LED2_OFF
				delay(1000000);
				GPX1.DAT = GPX1.DAT & (~1);//LED3_OFF
				GPF3.DAT = GPF3.DAT & (~(1 << 4));//LED4_OFF
				GPF3.DAT = GPF3.DAT & (~(1 << 5));//LED5_OFF
				break;
			case 2:
				GPX2.DAT = GPX2.DAT | (1 << 7);//LED2_ON	
				GPX1.DAT = GPX1.DAT | 1;//LED3_ON
				GPF3.DAT = GPF3.DAT & (~(1 << 4));//LED4_OFF
				GPF3.DAT = GPF3.DAT & (~(1 << 5));//LED5_OFF
				break;
			case 3:
				GPX2.DAT = GPX2.DAT | (1 << 7);//LED2_ON
				GPX1.DAT = GPX1.DAT | 1;//LED3_ON
				GPF3.DAT = GPF3.DAT | (1 << 4);//LED4_ON
				GPF3.DAT = GPF3.DAT & (~(1 << 5));//LED5_OFF
				break;
			case 4:
				GPX2.DAT = GPX2.DAT | (1 << 7);//LED2_ON
				GPX1.DAT = GPX1.DAT | 1;//LED3_ON
				GPF3.DAT = GPF3.DAT | (1 << 4);//LED4_ON
				GPF3.DAT = GPF3.DAT | (1 << 5);//LED5_ON
				break;
			default:
				GPX2.DAT = GPX2.DAT & (~(1 << 7));//LED2_OFF
				GPX1.DAT = GPX1.DAT & (~1);//LED3_OFF
				GPF3.DAT = GPF3.DAT & (~(1 << 4));//LED4_OFF
				GPF3.DAT = GPF3.DAT & (~(1 << 5));//LED5_OFF
				break;
		}

        printf("adc_value = %d mV\n",adc_value);
    }
    return 0;
}

二、RTC简介

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

比如以前的手机,扣掉电池在安上时间就不准了,而现在的电子产品不会出现这个问题是因为他有备用电源。由于它只有一个RTC电路所以功耗很低,一般都是一个小的纽扣电池甚至一个电容就够了。

三、Exynos_4412下的RTC控制器

4412下的RTC还支持闹钟功能

它支持BCD number 年月日、星期、时分秒

https://baike.baidu.com/item/BCD%E7%A0%81/826461?fromtitle=bcd&fromid=13009167&fr=aladdin

举个栗子:

12 用二进制表示是   1100    用BCD码表示就是       0001  0010

支持闰年

支持告警功能即闹钟中断和低功耗模式 低功耗包括:空闲、深度空闲、停止、深度停止、休眠

支持滴答定时器,

支持独立电源引脚(RTCVDD)

滴答定时器还支持实时操作系统工作

这些东西32用的比较多,4412一般只用它来获取时间

32.768KHz的时钟 经过一个2^15的分频器(32768)就获得了一个1Hz的时钟,来给秒使用

四、RTC中的寄存器

 它有三块,用BCD码分别表示百位十位和个位,千位默认是2就行,估计这个单片机都用不到3开头那年。或者我也活不到那个时候啊,哈哈哈

 

 

 注意:  三星把星期和日的地址写反了

 

对于RTCCON这个寄存器我们只需要关注他的第0位就行,其它位使用默认设置。

这其实就是一把锁,只有把锁打开了我们才能修改时间,这是为了防止有些野指针,把内容修改了。

五、RTC编程

还是先解压一个工程

由于板子并没有备用电源,所以我们要先校准一下时间:

由于BCD转化成10进制看起来怪怪的,所以我们要写一个转化函数,这里我偷懒一下,以为16进制和BCD需要转化的10进制刚好相等,直接写16进制数

同样读取的时候也需要我们写这样一个转化函数,这里再偷个懒

#include "exynos_4412.h"

int main()
{
    //使能RTC控制
    RTCCON = RTCCON | 1;
    //校准时间
    RTC.BCDYEAR = 0x023; //000000100011  2023
    RTC.BCDMON  = 0x1;   //1
    RTC.BCDDAY  = 0x5;   //5
    RTC.BCDWEEK = 0x4;   //星期四
    RTC.BCDHOUR = 0x11;  //11
    RTC.BCDMIN  = 0x32;  //32
    RTC.BCDSEC  = 0x50;  //50s

    //关闭RTC控制
    RTCCON = RTCCON & 0;

    while(1)
    {
        printf("%x-%x-%x %x %x:%x:%x\n",RTC.BCDYEAR,RTC.BCDMON,RTC.BCDDAY,RTC.BCDWEEK,RTC.BCDHOUR,RTC.BCDMIN,RTC.BCDSEC);
    }

	return 0;
}

 但是程序跳动的太快了,所以我们改一下让他一秒钟打印一次

#include "exynos_4412.h"

int main()
{
	unsigned int Oldsec = 0, Newsec = 0;
    //使能RTC控制
    RTCCON = RTCCON | 1;
    //校准时间
    RTC.BCDYEAR = 0x023; //000000100011  2023
    RTC.BCDMON  = 0x1;   //1
    RTC.BCDDAY  = 0x5;   //5
    RTC.BCDWEEK = 0x7;   //星期四
    RTC.BCDHOUR = 0x11;  //11
    RTC.BCDMIN  = 0x32;  //32
    RTC.BCDSEC  = 0x50;  //50s

    //关闭RTC控制
    RTCCON = RTCCON & 0;

    while(1)
    {
		Newsec = RTC.BCDSEC;
		if(Newsec != Oldsec)
		{
        	printf("%x-%x-%x %x %x:%x:%x\n",RTC.BCDYEAR,RTC.BCDMON,RTC.BCDDAY,RTC.BCDWEEK,RTC.BCDHOUR,RTC.BCDMIN,RTC.BCDSEC);
		
			Oldsec = Newsec;				

		}   
	}

	return 0;
}

 手动填个20看起来更好看一些

六、RTC小作业

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

#include "exynos_4412.h"

void RTC_Init()
{
	//使能RTC控制
    RTCCON = RTCCON | 1;
    //校准时间
    RTC.BCDYEAR = 0x023; //000000100011  2023
    RTC.BCDMON  = 0x1;   //1
    RTC.BCDDAY  = 0x5;   //5
    RTC.BCDWEEK = 0x4;   //星期四
    RTC.BCDHOUR = 0x11;  //11
    RTC.BCDMIN  = 0x32;  //32
    RTC.BCDSEC  = 0x50;  //50s

    //关闭RTC控制
    RTCCON = RTCCON & 0;

}
void ADC_Init()
{
	//12
    ADCCON = ADCCON | (1 << 16);
    //使能ADC分频器
    ADCCON = ADCCON | (1 << 14);
    //100/(19+1)=5MHz 5 / 5 = 1MHz
    ADCCON = ADCCON & (~(0xFF << 6)) | (19 << 6);
    //关闭待机模式
    ADCCON = ADCCON & (~(1 << 2));
    //关闭通过读使能AD转换
    ADCCON = ADCCON & (~(1 << 1));

    ADCMUX = 3;

}
void LED_Init()
{
	GPX2.CON = GPX2.CON & (~(0xF << 28)) | (0x1 << 28);
	GPX1.CON = GPX1.CON & (~(0xF)) | (0x1);
	GPF3.CON = GPF3.CON & (~(0xFF << 16)) | (0x11 << 16);
}
int main()
{
	unsigned int Oldsec = 0, Newsec = 0;	
	unsigned int adc_value;
	unsigned int n = 0;
	unsigned int flag = 1;
    RTC_Init();
	ADC_Init();
	LED_Init();

    while(1)
    {
		Newsec = RTC.BCDSEC;
		//开始
        ADCCON = ADCCON | 1;
        while(!(ADCCON & (1 << 15)));
        //读取
        adc_value = ADCDAT & 0xFFF;
        // 1800mV/2^12=1800/4096=0.44
        adc_value = adc_value * 0.44;
		if(adc_value >= 0 & adc_value <= 500)
			n = 1;
		if(adc_value >= 501 & adc_value <= 1000)
			n = 2;
		if(adc_value >= 1001 & adc_value <= 1500)
			n = 3;
		if(adc_value >= 1501 & adc_value <= 1800)
			n = 4;
		switch(n)
		{
			case 1:								
				GPX1.DAT = GPX1.DAT & (~1);//LED3_OFF
				GPF3.DAT = GPF3.DAT & (~(1 << 4));//LED4_OFF
				GPF3.DAT = GPF3.DAT & (~(1 << 5));//LED5_OFF
				if(Newsec != Oldsec)
				{
					if(flag == 1)
					{
        				printf("20%x-%x-%x %x %x:%x:%x  adc_value = %d mV\n",RTC.BCDYEAR,RTC.BCDMON,RTC.BCDDAY,RTC.BCDWEEK,RTC.BCDHOUR,RTC.BCDMIN,RTC.BCDSEC,adc_value);
						GPX2.DAT = GPX2.DAT | (1 << 7);//LED2_ON
						flag = 0;						
					}else{
						GPX2.DAT = GPX2.DAT & (~(1 << 7));//LED2_OFF
						printf("20%x-%x-%x %x %x:%x:%x  adc_value = %d mV\n",RTC.BCDYEAR,RTC.BCDMON,RTC.BCDDAY,RTC.BCDWEEK,RTC.BCDHOUR,RTC.BCDMIN,RTC.BCDSEC,adc_value);
						flag = 1;
					}	
					Oldsec = Newsec;			
				} 
				break;
			case 2:
				GPX2.DAT = GPX2.DAT | (1 << 7);//LED2_ON	
				GPX1.DAT = GPX1.DAT | 1;//LED3_ON
				GPF3.DAT = GPF3.DAT & (~(1 << 4));//LED4_OFF
				GPF3.DAT = GPF3.DAT & (~(1 << 5));//LED5_OFF
				break;
			case 3:
				GPX2.DAT = GPX2.DAT | (1 << 7);//LED2_ON
				GPX1.DAT = GPX1.DAT | 1;//LED3_ON
				GPF3.DAT = GPF3.DAT | (1 << 4);//LED4_ON
				GPF3.DAT = GPF3.DAT & (~(1 << 5));//LED5_OFF
				break;
			case 4:
				GPX2.DAT = GPX2.DAT | (1 << 7);//LED2_ON
				GPX1.DAT = GPX1.DAT | 1;//LED3_ON
				GPF3.DAT = GPF3.DAT | (1 << 4);//LED4_ON
				GPF3.DAT = GPF3.DAT | (1 << 5);//LED5_ON
				break;
			default:
				GPX2.DAT = GPX2.DAT & (~(1 << 7));//LED2_OFF
				GPX1.DAT = GPX1.DAT & (~1);//LED3_OFF
				GPF3.DAT = GPF3.DAT & (~(1 << 4));//LED4_OFF
				GPF3.DAT = GPF3.DAT & (~(1 << 5));//LED5_OFF
				break;
		}  
	}
	return 0;
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宇努力学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值