RTC與UART實習 RTC與LCD實習 RTC中斷實習
/******************RTC與UART範例程式***********************************
*檔名︰RTC1.C
*功能︰RTC進行計時,並由UART0發射到電腦,同時令LED1每秒閃爍一次。
*模擬:開啟RTC及Serial#1視窗,快速執行,觀察其時間的變化
*操作:在電腦使用超級終端機,設定115200-bps,接收RTC時間顯示出來
************************************************************************/
#include "LPC2106.h"
uint8 send_buf[20]; // UART0資料接收緩衝區
/************************************************************************
* 名稱︰ISendBuf()
* 功能︰將緩衝區的資料發射到電腦。
* 進入參數︰buf=資料緩衝區,no=發射資料數
***************************************************************************/
void ISendBuf(uint8 const *buf, uint8 no)
{ uint8 i;
for(i=0; i<no; i++)
{
U0THR=buf[i]; // 向UART0串列埠發射1-byte資料
while((U0LSR & THRE)==0); // 若THRE=0,等待資料發射完畢
}
}
/****************************************************************************
* 名稱︰SendTime()
* 功能︰讀取RTC的時間值,由UART0發射到電腦顯示
****************************************************************************/
void SendTime(void)
{ uint8 const MESSAGE[]= "RTC現在日期: "; //在電腦上顯示訊息
uint16 Time;
Time = (CTIME1 >> 16); // 取得“年“的值
send_buf[0] = Time / 1000+'0'; // 存入年千位數
send_buf[1] = Time % 1000/100+'0'; // 存入年百位數
send_buf[2] = Time % 100/10+'0'; // 存入年十位數
send_buf[3] = Time % 10+'0'; // 存入年個位數
send_buf[4] = '-'; // 存入“:“
Time = (CTIME1 >> 8) & 0x3F; // 取得“月“的值
send_buf[5] = Time/10+'0'; // 存入月十位數
send_buf[6] = Time%10+'0'; // 存入月個位數
send_buf[7] = '-'; // 存入“:“
Time = CTIME1 & 0x3F; // 取得“日“的值
send_buf[8] = Time/10+'0'; // 存入日十位數
send_buf[9] = Time%10+'0'; // 存入日個位數
send_buf[10] = '-'; // 存入“:“
Time = (CTIME0 >> 16) & 0x1F; // 讀取“時“的值
send_buf[11] = Time / 10+'0'; // 存入時十位數字元
send_buf[12] = Time % 10+'0'; // 存入時個位數字元
send_buf[13] = ':'; // 存入“:“
Time = (CTIME0 >> 8) & 0x3F; // 讀取“分“的值
send_buf[14] = Time / 10+'0'; // 存入分十位數字元
send_buf[15] = Time % 10+'0'; // 存入分個位數字元
send_buf[16] = ':'; // 存入“:“
Time = CTIME0 & 0x3F; // 讀取“秒“的值
send_buf[17] = Time / 10+'0'; // 存入秒十位數字元
send_buf[18] = Time % 10+'0'; // 存入秒個位數字元
send_buf[19] = '\r'; // 存入歸位控制“
ISendBuf(MESSAGE, 12); // 發射訊息資料
ISendBuf(send_buf, 20); // 發射時間資料
}
/******************************************************************
* 名稱︰RTCIni()
* 功能︰初始化RTC。
*******************************************************************/
void RTCIni(void)
{
PREINT = Fpclk / 32768 - 1; // 設定基準時脈除頻器
PREFRAC = Fpclk - (Fpclk / 32768) * 32768;
YEAR = 2005; // 初始化年
MONTH = 6; // 初始化月
DOM = 6; // 初始化日
DOW=1; // 初始化星期
HOUR = 8; // 初始化時
MIN = 30; // 初始化分
SEC = 0; // 初始化秒
CIIR =IMSEC; // 設定秒遞加產生中斷
CCR = CLKEN; // 啟動RTC計時
}
/*******************************************************************
* 名稱︰main()
* 功能︰讀取RTC的值,由串列埠發射出去,同時令LED1每秒閃爍一次。
*********************************************************************/
int main(void)
{
IODIR = LED1; // 設定LED1為輸出
PLL_Init(); // PLL初始程式,改為Fcclk=Fosc*4
UART0_Init(); // 初始UART0
U0FCR = 0x01; // 致能FIFO
RTCIni(); // 初始化RTC
while(1)
{
IOCLR = LED1; // LED點亮
SendTime(); // 讀取RTC的時間值,由UART0發射到電腦顯示
while((ILR & RTCIF)==0); // 等待RTC秒遞加中斷旗標
ILR = RTCIF; // 清除遞加中斷旗標
IOSET = LED1; Delay_ms(500); // LED熄滅0.5秒
}
}
/****************RTC與LCD範例程式*************************
*檔名︰RTC2.C
*功能︰RTC進行計時,並將日期及時間值不斷的送到LCD顯示出來
*模擬:開啟RTC視窗,快速執行,觀察其時間的變化
*操作:在LCD顯示"DATE="年-月-日"及"TIME="時:分:秒"
*接線:P22=LCD_RS,P23=LCD_EN ,P24-31=LCD_DATA,令DBGSEL=0
***********************************************************/
#include "LPC2106.h"
uint8 const Table1[]={"DATE="}; // 第一行列表字元
uint8 const Table2[]={"TIME="}; // 第二行列表字元
/*************************************************************
* 名稱︰SendTimeRtc()
* 功能︰讀取RTC的時間值,並將時間值不斷的送到LCD顯示出來。
************************************************************/
void SendTime(void)
{ uint16 Time;
LCD_Cmd(0x85); // 由第一行第5字開始顯示
Time = (CTIME1 >> 16); // 取得“年“的值
Send_Data(Time / 1000+'0'); // 顯示年千位數字元
Send_Data(Time % 1000/100+'0'); // 顯示年百位數字元
Send_Data(Time % 100/10+'0'); // 顯示年十位數字元
Send_Data(Time % 10+'0'); // 顯示年個位數字元
Send_Data('-'); // 顯示“-“
Time = (CTIME1 >> 8) & 0x3F; // 取得“月“的值
Send_Data(Time/10+'0'); // 顯示月十位數字元
Send_Data( Time%10+'0'); // 顯示月個位數字元
Send_Data('-'); // 顯示“-“
Time = CTIME1 & 0x3F; // 取得“日“的值
Send_Data(Time/10+'0'); // 顯示日十位數字元
Send_Data(Time%10+'0'); // 顯示日個位數字元
LCD_Cmd(0xc5); // 由第二行第5字開始顯示
Time = (CTIME0 >> 16) & 0x1F; // 取得時的值
Send_Data(Time / 10+'0'); // 顯示時十位數字元
Send_Data(Time % 10+'0'); // 顯示時個位數字元
Send_Data(':'); // 顯示“:“
Time = (CTIME0 >> 8) & 0x3F; // 取得分的值
Send_Data(Time / 10+'0'); // 顯示分十位數字元
Send_Data(Time % 10+'0'); // 顯示分個位數字元
Send_Data(':'); // 顯示“:“
Time = CTIME0 & 0x3F; // 取得秒值
Send_Data(Time / 10+'0'); // 顯示秒十位數字元
Send_Data(Time % 10+'0'); // 顯示秒個位數字元
}
/*************************************************************
* 名稱︰RTCIni()
* 功能︰初始化RTC。
**************************************************************/
void RTCIni(void)
{ PREINT = Fpclk / 32768 - 1; // 設定基準時脈除頻器
PREFRAC = Fpclk - (Fpclk / 32768) * 32768;
YEAR = 2005; // 初始化年
MONTH = 6; // 初始化月
DOM = 6; // 初始化日
DOW=1; // 初始化星期
HOUR = 8; // 初始化時
MIN = 30; // 初始化分
SEC = 0; // 初始化秒
CIIR =IMSEC; // 設定秒遞加產生中斷
CCR = CLKEN; // 啟動RTC計時
}
/**************************************************************
* 名稱︰main()
* 功能︰讀取RTC的值,由LCD顯示
***************************************************************/
int main(void)
{ uint8 i;
LCD_init(); // 重置及清除LCD
LCD_Cmd(0x80); // 第一行顯示
for(i=0 ; i<5 ; i++) // 讀取列表"DATE="字元
Send_Data(Table1[i]); // 到LCD顯示出來
LCD_Cmd(0xc0); // 第二行顯示
for(i=0 ; i<5 ; i++) // 讀取列表"TIME="字元
Send_Data(Table2[i]); // 到LCD顯示出來
RTCIni(); // 初始化RTC
while(1)
{
while( 0==(ILR & RTCIF) ); // 等待RTC秒遞加中斷旗標
ILR = RTCIF; // 清除RTC秒遞加中斷旗標
SendTime(); // 讀取RTC時鐘送到LCD顯示
}
}
******************RTC中斷範例程式**************************
*檔名︰RTC3.C
*功能︰RTC進行計時,秒遞加中斷令LED1閃爍,每3秒產生警告中斷令LED2閃爍
*模擬:開啟RTC及GPIO視窗,快速執行,觀察其時間的變化
***************************************************************/
#include "LPC2106.h"
void RTC_isr(void)__irq; // 宣告警告中斷IRQ服務程式
/**************************************************************
* 名稱︰RTCIni()
* 功能︰初始化RTC。
**************************************************************/
void RTCIni(void)
{
PLL_Init(); // PLL初始程式,改為Fcclk=Fosc*4
PREINT = Fpclk / 32768 - 1; // 設定基準時脈除頻器
PREFRAC = Fpclk - (Fpclk / 32768) * 32768;
SEC = 0; // 初始化秒
CIIR = IMSEC; // 致能秒每遞增一次,即產生中斷
ALSEC = 3; // 設定3秒後產生秒警告中斷
AMR = ~ARMSEC; // ARMSEC=0 致能秒警告(Alarm)中斷
CCR = CLKEN ; // 致能時間計數,啟動RTC
}
/*******************************************************************
* 名稱︰main()
* 功能︰初始化RTC及致RTC能中斷。
*********************************************************************/
int main(void)
{
IODIR=IOCLR=LED2+LED1; // 設定LED輸出0
RTCIni(); // 初始化RTCC
VICVectAddr13 = (unsigned)RTC_isr; // 設定RTC中斷服務程式位址
VICVectCntl13 = CntlRTC; // 設定向量控制暫存器通道為RTC
VICIntEnable = IntRTC; // 致能RTC中斷
while(1); // 空轉,等待RTC中斷
}
/*******************************************************************
* 名稱︰RTC_isr()
* 功能︰中斷服務程式,秒遞加計數中斷令LED1閃爍,警告中斷令LED2閃爍
*********************************************************************/
void RTC_isr(void) __irq
{
if(ILR & RTCIF) // 檢查是否為秒遞加計數中斷
{
IOSET= LED1; Delay_ms(50); IOCLR= LED1; // LED1閃爍
ILR = RTCIF; // 清除秒遞加計數中斷旗標
}
if(ILR & RTCALF) // 檢查是否為警報中斷
{
IOSET= LED2; Delay_ms(50); IOCLR= LED2; // LED2閃爍
ILR = RTCALF; // 清除警報中斷旗標
ALSEC =ALSEC+3; // 設定每3秒產生秒警告中斷
}
VICVectAddr= 0x00000000; // 清除中斷向量位址
}