裸机系列——2440实时时钟

发布者:WhisperingRain最新更新时间:2022-02-28 来源: eefocus关键字:裸机系列  实时时钟 手机看文章 扫描二维码
随时随地手机看文章

对于2440的实时时钟操作还是比较简单的,难点的地方在于用设置串口通信来控制时钟时钟的读写设置时间和闹铃。但是用串口控制时钟终将只能用于测试,对于产品的话必然要用到显示器,或者lcd或者数码管,不过现代的时钟更加趋向于用lcd 况且能显示更多的信息。


1. 时钟的数据已经存到寄存器中了,只有读取寄存器的值就可以读出时钟,注意当秒钟为0的时候需要重新读取寄存器的值,这里有个一秒的问题。


2.数据的格式为BCD码,用4位二进制表示出十进制数,其本质还是二进制编码。


3. 数据的格式适合用结构体,还有多命令控制时用枚举类型比较好,以后要多用习惯这样的用法。


4.闹铃中断的发生,当设定的闹铃时间和时钟的时间相同时闹铃中断,其中可以有选择的使能year mon date hour min sec ,匹配时从year到sec。例如 只使能分和秒的时候,当时钟的值和设定闹铃的分和秒相同时闹铃中断,即每个小时的多少分多少秒时中断发生。这样一来就可以很灵活的运用闹铃功能了。


代码

enum {idle, write, read} cmd ; //UART control write&read

enum {set, Nset, alarm} settime ; //预设时钟 闹铃

enum {right, wrong} setformat ; //settime format flag

int setcount = -1 ; //用于设定时间闹铃计数

enum {start, end} uartrtcflag ; //串口设定时间闹铃数据开始结束标志

typedef struct time

{

char year ;

char mon  ;

char date ;

char day  ; // day of week

char hour ;

char mini ;

char sec  ;

} RTC ;

char RTCstr[17] = "00-00-00 00:00:00" ;

/***********************************

UART_int初始化led IO端口GPBCON5-8

初始化GPBHCON为串口通信

配置串口通信寄存器

配置中断寄存器

************************************/

void UART_int_init(void)

{

//configuration LED IO port

rGPBCON &= ~(0xff<<10) ;

rGPBCON |= 0x55<<10 ;

//configuration GPHCON to UART

rGPHCON &= ~(0xf<<4) ;

rGPHCON |=  0xa<<4 ;

//rGPHCON = 0x00faaa;

//rGPHUP = 0x7ff ;

//configuration UART0 communication register

//8-bits,1 stop bit, no parity

rULCON0 = 0x03 ;

rUCON0  = 0x05 ;

//configuration UART baudrate

rUBRDIV0= (int)(PCLK/baudrate/16) -1 ;

//clean interrupt bit

rSUBSRCPND |= 0x1 ;

rSRCPND |= 1<<28 ;

rINTPND |= 1<<28 ;

//open UART interrupt

rINTSUBMSK &= ~(0x1) ;

rINTMSK &= ~(0x1<<28) ;

}

void UART_send_byte(char Tx_data)

{

while(!(rUTRSTAT0&0x2)) ;//wait Tx empty

if(Tx_data == '/n') //Tx '/n'

{

rUTXH0 = 0x0d ;

while(!(rUTRSTAT0&0x2)) ;

rUTXH0 = 0x0a ;

}

else

{

rUTXH0 = Tx_data ;

}

}

void UART_send_string(const char *str) 

{

while(*str)

{

UART_send_byte(*str) ;

str++ ;

}

}

char UART_receive_byte(void) 

{

//char temp ;

while(!(rUTRSTAT0&0x1)) ; //wait RX ready

//temp = rURXH0 ;

return rURXH0 ;

}

/*************read RTC***************

read RTC data 

if secend is 0 re-read RTC data 

**************read RTC**************/

void get_rtc(RTC *prtc)

{

rRTCCON = 1 ;

prtc->year = rBCDYEAR ;

prtc->mon = rBCDMON  ;

prtc->date = rBCDDATE ;

prtc->day = rBCDDAY  ;

prtc->hour = rBCDHOUR ;

prtc->mini = rBCDMIN  ;

prtc->sec = rBCDSEC  ;

if(prtc->sec==0) //one secend diviation

{

prtc->year = rBCDYEAR ;

prtc->mon = rBCDMON  ;

prtc->date = rBCDDATE ;

prtc->day = rBCDDAY  ;

prtc->hour = rBCDHOUR ;

prtc->mini = rBCDMIN  ;

prtc->sec = rBCDSEC  ;

}

rRTCCON = 0 ;

}

/******************************************************

convent RTC data to string  

the form : xx-xx-xx xx:xx:xx 

*******************************************************/

void rtc_to_str(char *str_time, RTC *rtctime)

{

//year

str_time[0] = (char)((rtctime->year >> 4) + 48 )  ;

str_time[1] = (char)((rtctime->year & 0x0f) + 48) ;

str_time[2] = '-' ;

//mon

str_time[3] = (char)((rtctime->mon  >> 4) + 48 )  ;

str_time[4] = (char)((rtctime->mon  & 0x0f) + 48) ;

str_time[5] = '-' ;

//date

str_time[6] = (char)((rtctime->date >> 4) + 48 )  ;

str_time[7] = (char)((rtctime->date & 0x0f) + 48) ;

str_time[8] = ' ' ;

//hour

str_time[9] = (char)((rtctime->hour >> 4) + 48 )  ;

str_time[10] = (char)((rtctime->hour & 0x0f) + 48) ;

str_time[11] = ':' ;

//mini

str_time[12] = (char)((rtctime->mini >> 4) + 48 )  ;

str_time[13] = (char)((rtctime->mini & 0x0f) + 48) ;

str_time[14] = ':' ;

//sec

str_time[15] = (char)((rtctime->sec  >> 4) + 48 )  ;

str_time[16] = (char)((rtctime->sec  & 0x0f) + 48) ;

str_time[17] = '/0' ;

}

void str_to_RTC(char *strtime, RTC *rtctime)

{

rtctime->year = ((strtime[0]-48)<<4) + (strtime[1]-48) ;

if(strtime[2] != '-') 

{

setformat = wrong ;

UART_send_string("/n setting time form error please input 's' to re-set") ;

return ;

}

rtctime->mon = ((strtime[3]-48)<<4) + (strtime[4]-48) ;

if(strtime[5] != '-') 

{

setformat = wrong ;

UART_send_string("/n setting time form error please input 's' to re-set") ;

return ;

}

rtctime->date = ((strtime[6]-48)<<4) + (strtime[7]-48) ;

if(strtime[8] != ' ') 

{

setformat = wrong ;

UART_send_string("/n setting time form error please input 's' to re-set") ;

return ;

}

rtctime->hour = ((strtime[9]-48)<<4) + (strtime[10]-48) ;

if(strtime[11] != ':') 

{

setformat = wrong ;

UART_send_string("/n setting time form error please input 's' to re-set") ;

return ;

}

rtctime->mini = ((strtime[12]-48)<<4) + (strtime[13]-48) ;

if(strtime[14] != ':') 

{

setformat = wrong ;

UART_send_string("/n setting time form error please input 's' to re-set") ;

return ;

}

rtctime->sec = ((strtime[15]-48)<<4) + (strtime[16]-48) ;

setformat = right ; //set format right flag 

}

void set_RTC(RTC *prtc)

{

rRTCCON = 1 ;

rBCDYEAR = prtc->year ;

rBCDMON = prtc->mon ;

rBCDDATE = prtc->date  ;

rBCDDAY = prtc->day  ;

rBCDHOUR = prtc->hour  ;

rBCDMIN = prtc->mini  ;

rBCDSEC = prtc->sec  ;

rRTCCON = 0 ;

}

void alarm_init(void)

{

/****clear RTC alarm interrupt pending****/

rSRCPND |= 1<<30 ;

rINTPND |= 1<<30 ;

rINTMSK &= ~(1<<30) ; //open RTC alarm interrupt 

rRTCALM = 0x41 ; //all alarm Enable

}

void set_alarm(RTC *prtc)

{

rRTCCON = 1 ;

rALMYEAR = prtc->year ;

rALMMON = prtc->mon ;

rALMDATE = prtc->date  ;

rALMHOUR = prtc->hour  ;

rALMMIN = prtc->mini  ;

rALMSEC = prtc->sec  ;

rRTCCON = 0 ;

}

void __irq RTC_alarm_interrupt(void)

{

/****clear RTC alarm interrupt pending****/

rSRCPND |= 1<<30 ;

rINTPND |= 1<<30 ;

rINTMSK &= ~(1<<30) ; //open RTC alarm interrupt 

rGPBDAT &= ~(0xf<<5) ; //lighten led

UART_send_string("/nRTC alarm") ;

}

//UART0 interrupt

void __irq UART0_interrupt(void)

{

char value ;

/*********clean interrupt bit*********/

rSUBSRCPND |= 0x1 ; //注意顺序

rSRCPND |= 1<<28 ;

rINTPND |= 1<<28 ;

value = UART_receive_byte();

switch(value)

{

case 'w': //write

cmd = write  ; 

break ;

case 'r': //read

cmd = read  ;

break ;

case 's': //settime

settime = set;

UART_send_string("/n please input settime data bxx-xx-xx xx:xx:xxew") ;

  break ;

  case 'a':

  settime = alarm ; //set alarm

  UART_send_string("/n please input set alarm data bxx-xx-xx xx:xx:xxew") ;

  break ;

  case 'b': // data format bxx-xx-xx xx:xx:xxew

  uartrtcflag = start ;// set alarm start flag

  setcount = -1 ;

  break ;

  case 'e' :

  uartrtcflag = end ;

  setcount = -1 ;

  break ;

  case 't': //turnoff alarm

  rRTCALM = 0 ; //disable RTC alarm

  rINTMSK |= 1<<30 ; //disable RTC alarm interrupt

  break ;

}

if(uartrtcflag==start)

{

if(value != 'b')

{

RTCstr[setcount] = value ;

}

setcount++ ;

}

}

int Main(void)

{

RTC rtcdata ;

MMU_Init();

ChangeMPllValue(127,2,1); //405MHZ

ChangeClockDivider(13,12);  //1:3:6 PCLK 67.5M

UART_int_init();

cmd = idle ; //idle model

settime = Nset ; //NO settime

setformat = wrong ; //NO right setformat 

uartrtcflag = end ; //NO set data transination

pISR_UART0 = (U32)UART0_interrupt ;

pISR_RTC = (U32)RTC_alarm_interrupt ;

while(1)

{

if(cmd==write)

{

cmd = idle ;//clean write model to idle

str_to_RTC(RTCstr, &rtcdata) ;

if(settime==set)

{

settime = Nset ; //设置时间后清除设置标志,防止无意设置

if(setformat==right)

{

setformat = wrong ;

set_RTC(&rtcdata) ;

UART_send_string("/n set RTC time successful") ;

}

}

if(settime==alarm)

{

settime = Nset ; //设置闹铃后清除设置标志,防止无意设置

if(setformat==right)

{

setformat = wrong ;

alarm_init() ; //initial alarm register

set_alarm(&rtcdata) ;

UART_send_string("/n set RTC alarm successful") ;

}

}

}

if(cmd==read)

{

cmd = idle ; //clean read model to idle

get_rtc(&rtcdata) ;

rtc_to_str(RTCstr, &rtcdata) ;

UART_send_string("/n The current time is /t") ;

UART_send_string(RTCstr) ;

}

}

return 0 ;

}



关键字:裸机系列  实时时钟 引用地址:裸机系列——2440实时时钟

上一篇:2440的flash、linux、bootloader
下一篇:裸机系列——IIC

推荐阅读最新更新时间:2024-11-05 11:23

LPC1768 -- RTC实时时钟
RTC是当下设备中比较普遍的一个部件,很多设备都需要查看时间。RTC实时时钟已经在很多的单片机中集成,以前还要专门的时钟芯片,现在Cortex-M3内核都包括了这个部件了。和以前NXP的ARM7内核不同的是,LPC1768的时钟源只有32K时钟源提供,这一点是要注意的,其他和ARM7一致。 RTC其实也就是一个定时,可以理解为秒定时器,RTC寄存器挺多的,不过寄存器结构相对简单,操作起来还是很方便的。 讲解几个重要的寄存器,中断位置寄存器ILR、时钟控制寄存器CCR、计数器增量中断寄存器CIIR、报警屏蔽寄存器AMR 第一个ILR中断位置寄存器 BIT0,当为1时计数器增量模块产生中断。 BIT1,当为1是报警寄存器产生中断
[单片机]
LPC1768 -- RTC<font color='red'>实时时钟</font>
s3c2440裸机-内存控制器(二、不同位宽外设与CPU地址总线的连接)
不同位宽设备的连接 我们先看一下2440芯片手册上外设rom是如何与CPU地址总线连接的。 8bit rom与CPU地址线的连接 8bit*2 rom与CPU地址线的连接 8bit*4 rom与CPU地址线的连接 16bit rom与CPU地址线的连接 16bit*2 rom与CPU地址线的连接 从上面的图中,我们知道可以对2片位宽为8bit的外设扩展级联成1个16bit的外设,同理可用4片位宽为8bit的外设进行级联成1个32bit的外设... 从上面的图中,我们还看见一个规律: 当外设总线位宽为8bit时, 外设A0接CPU的地址总线ADDR , A - ADDR ...A - ADDR 当外设总线
[单片机]
s3c<font color='red'>2440</font><font color='red'>裸机</font>-内存控制器(二、不同位宽外设与CPU地址总线的连接)
S3C2440——使用URAT0查询方式发送和接收字符串
UART初始化函数 void Uart_Init(int pclk,int baud) { int i; rGPHCON|=0xa0; //GPH2,GPH3 as TXD0,RXD0 rGPHUP = 0x0; //GPH2,GPH3内部上拉 if(pclk == 0) pclk = PCLK; rUFCON0 = 0x0; //禁止3个通道的FIFO控制寄存器 rUFCON1 = 0x0; rUFCON2 = 0x0; rUMCON0 = 0x0; rUMCON1 = 0x0; rUMCON2 = 0x0; //初始化3个通道的MODEM控制寄存器,禁止AFC //Lin
[单片机]
S3C2440 IIC总线接口
s3c2440内部有一个IIC总线接口,因此为我们连接带有IIC通信模块的外围设备提供了便利。它具有四种操作模式:主设备发送模式、主设备接收模式、从设备发送模式和从设备接收模式。 在这里只把s3c2440当做IIC总线的主设备来使用,因此只介绍前两种操作模式。在主设备发送模式下,它的工作流程为:首先配置IIC模式,然后把从设备地址写入接收发送数据移位寄存器IICDS中,再把0xF0写入控制状态寄存器IICSTAT中,这时等待从设备发送应答信号,如果想要继续发送数据,那么在接收到应答信号后,再把待发送的数据写入寄存器IICDS中,清除中断标志后,再次等待应答信号;如果不想再发送数据了,那么把0x90写入寄存器IICSTAT中
[单片机]
S3C<font color='red'>2440</font> IIC总线接口
s3c2440裸机-电阻触摸屏编程(4.isr设计_4.1获取触摸屏坐标)
1.进入自动测量模式 上一节介绍了TSC的初始化,以及中断服务程序框架,能够对的触摸屏进行基本的按下松开检测。 那让bit =1, bit =00,则会进入auto measurement。如果bit =0,则需配置bit =01 or 10是手动测量x,y坐标。 #define AUTO_PST (1 2) /*自动转换*/ #define WAIT_INT_MODE (3) /*等待中断模式*/ #define NO_OPR_MODE (0) /*禁止模式*/ void enter_auto_measure_mode(void) {   ADCTSC = AUTO_PST | NO_OPR_M
[单片机]
s3c<font color='red'>2440</font><font color='red'>裸机</font>-电阻触摸屏编程(4.isr设计_4.1获取触摸屏坐标)
基于S3C2440的Linux内核移植和yaffs2文件系统制作--启动系统
第三章 启动系统 将前面两章生成的内核映像文件和根文件系统映像文件下载到mini2440开发板,查看启动信息。我成功移植启动信息如下: VIVI version 0.1.4 ( root@capcross ) (gcc version 2.95.3 20010315 (release)) #0.1.4 Mon Oct 27 10:18:15 CST 2008 MMU table base address = 0x33DFC000 Succeed memory mapping. DIVN_UPLL0 MPLLVal CLKDIVN:5h +------------------------------------------
[单片机]
OpenCV2.0.0移植到ARM9(一)(JZ2440----S3c2440
Linux系统:Ubuntu9.10 交叉编译器:arm-linux-gcc-4.3.2(已安装) OpenCV:OpenCV-2.0.0.tar.bz2(OpenCV for Linux/Mac) CMake:cmake-2.8.12-Linux-i386.tar.gz 1、OpenCV解压 将OpenCV-2.0.0.tar.bz2放到/work/systems/下。 解压命令: tar -jxvf OpenCV-2.0.0.tar.bz2 2、CMake解压: 将cmake-2.8.12-Linux-i386.tar.gz放到/work/tools/目录下 解压命令 :tar -zxv
[单片机]
OpenCV2.0.0移植到ARM9(一)(JZ<font color='red'>2440</font>----S3c<font color='red'>2440</font>)
【菜鸟入门】stm32 之 实时时钟
经过这么10天的瞎搞,我的库已经初具规模了,于是,不用每次都把所有的文件copy过去,直接在Option里面把path给加上就ok了。 RTC的时钟配置,RTC的时间寄存器是2个32位的寄存器,无非就是一个计数器,大概可以这样理解吧,我们先看看时钟吧 RTC的时钟可以从这3路来,我们需要PTCSEL寄存器来进行设置, 上面这个图是摘自李想老师的课件里面的,我觉得这个是做的相对好的! 位了保证RTC正常工作,我们需要在系统断电时,RTC不受影响,当然我们一般都需要接一个Battery,作为rtc的后备电源,这里设计到电源管理,我们先来看看电源管理里面关于rtc的 只要我们把第八位置1我们就可以对其进行正常供电,我
[单片机]
【菜鸟入门】stm32 之 <font color='red'>实时时钟</font>
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved