【ARM】2440裸机系列-RTC数字时钟
功能
裸机程序,实现LCD显示数字时钟
主要代码
1)背景绘制
void Brush_ U32 c) { int x,y ; for ( y = 0 ; y < LCD_HEIGHT ; y++ ) { for ( x = 0 ; x < LCD_WIDTH ; x++ ) { LCD_BUFFER[y][x] = c ; } } }
2)文字绘制
void Draw_Text16(U32 x,U32 y,U32 color,U32 backColor,const unsigned char ch[]) { unsigned short int i,j; unsigned char mask,buffer; /*一个汉字16行*/ for (i=0;i<16;i++) { /*汉字左半部分*/ mask=0x80; //从bit7开始判断 buffer=ch[i*2]; //提取一行的第一个字节 /*一个字节有8个位,每一位代表字模数据对应的点是否描颜色*/ for (j=0;j<8;j++) { if (buffer&mask) { PutPixel(x+j,y+i,color); //为笔画上色 } else { PutPixel(x+j,y+i,backColor); //背景色 } mask=mask>>1; //移位,为判断下一位作准备 } /*汉字右半部分*/ mask=0x80; //从bit7开始判断 buffer=ch[i*2+1]; //提取一行的第二个字节 /*一个字节有8个位,每一位代表字模数据对应的点是否描颜色*/ for (j=0;j<8;j++) { if (buffer&mask) { PutPixel(x+j+8,y+i,color); //为笔画上色 } else { PutPixel(x+j+8,y+i,backColor);//背景色 } mask=mask>>1; //移位,为判断下一位作准备 } } }
3)时钟设置
void RTC_Time_Set( void ) { /*RTC读写使能,选择BCD时钟、计数器,无复位,1/32768*/ rRTCCON = 1 ; rBCDYEAR = 0x13; /*年*/ rBCDMON = 0x05; /*月*/ rBCDDATE = 0x09; /*日*/ rBCDDAY = 0x04; /*星*/ rBCDHOUR = 0x10; /*小时*/ rBCDMIN = 0x57; /*分*/ rBCDSEC = 0x20; /*秒*/ /*关读写使能*/ rRTCCON &= ~1 ; }
4)数字绘制
void Draw_Text_8_16(U32 x,U32 y,U32 color,U32 backColor,const unsigned char *chs) { U32 i=0; while (*chs != '\0') { //汉字内码都是大于0xa0 if (*chs > 0xa0) { /*查汉字表*/ for (i=0 ;i < GB16_NUM();i++) { /*换行*/ if(x>235) { x=0; y=y+16; } /*判断汉字是否匹配*/ if ((*chs == hz_index[i]) && (*(chs+1) == hz_index[i+1])) { /*写汉字*/ Draw_Text16(x,y,color,backColor,&hz[16*(i)]); /*增加X坐标值,为写下一个汉字或字符作准备*/ x +=16; break; } } /*字符串指针加2,一个汉字编译后内码占两个字节*/ chs+=2; } /*如果是字符*/ else { /*换行*/ if(x>230) { x=0; y=y+16; } /*查字符表*/ for (i=0 ;i < ASCII_NUM();i++) { /*判断字符是否匹配*/ if (*chs == zf_index[i]) { /*写字符*/ Draw_ASCII(x,y,color,backColor,&zf[16*i]); /*增加X坐标值,为写下一个汉字或字符作准备*/ x += 8; break; } } /*字符串指针加1,一个字符编译后内码占1个字节*/ chs++; } } }
5)时钟显示
void rtc_display_lcd(void) { //0 1 2 3 4 unsigned char time[]={'2','0','1','3','-', //5 6 7 8 9 10 '0','5','-','0','9',' ', //11 12 13 14 15 16 17 18 '1','5',':','2','1',':','5','9', '\0'}; time[2]=rBCDYEAR/16+'0'; //年十位,16进制 time[3]=rBCDYEAR%16+'0'; //年个位 time[5]=rBCDMON/16+'0'; //月十位 time[6]=rBCDMON%16+'0'; //月个位 time[8]=rBCDDATE/16+'0'; //天十位 time[9]=rBCDDATE%16+'0'; //天个位 time[11]=rBCDHOUR/16+'0'; //时十位 time[12]=rBCDHOUR%16+'0'; //时个位 time[14]=rBCDMIN/16+'0'; //分十位 time[15]=rBCDMIN%16+'0'; //分个位 time[17]=rBCDSEC/16+'0'; //秒十位 time[18]=rBCDSEC%16+'0'; //秒个位 /*调用LCD显示时间程序*/ if(time[18]%2==1) { time[16]=':'; } else { time[16]=' '; } Draw_Text_8_16(50,220,0x0,0xffff,(const unsigned char * )time); }
6)实时刷新
while (1) { /*读取时间,并LCD显示*/ rtc_display_lcd(); for(r=0;r<3;r++) { for(a=0;a<(2*PI);) { X=(int)(r*cos(a)+120); Y=(int)(r*sin(a)+120); LCD_BUFFER[Y][X]=0X00; a=a+(PI/360); } } /************秒指针的显示*************/ n=(rBCDSEC/16)*10+(rBCDSEC%16); if(secondbit!=n) { for(w=0;w<66;w++)//清前一秒秒表指针,必须要清掉 { X=(int)(w*cos((3*PI/2)+secondbit*(PI/30))+120); Y=(int)(w*sin((3*PI/2)+secondbit*(PI/30))+120); LCD_BUFFER[Y][X]=0Xffff; } for(w=0;w<66;w++) //显示当前秒表指针 { X=(int)(w*cos((3*PI/2)+n*(PI/30))+120); Y=(int)(w*sin((3*PI/2)+n*(PI/30))+120); LCD_BUFFER[Y][X]=0X00; } } /************分指针的显示*************/ m=(rBCDMIN/16)*10+(rBCDMIN%16); if(minbit!=m||m==secondbit) { for(w=0;w<55;w++)//清前一秒分钟指针 { X=(int)(w*cos((3*PI/2)+minbit*(PI/30))+120); Y=(int)(w*sin((3*PI/2)+minbit*(PI/30))+120); LCD_BUFFER[Y][X]=0Xffff; } for(w=0;w<55;w++) //显示当前分钟指针 { X=(int)(w*cos((3*PI/2)+m*(PI/30))+120); Y=(int)(w*sin((3*PI/2)+m*(PI/30))+120); LCD_BUFFER[Y][X]=0X00; } } /************小时指针的显示*************/ h=(rBCDHOUR/16)*10+(rBCDHOUR%16); if(h>12) h-=12; if(hourbit!=h||h==(minbit/5)||h==(secondbit/5)) { for(w=0;w<38;w++)//清前一小时指针 { X=(int)(w*cos((3*PI/2)+hourbit*(PI/30))+120); Y=(int)(w*sin((3*PI/2)+hourbit*(PI/30))+120); LCD_BUFFER[Y][X]=0xffff; } for(w=0;w<38;w++) //显示当前小时指针 { X=(int)(w*cos((3*PI/2)+h*(PI/6))+120); Y=(int)(w*sin((3*PI/2)+h*(PI/6))+120); LCD_BUFFER[Y][X]=0X00; } } hourbit = h; minbit = m; secondbit = n; }
时钟效果