rtc
1 这个程序用十进制不行。
2 注意是寄存器的起始地址是小端。寄存器的地址不连续的问题。
3 Int类型分为10进制,16进制,2进制也是。
char类型。
注意此处的寄存器中存的是BCD码,int型中的16进制。
4 void htoa(unsigned int data)
putc(data/16+48);
putc(data%16+48);
}
此处是把int类型(16进制的)data先转化为10进制然后转化为字符打印出来。
5 int atoh(char *data)
{
int sum = 0;
while(*data != '\0')
{
sum = sum*16+*data++-'0';
}
return sum;
}
此处是把char类型的数组中的数然后化为16进制然后输出。
6 BCD码只的就是16进制。
7 16进制 10进制 2进制
23 35 100011
17 23 10111
15 22 10110
10 16 10000
9 9
a 10
b 11
c 12
d 13
e 14
f 15
8 char time[7] = {0, 0, 0, 1, 0, 0, 1};(这里边是十进制)
2进制除以2就是10进制,16进制除以16就是10进制。
rtc_init(time);
void rtc_init(char *data)
{
RTC.RTCCON = 0x1;
RTC.BCDYEAR = data[0];(十进制赋值,但是进去就变为16进制了你也可以16进制赋值,)
RTC.BCDMON = data[1];
RTC.BCDDATE = data[2];
RTC.BCDDAY = data[3];
RTC.BCDHOUR = data[4];
RTC.BCDMIN = data[5];
RTC.BCDSEC = data[6];
RTC.RTCALM = 0x1<<6|data[7]<<0;
RTC.ALMSEC = data[8];
RTC.RTCCON = 0x0;
}
本来给rtc寄存器赋值,我们最好用16进制,因为BCD码本来就是16进制。
而十进制,本来不可以赋值的,但是
一直以为我们输入的是 10进制因为小的时候和16进制一样(最起码2进制一样),虽有小于9的时候可以赋值。
11 while(1)
{
puts("20");
htoa(RTC.BCDYEAR);
putc('-');
htoa(RTC.BCDMON);
putc('-');
htoa(RTC.BCDDATE);
putc(' ');
htoa(RTC.BCDDAY);
putc(' ');
htoa(RTC.BCDHOUR);
putc(':');
htoa(RTC.BCDMIN);
putc(':');
htoa(RTC.BCDSEC);
puts("\r\n");
sleep(1);
}
void htoa(unsigned int data)
{
putc(data/16+48);
putc(data%16+48);
}
从寄存器中取得的是16进制,所以我们用htoa函数,int类型16进制转化为字符串类型。
12 我们设置时间的时候输入的是字符串类型,而我们需要把子字符串传化为Int类型的16进制,然后放到寄存器里,
寄存里取出来打印的时候,还需要把16进制转化为字符类型才能打印。
13 断电后,芯片不提供时钟。CPU晶振(X2)的边上有一个时针晶振(X1)(网络还有一个晶振) ,RTC在CPU的里边,断电后独立运行。RTC有两个2级管,供选择电。
14 RTC.RTCCON=0x1;
RTC.BCDYEAR=0x1;
RTC.RTCCON=0x0;此处关闭BCD写。
15 RTC注意寄存器的地址不连的问题。
16 char time[9] = {0, 0, 0, 1, 0, 0, 1, 1, 0};
char data[32], *arg[11];
int i;
getsexample(data);
arg[0] = strtok(data, " ");
for(i=1; arg[i-1]!=NULL; i++)
{
arg[i] = strtok(NULL, " ");
}
if(strcmp(arg[0], "rtcset") == 0)
{
time[0] = atoh(arg[1]);(这里h代表16进制,但是没有加0x,所以还是转化为10进制保存)
time[1] = atoh(arg[2]);
time[2] = atoh(arg[3]);
time[3] = atoh(arg[4]);
time[4] = atoh(arg[5]);
time[5] = atoh(arg[6]);
time[6] = atoh(arg[7]);
time[7] = atoh(arg[8]);
time[8] = atoh(arg[9]);
rtc_init(time);
}
___________________________________________________________________
void rtc_init(char *d)
{
RTC.RTCCON = 0x1;
RTC.BCDYEAR = data[0];
RTC.BCDMON = data[1];
RTC.BCDDATE = data[2];
RTC.BCDDAY = data[3];
RTC.BCDHOUR = data[4];
RTC.BCDMIN = data[5];
RTC.BCDSEC = data[6];
RTC.RTCALM = 0x1<<6|data[7]<<0;
RTC.ALMSEC = data[8];
RTC.RTCCON = 0x0;
}
这里的char time[9] = {0, 0, 0, 1, 0, 0, 1, 1, 0};是字符型的数组,他的十进制表示不能大于255,也可由用字符直接表示‘9’等,但是给计算机和寄存器的时候仍然是十进制, atoh把字符转化为16进制的10进制表示,RTC.BCDYEAR = data[0];这里赋值的时候,data[0]是个地址,而地址中存的是字符,但是这个字符是以16进制的十进制表示的,所以仍然是10进制赋值给寄存器。给寄存器赋值的话,不论是16进制还是10进制,但是必须要int型,如果是字符也是他的十进制表示赋值。
****************************************************************
int time[7];
char buf[32], *p[9];
int i;
uart_init();
while(1)
{
puts("\r\nrtc> ");
gets(buf);
buf[strlen(buf)-2] = '\0';
p[0] = strtok(buf, " ");
for(i=1; p[i-1]!=NULL; i++)
{
p[i] = strtok(NULL, " ");
}
if(strcmp(p[0], "timeset") == 0)
{
time[0] = atoh(p[1]);
time[1] = atoh(p[2]);
time[2] = atoh(p[3]);
time[3] = atoh(p[4]);
time[4] = atoh(p[5]);
time[5] = atoh(p[6]);
time[6] = atoh(p[7]);
rtc_init(time);
}
if(strcmp(p[0], "time") == 0)
{
rtc_display();
}
}
_____________________________________________________________
void rtc_init(int *t)
{
RTC.RTCCON = 0x1;
RTC.BCDYEAR = t[0];
RTC.BCDMON = t[1];
RTC.BCDDATE = t[2];
RTC.BCDDAY = t[3];
RTC.BCDHOUR = t[4];
RTC.BCDMIN = t[5];
RTC.BCDSEC = t[6];
RTC.RTCCON = 0x0;
}
无论是int数组赋值,还是char数组赋值,我们函数都是用指针类型接收,字符和Int数组的数组名都表示指针。
****************************************************************
17 RTC的时间设置
你可以16进制0x14直接给寄存器赋值,从寄存器读出来的int型也是16进制的10进制表示20,然后你把它用字符串打印出来14。
你可以用10进制20直接给寄存器赋值,从寄存器里读出来的Int型16进制的10进制表示,也是20,然后你把他用字符表示出来就是14.
你可以用字符(比如对应的Int型仍然是0x14,或者20)给寄存器赋值,(计算机中一切都是10进制,所以我们说是字符赋值,仍然是用字符的10进制赋值,)吧20赋进去,从寄存器读出来的是20,不是你的字符。
18 问题既然说我们赋值的时候仍然是10进制,为什么不直接用atoi,或者itoa,
因为时间是60进制,计算机中所有数据都用16进制保存,这样才可以从寄存器里读出来的数字正确确定时间 。
比如60进制中的14分钟和59分钟,我们用串口出入14和59时,先用atoh,14转化为49+52,59转化为53+57,
这是16进制的10进制表示,把这个结果赋给寄存器,当我们读出来的时候101和110怎么转化为原来的分钟呢
,原来的一个十进制中的数101,怎么转化为两位的14,就是进去两个48,是5,5用什么公式转化为1和4,至少当前我不会,所以理解到这里就行了。
19 7500正好10秒。