打印
[LOOK]

LOOK_RTC例程及星期算法的各种实现

[复制链接]
2195|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
RTC, se, ui, TE, ck
本帖最后由 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

相关帖子

沙发
jutyy| | 2011-7-22 20:33 | 只看该作者
支持!

使用特权

评论回复
板凳
wang0225| | 2011-7-22 20:42 | 只看该作者
给力

使用特权

评论回复
地板
老鱼探戈| | 2011-7-22 20:43 | 只看该作者
板凳!

使用特权

评论回复
5
859419016| | 2011-7-22 22:20 | 只看该作者
:victory:

使用特权

评论回复
6
乡村男孩| | 2011-7-22 22:35 | 只看该作者
大叔精彩

使用特权

评论回复
7
stepme| | 2011-7-22 22:55 | 只看该作者
头回来

使用特权

评论回复
8
hotpower|  楼主 | 2011-7-23 10:22 | 只看该作者
现在look已经经历了gpio,iic,spi,pdma,uart,adc,rtc这些模块的考验通过。老师的头文件昨晚应该是俺最满意的!

使用特权

评论回复
9
zxs2000| | 2011-7-23 11:32 | 只看该作者

使用特权

评论回复
10
c51avr| | 2011-7-23 11:38 | 只看该作者
:victory:顶大叔啊

使用特权

评论回复
11
hotpower|  楼主 | 2011-7-25 00:01 | 只看该作者

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:[url=http://www.21ic.com/tools/HotWC3_V1.23.html]

1538

主题

21697

帖子

505

粉丝