本帖最后由 hotpower 于 2011-7-23 13:25 编辑
1.LOOK的核
2.LOOK_RTC例程工程包
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
|