关于RTC的万年历实验Word文档下载推荐.docx
《关于RTC的万年历实验Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《关于RTC的万年历实验Word文档下载推荐.docx(17页珍藏版)》请在冰豆网上搜索。
在调试过程中,总结了一些错误原因分析以及编程注意点:
①刚开始时,由于没注意格式书写,程序看起来很乱,在涂老师的建议下,将程序中函数的正反大括号对齐,这样程序变得更直观。
②经过调试以及和同学的探讨,成功实现了KEY3和KEY4按键在最小值和最大值的变化。
其中关键是使用类似if(SEC==0)SEC=59;
elseSEC--;
和if(SEC==59)SEC=0;
elseSEC++;
而自己原来是将类似SEC--和SEC++放在前面,由于SEC寄存器不能取-1值,所以SEC--放在前面时,不能减到00的状态,直接从01到59了。
原来只是个顺序问题,让程序变得如此微妙。
③在调试时,由于错在将#defineKEY11<
<
16后面多加了“;
”导致调试时显示很多错误。
从中发现,有时会因一个地方出错导致显示很多错误。
同样的,有时也会是调试时只显示一个错误,但其实有多个地方有错。
以后要注意这点。
④在调整星期时发现,当7加一时竟变成0了。
和同学讨论后得知原来星期寄存器只用了3为(26:
24),所以当7加一时为8但第四位没被获取故只得0。
以后多了解寄存器地址、结构等内部原理知识,这样一些问题就会迎刃而解。
⑤调试时发现,当双击“{”或“}”所在行,则其所包含的函数体会用黑色显示,如下图,这样即可快速找到“{”或“}”的匹配括号,因此也可以很方便用来查错。
⑥通过调试,掌握了按键释放程序的应用。
程序中采用类似while((IO0PIN&
KEY4)==0);
语句,其作用与while(!
(IO0PIN&
KEY4));
等价得知“!
KEY4)”并不是取反的意思。
程序中KEY1和KEY2采用等待按键释放,而为了按住按键时自动快速加减,KEY3和KEY4不用等待按键释放程序。
这次实验,我习得了不少,从中体会到多调试多实际操作练习将会发现很多的问题,同时在解决问题过程中可以获得很多知识。
再次,感谢涂老师的指导和同学的帮助。
附录:
#include"
config.h"
music.h"
#defineBEEP1<
7
constuint32KEY1=1<
16;
constuint32KEY2=1<
17;
constuint32KEY3=1<
18;
constuint32KEY4=1<
19;
constuint32LED8=1<
25;
constuint32LED1=1<
constuint32LED2=1<
constuint32LED3=1<
20;
constuint32LED4=1<
21;
constuint32LED5=1<
22;
constuint32LED6=1<
23;
constuint32LED7=1<
24;
constuint32LEDS8=0xFF<
//定义串口模式设置的数据结构
constuint32HCMM[]=
{
_LA,_SO,_MI,_LA,_SO,_MI,
_LA,_LA,_SO,_LA,
_RE,_RE,_DO,_RE,
_MI,_MI,_SO,_LA,_DO1,_LA,_SO,
_MI,_MI,_SO,_DO,
_MI,_MI,_MI,_MI,_MI,
_1LA,_1LA,_1SO,_1LA,
};
/*歌曲节拍*/
constuint32HCMM_L[]=
_4,_8,_8,_4,_8,_8,
_8,_4,_8,_2,
_4,_8,_8,_8,_8,_8,_8,
_4,_4,_4,_8,_8,
typedefstructUartMode
uint8datab;
//字长度5/6/7/8
uint8stopb;
//停止位1/2
uint8parity;
//奇偶校验0-无校验,1-奇校验,2-偶校验
}UARTMODE;
voidDelay(uint8dly)
uint32i;
for(;
dly>
0;
dly--)
{for(i=0;
i<
0x7FFFF;
i++);
}
uint8UART0_Init(uint32baud,UARTMODEset)
uint32bak;
//参数过滤
if((0==baud)||(baud>
115200))return(0);
if((set.datab<
5)||(set.datab>
8))return(0);
if((0==set.stopb)||(set.stopb>
2))return(0);
if(set.parity>
4)return(0);
//设置串口波特率
U0LCR=0x80;
//DLAB=1
bak=(Fpclk>
>
4)/baud;
U0DLM=bak>
8;
U0DLL=bak&
0xff;
//设置串口模式
bak=set.datab-5;
if(2==set.stopb)bak|=0x04;
if(0!
=set.parity)
{
set.parity=set.parity-1;
bak|=0x08;
}
bak|=set.parity<
4;
U0LCR=bak;
return(0);
voidSendByte(uint8data)
U0THR=data;
while((U0LSR&
0X20)==0);
//等待数据发送
voidPC_DispChar(uint8no,uint8chr)
SendByte(0xff);
SendByte(0x81);
SendByte(no);
SendByte(chr);
SendByte(0x00);
voidabd(void)
IO0CLR=BEEP;
IO1CLR=LED8;
Delay(5);
IO0SET=BEEP;
IO1SET=LED8;
uint8constSHOWTABLE[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
voidSendTimeRtc(void)
uint32datas;
uint32times;
times=CTIME0;
//读取完整的时钟寄存器
datas=CTIME1;
bak=(datas>
16)&
0xfff;
//获取年
PC_DispChar(0,SHOWTABLE[bak/1000]);
bak=bak%1000;
PC_DispChar(1,SHOWTABLE[bak/100]);
bak=bak%100;
PC_DispChar(2,SHOWTABLE[bak/10]);
PC_DispChar(3,SHOWTABLE[bak%10]);
8)&
0x0f;
//获取月
PC_DispChar(4,SHOWTABLE[bak/10]);
PC_DispChar(5,SHOWTABLE[bak%10]);
bak=datas&
0x1f;
//获取日
PC_DispChar(6,SHOWTABLE[bak/10]);
PC_DispChar(7,SHOWTABLE[bak%10]);
bak=(times>
24)&
0x07;
//获取星期
PC_DispChar(8,SHOWTABLE[bak]);
//获取小时
PC_DispChar(9,SHOWTABLE[bak/10]);
PC_DispChar(10,SHOWTABLE[bak%10]);
0x3f;
//获取分钟
PC_DispChar(11,SHOWTABLE[bak/10]);
PC_DispChar(12,SHOWTABLE[bak%10]);
bak=times&
//获取秒钟
PC_DispChar(13,SHOWTABLE[bak/10]);
PC_DispChar(14,SHOWTABLE[bak%10]);
voidSendTimeRtc1(void)
PC_DispChar(0,SHOWTABLE[ALYEAR/1000]);
ALYEAR=ALYEAR%1000;
PC_DispChar(1,SHOWTABLE[ALYEAR/100]);
ALYEAR=ALYEAR%100;
PC_DispChar(2,SHOWTABLE[ALYEAR/10]);
PC_DispChar(3,SHOWTABLE[ALYEAR%10]);
PC_DispChar(4,SHOWTABLE[ALMON/10]);
PC_DispChar(5,SHOWTABLE[ALMON%10]);
PC_DispChar(6,SHOWTABLE[ALDOM/10]);
PC_DispChar(7,SHOWTABLE[ALDOM%10]);
PC_DispChar(8,SHOWTABLE[ALDOW]);
PC_DispChar(9,SHOWTABLE[ALHOUR/10]);
PC_DispChar(10,SHOWTABLE[ALHOUR%10]);
PC_DispChar(11,SHOWTABLE[ALMIN/10]);
PC_DispChar(12,SHOWTABLE[ALMIN%10]);
PC_DispChar(13,SHOWTABLE[ALSEC/10]);
PC_DispChar(14,SHOWTABLE[ALSEC%10]);
void__irqRTC_Int(void)
uint32i,num1;
if((IO1SET&
LED1)==0)IO1SET=LED1;
elseIO1CLR=LED1;
if(num1!
=0)SendTimeRtc1();
elseSendTimeRtc();
if(ILR==0x03)
for(i=0;
i<
3;
i++)
Delay(3);
PINSEL0=(PINSEL0&
0xFFFF3FFF)|(0x02<
14);
//P0.7选择PWM2功能
for(i=0;
sizeof(HCMM)/4;
i++)
PWMMR0=Fpclk/HCMM[i];
//设置输出频率
PWMLER=0x05;
//更新匹配值后,必须锁存
Delay(HCMM_L[i]);
//延时,控制播放速度
if(num1!
=0)SendTimeRtc1();
0xFFFF3FFF)|(0x00<
//P0.7取消PWM2功能
ILR=0x03;
VICVectAddr=0;
voidRTCInit(void)
YEAR=2011;
MONTH=04;
DOM=28;
DOW=4;
HOUR=10;
MIN=29;
SEC=50;
ALYEAR=2003;
ALMON=04;
ALDOM=01;
ALDOW=4;
ALHOUR=06;
ALMIN=42;
ALSEC=20;
AMR=0xFE;
//设置报警屏蔽寄存器,设置秒值与报警寄存器比较。
CIIR=0x01;
//设置秒值的增量产生1次中断
CCR=0x11;
//启动RTC
intmain(void)
uint8i,num=0,num1=0;
UARTMODEuart0_set;
PINSEL0=0x00000005;
//连接IO到UART0
PINSEL2=PINSEL2&
(~0x08);
IO1DIR=LEDS8;
IO1SET=LEDS8;
IO0DIR=BEEP;
PWMPR=0x00;
//不分频,计数频率为Fpclk
PWMMCR=0x02;
//设置PWMMR0匹配时复位PWMTC
PWMPCR=0x0400;
//允许PWM2输出,单边PWM
PWMMR0=Fpclk/1000;
PWMMR2=PWMMR0/2;
//50%占空比
PWMLER=0x05;
//PWM0和PWM2匹配锁存
PWMTCR=0x02;
//复位PWMTC
PWMTCR=0x09;
//启动PWM输出
//IRQEnable();
//中断使能,程序可用查询方式,也可以用中断方式。
VICIntSelect=0x00;
//设置所有中断连接IRQ中断
VICVectCntl0=0x20|13;
//分配通道0
VICVectAddr0=(int)RTC_Int;
//设置中断服务程序地址
VICIntEnable=(1<
13);
//使能RTC中断
uart0_set.datab=8;
uart0_set.stopb=1;
uart0_set.parity=0;
UART0_Init(115200,uart0_set);
U0FCR=0x01;
//FIFO使能
RTCInit();
while
(1)
if(ILR==0x01)
if((IO0PIN&
KEY1)==0)
Delay
(1);
abd();
CCR=0x00;
num++;
switch(num)
case1:
IO1CLR=LED1;
break;
case2:
IO1SET=LED1;
IO1CLR=LED2;
case3:
IO1SET=LED2;
IO1CLR=LED3;
case4:
IO1SET=LED3;
IO1CLR=LED4;
case5:
IO1SET=LED4;
IO1CLR=LED5;
case6:
IO1SET=LED5;
IO1CLR=LED6;
case7:
IO1SET=LED6;
IO1CLR=LED7;
case8:
IO1SET=LED7;
num=0;
CCR=0x01;
while((IO0PIN&
KEY1)==0);
//等待按键释放
KEY2)==0)
num1++;
SendTimeRtc1();
switch(num1)
num1=0;
KEY2)==0);
KEY3)==0)
if(SEC==0)SEC=59;
elseSEC--;
if(MIN==0)MIN=59;
elseMIN--;
if(HOUR==0)HOUR=23;
elseHOUR--;
if(DOW==1)DOW=7;
elseDOW--;
if(DOM==1)DOM=31;
elseDOM--;
if(MONTH==1)MONTH=12;
elseMONTH--;
if(YEAR==0)YEAR=4095;
elseYEAR--;
if(ALSEC==0)ALSEC=59;
elseALSEC--;
if(ALMIN==0)ALMIN=59;
else