对于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 ;
-
}
参考了赵老师的博客,这里表示感谢,博客地址
http://blog.csdn.net/zhaocj/archive/2010/04/05/5452541.aspx
阅读(1773) | 评论(0) | 转发(0) |