源码如下:
- /*
- 24MHz+波特率115200
-
- 使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。
- edata建议保留1K给堆栈使用,空间不够时可将大数组、不常用变量加xdata关键字定义到xdata空间。
-
- */
-
-
-
-
-
- #include "AI8051U.h"
- #include "stdio.h"
- #include "intrins.h"
-
- /***********************************************************/
-
- typedef unsigned char u8;
- typedef unsigned int u16;
- typedef unsigned long u32;
-
- /****************************** 用户定义宏 ***********************************/
-
- #define MAIN_Fosc 24000000L //定义主时钟
- #define PrintUart 1 //1:printf 使用 UART1; 2:printf 使用 UART2
- #define Baudrate 115200L
- #define TM (65536 -(MAIN_Fosc/Baudrate/4))
- #define Timer0_Reload (65536UL -(MAIN_Fosc / 1000)) //Timer 0 中断频率, 1000次/秒
- /*****************************************************************************/
-
-
- u8 B_10ms; //10ms标志
- bit B_1s; //1s标志
- bit B_Alarm; //闹钟标志
-
- u8 hour,minute,sec; //RTC变量
- u16 msecond;
- #define LED P35
-
- /************* 本地函数声明 **************/
-
- void WriteRTC(void);
- void RTC_config(void);
- void Timer0_Init(void); //1000毫秒@24.000MHz
- void delay_ms(u8 ms);
-
- void UartInit(void)
- {
- #if(PrintUart == 1)
- S1_S1 = 0; //UART1 switch to, 0x00: P3.0 P3.1, 0x40: P3.6 P3.7, 0x80: P1.6 P1.7, 0xC0: P4.3 P4.4
- S1_S0 = 0;
- SCON = (SCON & 0x3f) | 0x40;
- T1x12 = 1; //定时器时钟1T模式
- S1BRT = 0; //串口1选择定时器1为波特率发生器
- TL1 = TM;
- TH1 = TM>>8;
- TR1 = 1; //定时器1开始计时
-
- // SCON = (SCON & 0x3f) | 0x40;
- // T2L = TM;
- // T2H = TM>>8;
- // AUXR |= 0x15; //串口1选择定时器2为波特率发生器
- #else
- S2_S = 1; //UART2 switch to: 0: P1.2 P1.3, 1: P4.2 P4.3
- S2CFG |= 0x01; //使用串口2时,W1位必需设置为1,否则可能会产生不可预期的错误
- S2CON = (SCON & 0x3f) | 0x40;
- T2L = TM;
- T2H = TM>>8;
- AUXR |= 0x14; //定时器2时钟1T模式,开始计时
- #endif
- }
-
-
-
-
-
-
- /**********************************************/
- void main(void)
- {
-
- WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
- EAXFR = 1; //扩展寄存器(XFR)访问使能
- CKCON = 0; //提高访问XRAM速度
-
- P0M1 = 0x00; P0M0 = 0x00; //设置为准双向口
- P1M1 = 0x00; P1M0 = 0x00; //设置为准双向口
- P2M1 = 0x00; P2M0 = 0x00; //设置为准双向口
- P3M1 = 0x00; P3M0 = 0x00; //设置为准双向口
- P4M1 = 0x00; P4M0 = 0x00; //设置为准双向口
- P5M1 = 0x00; P5M0 = 0x00; //设置为准双向口
- P6M1 = 0x00; P6M0 = 0x00; //设置为准双向口
- P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
-
- Timer0_Init();
- UartInit();
- RTC_config();
- EA = 1; //打开总中断
- delay_ms(100);
- while(1)
- {
- if(B_1s)
- {
- B_1s = 0;
- LED=~LED;
- // printf("LED---");
- printf("20%d-%d-%d Week=%d %d:%d:%d\r\n",YEAR,MONTH,DAY,WEEK,HOUR,MIN,SEC);//
-
- }
-
- // if(B_Alarm)
- // {
- // B_Alarm = 0;
- // printf("RTC Alarm!\r\n");
- // }
- }
- }
-
- void Timer0_Isr(void) interrupt 1
- {
- B_1s=1;
- }
-
- void Timer0_Init(void) //1000毫秒@24.000MHz
- {
- TM0PS = 0x1E; //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
- AUXR &= 0x7F; //定时器时钟12T模式
- TMOD &= 0xF0; //设置定时器模式
- TL0 = 0xFC; //设置定时初始值
- TH0 = 0x03; //设置定时初始值
- TF0 = 0; //清除TF0标志
- TR0 = 1; //定时器0开始计时
- ET0 = 1; //使能定时器0中断
- }
-
-
-
-
-
- ///********************** 写RTC函数 ************************/
- //void WriteRTC(void)
- //{
- // INIYEAR = YEAR; //继承当前年月日
- // INIMONTH = MONTH;
- // INIDAY = DAY;
-
- // INIHOUR = hour; //修改时分秒
- // INIMIN = minute;
- // INISEC = sec;
- // INISSEC = 0;
- // RTCCFG |= 0x01; //触发RTC寄存器初始化
- //}
-
-
- /******************** RTC中断函数 *********************/
- void RTC_Isr() interrupt 13
- {
- if(RTCIF & 0x80) //闹钟中断
- {
- RTCIF &= ~0x80;
- B_Alarm = 1;
- }
-
- if(RTCIF & 0x08) //秒中断
- {
- RTCIF &= ~0x08;
- // B_1s = 1;
- }
- }
-
-
- //========================================================================
- // 函数: void RTC_config(void)
- // 描述: RTC初始化函数。
- // 参数: 无.
- // 返回: 无.
- // 版本: V1.0, 2020-6-10
- //========================================================================
- void RTC_config(void)
- {
- INIYEAR = 24; //年
- INIMONTH = 11; //月
- INIDAY = 30; //日
- INIWEEK=3; //星期
- INIHOUR = 23; //H:23
- INIMIN = 59; //M:59
- INISEC = 55; //S:50
- INISSEC = 0; //S/128:0
-
- ALAHOUR = 0; //闹钟小时
- ALAMIN = 0; //闹钟分钟
- ALASEC = 0; //闹钟秒
- ALASSEC = 0; //闹钟1/128秒
-
- IRC32KCR = 0x80; //启动内部32K晶振.
- while (!(IRC32KCR & 1)); //等待时钟稳定
- RTCCFG = 0x03; //选择内部32K时钟源,触发RTC寄存器初始化
-
- // X32KCR = 0x80 + 0x40; //启动外部32K晶振, 低增益+0x00, 高增益+0x40.
- // while (!(X32KCR & 1)); //等待时钟稳定
- // RTCCFG = 0x01; //选择外部32K时钟源,触发RTC寄存器初始化
-
- RTCIF = 0x00; //清中断标志
- RTCIEN = 0x88; //中断使能, 0x80:闹钟中断, 0x40:日中断, 0x20:小时中断, 0x10:分钟中断, 0x08:秒中断, 0x04:1/2秒中断, 0x02:1/8秒中断, 0x01:1/32秒中断
- RTCCR = 0x01; //RTC使能
-
- while(RTCCFG & 0x01); //等待初始化完成,需要在 "RTC使能" 之后判断.
- //设置RTC时间需要32768Hz的1个周期时间,大约30.5us. 由于同步, 所以实际等待时间是0~30.5us.
- //如果不等待设置完成就睡眠, 则RTC会由于设置没完成, 停止计数, 唤醒后才继续完成设置并继续计数.
- }
-
- void UartPutc(unsigned char dat)
- {
- #if(PrintUart == 1)
- SBUF = dat;
- while(TI == 0);
- TI = 0;
- #else
- S2BUF = dat;
- while(S2TI == 0);
- S2TI = 0; //Clear Tx flag
- #endif
- }
-
- char putchar(char c)
- {
- UartPutc(c);
- return c;
- }
-
- void Delay1ms(void) //@24.000MHz
- {
- unsigned long edata i;
-
- _nop_();
- _nop_();
- _nop_();
- i = 5998UL;
- while (i) i--;
- }
- void delay_ms(u8 ms)
- {
- while(ms--)Delay1ms();
-
- }
-
复制代码
|