本帖最后由 hotpower 于 2011-7-23 13:25 编辑
1.LOOK的核
Cortex.rar
(771.7 KB)
2.LOOK_RTC例程工程包
LOOK_RTC.rar
(2.61 MB)
3.例程运行网页串口调试图示
4.LOOK_RTC.CPP程序片段
#include "LOOK_RTC.h"
#define LOOK_H 1
/*---------------------------------------------------------
0.红杏
1.老师
2.暴力
----------------------------------------------------------*/
#define WEEK_M 6
/*---------------------------------------------------------
0.世纪内星期算法 0 3536 3524
1.菜农星期表格 12 3548 3536
2.菜农星期公式 20 3556 3544
3.菜农星期第二公式 20 3556 3544
4.基姆拉尔森星期公式 36 3572 3560
5.蔡勒完整星期公式 36 3572 3560
6.蔡勒星期公式(无越界校验) 28 3564 3552 (此公式不能在计算机实战)
----------------------------------------------------------*/
#if LOOK_H == 0
#include "NUC1xx.h"
#include "NUC1xxM051Seriescfg.h"
#else
#include <nuc120re3an.h>
using namespace nuvoton;
#endif
sem_t sem = 0;
class rtc_t : public interrupt_t {
public:
__INLINE__ rtc_t();
bool Init();
char* GetRTCString();
void OutSendSecond();
protected:
bool isr(int vector);
void dsr(int vector, uintptr_t count);
private:
bool RtcInit();
bool WriteEnable();
void SetTickMode(uint32_t ucMode);
void SetTickInt();
void SetCalender();
void SetHourMode(uint32_t ClockDisplay);
void SetDate(uint32_t Year, uint32_t Month, uint32_t Day);
void SetTime(uint32_t Hour, uint32_t Minute, uint32_t Second);
void SetWeek(uint32_t Year, uint32_t Month, uint32_t Day);
void GetCalender();
char* GetDateWeekString();
char* GetTimeString();
private:
uint32_t Year;
uint32_t Month;
uint32_t Day;
uint32_t DayOfWeek;
uint32_t Hour;
uint32_t Minute;
uint32_t Second;
uint32_t ClockDisplay;
char Buffers[256];
};
// rtc_t构造函数
__INLINE__ rtc_t::rtc_t()
{
attach(RTC_IRQn);
vector_t::enable(RTC_IRQn);
// Init();
}
bool rtc_t::Init()
{
if (RtcInit())
{
SetCalender();
SetTickInt();
return true;
}
return false;
}
void rtc_t::SetTickInt()
{
#if LOOK_H == 0
RTCs.RIER.Bits.TIER = 1;
#else
RTC.RIER().TIER = 1;
#endif
}
void rtc_t::SetCalender()
{
if (WriteEnable())
{
SetHourMode(1);//DRVRTC_CLOCK_24
SetDate(2011, 7, 15);
SetTime(23, 59, 0);
SetWeek(2011, 7, 15);
SetTickMode(0);
}
}
void rtc_t::SetTickMode(uint32_t ucMode)
{
if (WriteEnable())
{
#if LOOK_H == 0
RTCs.TTR.Bits.TTR = ucMode;
#else
RTC.TTR().TTR = ucMode;
#endif
}
}
bool rtc_t::RtcInit()
{
#if LOOK_H == 0
RTCs.INIR.Regs = 0xa5eb1357;
delay(1);
return RTCs.INIR.Regs == 1;
#else
RTC.INIR = 0xa5eb1357;
delay(1);
return RTC.INIR().ACTIVE;
// return RTCs.INIR == 1;
#endif
}
bool rtc_t::WriteEnable()
{
bool result;
uint32_t count = 0;
#if LOOK_H == 0
do{
RTCs.AER.Bits.AER = 0xA965;
}
while ((++count < 2500) && (RTCs.AER.Bits.ENF != 1));
#else
do{
RTC.AER().AER = 0xA965;
}
while ((++count < 2500) && RTC.AER().ENF != 1);
#endif
result = (count < 2500) ? true : false;
return result;
}
void rtc_t::SetHourMode(uint32_t ClockDisplay)
{
if (WriteEnable())
{
#if LOOK_H == 0
RTCs.TSSR.Bits.HR24 = ClockDisplay;
#else
RTC.TSSR().HR24 = ClockDisplay;
#endif
}
rtc_t::ClockDisplay = ClockDisplay;
}
void rtc_t::SetWeek(uint32_t Year, uint32_t Month, uint32_t Day)
{
uint32_t DayOfWeek;
#if WEEK_M == 1
//月表=(13*Month+8)/5
static const char WeekTable[]="\x2\x5\x0\x3\x5\x1\x4\x6\x2\x0";
#endif
if (WriteEnable())
{
if (Month < 2)
{
//去年
if (Year > 0) Year --;//2000.3~2099.12
else Year = 9999;
//今年的1月2月是去年的13月14月
// Month += 12;
//今年的1月2月是去年的5月6月
Month += 4;
}
#if WEEK_M == 0
//世纪内星期算法
//工程编译长度合计3480个字节
DayOfWeek = ((Year%100)+((Year%100)>>2)+(13*Month+8)/5+Day)%7;
#else
#if WEEK_M == 1
//菜农星期表格=((百年%4)*5+年+年/4+月表+日)%7
//月表=(13*Month+8)/5
//工程编译长度合计3492个字节
DayOfWeek = (((Year/100)&3)*5+(Year%100)+((Year%100)>>2)+WeekTable[Month-3]+Day)%7;
#else
#if WEEK_M == 2
//菜农星期公式=((百年&3)*5+年+(年>>2)+(13*月+8)/5+日)%7
//工程编译长度合计3500个字节
DayOfWeek = (((Year/100)&3)*5+(Year%100)+((Year%100)>>2)+(13*Month+8)/5+Day)%7;
#else
#if WEEK_M == 3
//菜农星期公式2=((百年*5)%20+年+(年>>2)+(13*月+8)/5+日)%7
//工程编译长度合计3492个字节
DayOfWeek = (((Year/100)*5)%20+(Year%100)+((Year%100)>>2)+(13*Month+8)/5+Day)%7;
#else
#if WEEK_M == 4
//基姆拉尔森星期公式=(百年/4+百年*5+年+年/4+(13*月+8)/5+日)%7
//工程编译长度合计3516个字节
DayOfWeek = (Year/400+(Year/100)*5+(Year%100)+((Year%100)>>2)+(13*Month+8)/5+Day)%7;
#else
#if WEEK_M == 5
//蔡勒完整星期公式=(203+百年/4-2*百年+年+年/4+(13*月+3)/5+日+1)%7
//工程编译长度合计3516个字节
DayOfWeek = (203+Year/400-(Year/100)*2+(Year%100)+((Year%100)>>2)+(13*Month+8)/5+Day)%7;
#else //WEEK_M == 6
//蔡勒星期公式=(百年/4-2*百年+年+年/4+(13*月+3)/5+日+1)%7 (此公式不能在计算机实战)
//工程编译长度合计3508个字节
DayOfWeek = (Year/400-(Year/100)*2+(Year%100)+((Year%100)>>2)+(13*Month+8)/5+Day)%7;
#endif
#endif
#endif
#endif
#endif
#endif
#if LOOK_H == 0
RTCs.DWR.Bits.DWR = DayOfWeek;
#else
RTC.DWR().DWR = DayOfWeek;
#endif
rtc_t::DayOfWeek = DayOfWeek;
}
}
void rtc_t::SetDate(uint32_t Year, uint32_t Month, uint32_t Day)
{
if (WriteEnable())
{
#if LOOK_H == 0
/*
RTCs.CLR.Bits.YEAR10 = (Year % 100) / 10;
RTCs.CLR.Bits.YEAR1 = (Year % 100) % 10;
RTCs.CLR.Bits.MON10 = Month / 10;
RTCs.CLR.Bits.MON1 = Month % 10;
RTCs.CLR.Bits.DAY10 = Day / 10;
RTCs.CLR.Bits.DAY1 = Day % 10;
*/
RTCs.CLR.Regs = (((Year % 100) / 10) << RTC_CLR_YEAR10)
| (((Year % 100) % 10) << RTC_CLR_YEAR1)
| ((Month / 10) << RTC_CLR_MON10)
| ((Month % 10) << RTC_CLR_MON1)
| ((Day / 10) << RTC_CLR_DAY10)
| ((Day % 10) << RTC_CLR_DAY1);
//
#else
RTC.CLR(0)
.YEAR10((Year % 100) / 10, false)
.YEAR1((Year % 100) % 10, false)
.MON10(Month / 10, false)
.MON1(Month % 10, false)
.DAY10(Day / 10, false)
.DAY1(Day % 10, false);
#endif
rtc_t::Year = Year;
rtc_t::Month = Month;
rtc_t::Day = Day;
}
}
void rtc_t::SetTime(uint32_t Hour, uint32_t Minute, uint32_t Second)
{
if (WriteEnable())
{
#if LOOK_H == 0
/*
RTCs.TLR.Bits.HR10 = Hour / 10;
RTCs.TLR.Bits.HR1 = Hour % 10;
RTCs.TLR.Bits.MIN10 = Minute / 10;
RTCs.TLR.Bits.MIN1 = Minute % 10;
RTCs.TLR.Bits.SEC10 = Second / 10;
RTCs.TLR.Bits.SEC1 = Second % 10;
*/
//
RTCs.TLR.Regs = ((Hour / 10) << RTC_TLR_HR10)
| ((Hour % 10) << RTC_TLR_HR1)
| ((Minute / 10) << RTC_TLR_MIN10)
| ((Minute % 10) << RTC_TLR_MIN1)
| ((Second / 10) << RTC_TLR_SEC10)
| ((Second % 10) << RTC_TLR_SEC1);
//
#else
RTC.TLR(0)
.HR10(Hour / 10, false)
.HR1(Hour % 10, false)
.MIN10(Minute / 10, false)
.MIN1(Minute % 10, false)
.SEC10(Second / 10, false)
.SEC1(Second % 10, false);
#endif
rtc_t::Hour = Hour;
rtc_t::Minute = Minute;
rtc_t::Second = Second;
}
}
void rtc_t::GetCalender()
{
#if LOOK_H == 0
Year = 2000 + RTCs.CLR.Bits.YEAR10 * 10 + RTCs.CLR.Bits.YEAR1;
Month = RTCs.CLR.Bits.MON10 * 10 + RTCs.CLR.Bits.MON1;
Day = RTCs.CLR.Bits.DAY10 * 10 + RTCs.CLR.Bits.DAY1;
Hour = RTCs.TLR.Bits.HR10 * 10 + RTCs.TLR.Bits.HR1;
Minute = RTCs.TLR.Bits.MIN10 * 10 + RTCs.TLR.Bits.MIN1;
Second = RTCs.TLR.Bits.SEC10 * 10 + RTCs.TLR.Bits.SEC1;
DayOfWeek = RTCs.DWR.Bits.DWR;
ClockDisplay = RTCs.TSSR.Bits.HR24;
#else
#if LOOK_H == 1
auto clr = RTC.CLR();
Year = 2000 + clr.YEAR10 * 10 + clr.YEAR1;
Month = clr.MON10 * 10 + clr.MON1;
Day = clr.DAY10 * 10 + clr.DAY1;
DayOfWeek = RTC.DWR().DWR;
auto tlr = RTC.TLR();
Hour = tlr.HR10 * 10 + tlr.HR1;
Minute = tlr.MIN10 * 10 + tlr.MIN1;
Second = tlr.SEC10 * 10 + tlr.SEC1;
ClockDisplay = RTC.TSSR().HR24;
#else
RTC.CLR()
.YEAR10.lambda([&Year](uint32_t y){Year = 2000 + y * 10; return y; })
.YEAR1.lambda([&Year](uint32_t y){ Year += y; return y; })
.MON10.lambda([&Month](uint32_t m){Month = m * 10; return m; })
.MON1.lambda([&Month](uint32_t m){ Month += m; return m; })
.DAY10.lambda([&Day](uint32_t d){Day = d * 10; return d; })
.DAY1.lambda([&Day](uint32_t d){ Day += d; return d; });
DayOfWeek = RTC.DWR().DWR;
RTC.TLR()
.HR10.lambda([&Hour](uint32_t h){Hour = h * 10; return h; })
.HR1.lambda([&Hour](uint32_t h){ Hour += h; return h; })
.MIN10.lambda([&Minute](uint32_t m){Minute = m * 10; return m; })
.MIN1.lambda([&Minute](uint32_t m){ Minute += m; return m; })
.SEC10.lambda([&Second](uint32_t s){Second = s * 10; return s; })
.SEC1.lambda([&Second](uint32_t s){ Second += s; return s; });
ClockDisplay = RTC.TSSR().HR24;
#endif
#endif
}
char* rtc_t::GetRTCString()
{
GetDateWeekString();
GetTimeString();
Buffers[14] = ' ';
Buffers[15] = ' ';
return &Buffers[0];
}
char* rtc_t::GetDateWeekString()
{
char *str;
str = &Buffers[0];
*str++ = (Year / 1000) + '0';
*str++ = ((Year / 100) % 10) + '0';
*str++ = ((Year / 10) % 10) + '0';
*str++ = (Year % 10) + '0';
*str++ = '.';
*str++ = ((Month / 10) % 10) + '0';
*str++ = (Month % 10) + '0';
*str++ = '.';
*str++ = ((Day / 10) % 10) + '0';
*str++ = (Day % 10) + '0';
*str++ = ' ';
*str++ = '[';
*str++ = (DayOfWeek % 10) + '0';
*str++ = ']';
*str++ = '\n';
*str++ = 0;
str = &Buffers[0];
return str;
}
char* rtc_t::GetTimeString()
{
char *str;
str = &Buffers[16];
*str++ = ((Hour / 10) % 10) + '0';
*str++ = (Hour % 10) + '0';
*str++ = ':';
*str++ = ((Minute / 10) % 10) + '0';
*str++ = (Minute % 10) + '0';
*str++ = ':';
*str++ = ((Second / 10) % 10) + '0';
*str++ = (Second % 10) + '0';
*str++ = ' ';
*str++ = '(';
*str++ = (ClockDisplay & 1) + '0';
*str++ = ')';
*str++ = '\n';
*str++ = 0;
str = &Buffers[16];
return str;
}
void rtc_t::OutSendSecond()
{
#if LOOK_H == 0
GPIOAs.DMASK.Regs = ~0b111100;
GPIOAs.DOUT.Regs = (~Second) << 2;
#else
GPIOA.DMASK(-1)
.DMASK5(0)
.DMASK4(0)
.DMASK3(0)
.DMASK2(0);
GPIOA.DOUT = (~Second) << 2;
#endif
}
// rtc_t中断服务例程
bool rtc_t::isr(int vector)
{
#if LOOK_H == 0
RTCs.RIIR.Bits.TI = 1;
#else
RTC.RIIR().TI = 1;
#endif
return true;
}
void rtc_t::dsr(int vector, uintptr_t count)
{
GetCalender();
sem.do_post();
}
rtc_t rtc; // 创建rtc对象
// uart0_t 类为应用层提供了简单的 uart 同步输出功能。
class uart0_t : public interrupt_t {
public:
__INLINE__ uart0_t();
void puts(const char* str);
protected:
bool isr(int vector);
void dsr(int vector, uintptr_t count);
private:
void fillfifo(const char* str);
private:
const char* buffer; // 输出缓冲区
task_t* task; // 正在输出的任务
};
// uart0 构造函数
__INLINE__ uart0_t::uart0_t()
{
attach(UART0_IRQn);
vector_t::enable(UART0_IRQn);
#if LOOK_H == 0
SYSs.IPRSTC2.Bits.UART0_RST = 1;
SYSs.IPRSTC2.Bits.UART0_RST = 0;
UART0s.FCR.Regs |= (1 << UART_FCR_TFR) | (1 << UART_FCR_RFR);
UART0s.LCR.Regs = 3 << UART_LCR_WLS; // 8bits
UART0s.BAUD.Regs = (0x66 << UART_BAUD_BRD)
| (1 << UART_BAUD_DIV_X_ONE)
| (1 << UART_BAUD_DIV_X_EN); // 115200
#else
SYS.IPRSTC2()
.UART0_RST(1);
SYS.IPRSTC2()
.UART0_RST(0);
UART0.FCR()
.TFR(1)
.RFR(1);
UART0.LCR(0)
.WLS(3); // 8bits
UART0.BAUD(0)
.BRD(0x66)
.DIV_X_ONE(1)
.DIV_X_EN(1); // 115200
#endif
}
// uart0 输出
void uart0_t::puts(const char* str)
{
fillfifo(str); // 填充 fifo
#if LOOK_H == 0
UART0s.IER.Bits.THRE_IEN = 1; // 允许发送中断
#else
UART0.IER()
.THRE_IEN(1); // 允许发送中断
#endif
task = &scheduler.get_current_task();
delay(); // 阻塞任务
}
// uart0 中断服务例程
bool uart0_t::isr(int vector)
{
const char* str = buffer;
if (str == 0) { // 无数据
#if LOOK_H == 0
UART0s.IER.Bits.THRE_IEN = 0; // 禁止发送中断
#else
UART0.IER()
.THRE_IEN(0); // 禁止发送中断
#endif
return true;
}
fillfifo(str); // 填充 fifo
return false;
}
// uart0 中断滞后服务例程
// 所有数据发送完成后,dsr() 被调用
void uart0_t::dsr(int vector, uintptr_t count)
{
task->do_wakeup(); // 唤醒任务
}
// uart0 填充 fifo
void uart0_t::fillfifo(const char* str)
{
#if LOOK_H == 0
do {
char ch;
ch = *str++;
if (ch == 0) {
str = 0;
break;
}
UART0s.DATA.Regs = ch;
} while (!UART0s.FSR.Bits.TX_FULL);
#else
do {
char ch;
ch = *str++;
if (ch == 0) {
str = 0;
break;
}
UART0.DATA = ch;
} while (!UART0.FSR().TX_FULL);
#endif
buffer = str;
}
uart0_t uart0; // 创建 uart0 对象
// 任务类 task_LOOK_RTC_t 的例程
void task_LOOK_RTC_t::routine()
{
// TODO: 在此编写 task_LOOK_RTC_t 例程的内容
uint_fast8_t n = 8;
do {
if (rtc.Init())
break;
} while (--n);
// uart0.putchar(n + '0');
if (n == 0) {
uart0.puts("rtc error\n");
while (true)
delay();
}
while (true) {
// TODO: 在此编写 task_LOOK_RTC_t 例程的内容
if (sem.wait())
{
uart0.puts(rtc.GetRTCString());//串口显示
rtc.OutSendSecond();//LED显示
}
}
}
#ifdef LOOK_SCHEDULING_PRIORITY
instantiate::task<task_LOOK_RTC_t, LOOK_STACK_SIZE> task_LOOK_RTC(0);
#else
instantiate::task<task_LOOK_RTC_t, LOOK_STACK_SIZE> task_LOOK_RTC;
#endif
|