三. 软件设计
3.1编程语言及编程软件的选择
本设计选择C语言作为编程语言。C语言虽然执行效率没有汇编语言高,但语言简洁,使用方便,灵活,运算丰富,表达化类型多样化,数据结构类型丰富,具有结构化的控制语句,程序设计自由度大,有很好的可重用性,可移植性等特点。 而汇编语言使用起来并没有这么方便。
本设计选用了Keil作为编程软件,.Keil C51生成的目标代码效率非常之
高,多数语句生成的汇编代码很紧凑,容易理解。在开发大型软件时更能体现高级语言的优势。
3.2时间的显示
ML016L和1602一样,都是两行十六列的液晶显示屏。通过程序对ML016L进行初始化后,通过写指令和写数据的操作就可以再液晶屏上显示出对应的数据,而时钟数据则是从DS1302获取。这样可以显示出时间。
四. 程序
#include
#define uchar unsigned char #define uint unsigned int sbit rs=P2^0; //1602命令\\数据选择端 sbit e=P2^1; //1602使能端 sbit sck=P3^6; //DS1302 sbit io=P3^7; //DS1302数据端 sbit rst=P3^5; //DS1302 CE端 RST的功能 uint temp; //定义整型的温度数据 float f_temp;
uchar code num[]=\ // 定义浮点型的温度数据 uchar code nian[]=\ - - %uchar code shi[]=\ : : \
uchar read_add[]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81}; //DS1302读数据地址端
uchar write_add[]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80}; //DS1302写数据地址端
uchar time_data[]={11,1,12,5,18,00,00}; //设置初始时间 uchar disp[14]; //定义数组 void delayms(uint z) //毫秒级延时函数 { uint i,j; for(i=z;i>0;i--) for(j=120;j>0;j--); }
void delayus(uint time) { while(time--); }
//1602液晶
void write_com(uchar com) { rs=0; P0=com; delayms(5); e=1; delayms(5); e=0; }
void write_data(uchar date) { rs=1; P0=date; delayms(5); e=1; delayms(5); e=0; }
void init() { uchar num; write_com(0x38); write_com(0x06); write_com(0x0c); write_com(0x01); write_com(0x80+0x40); for(num=0;num<8;num++) {
//微秒级延时函数 //写指令函数 //写数据函数 //液晶初始化函数 write_data(shi[num]); delayms(1); } write_com(0x80); for(num=0;num<10;num++) { write_data(nian[num]); delayms(1); } }
//DS1302
void write_ds1302_byte(uchar dat) { uchar i; for(i=0;i<8;i++) { sck=0; io=dat&0x01; dat=dat>>1; sck=1; } }
void write_ds1302(uchar add,uchar dat) { rst=0; _nop_(); sck=0; _nop_(); rst=1; _nop_(); write_ds1302_byte(add); write_ds1302_byte(dat); rst=0; _nop_(); io=1; sck=1; }
uchar read_ds1302(uchar add) { uchar i,value; rst=0; _nop_(); sck=0; _nop_();
//写一个字节函数
//写一个地址和数据函数//读地址函数
rst=1; _nop_(); write_ds1302_byte(add); for(i=0;i<8;i++) { value=value>>1; sck=0; if(io) value=value|0x80; sck=1; } rst=0; _nop_(); sck=0; _nop_(); sck=1; io=0; return value; } void read_rtc(void) //读时钟函数 { uchar i; for(i=0;i<7;i++) { time_data[i]=read_ds1302(read_add[i]); } } void z(void) //周 { write_com(0x80+0x40+9); switch(disp[2]) { case 1: write_data('M'); delayms(5); write_data('o'); delayms(5); write_data('n'); break; case 2: write_data('T'); delayms(5); write_data('u'); delayms(5); write_data('e'); break;
case 3: write_data('W'); delayms(5); write_data('e'); delayms(5); write_data('n'); break; case 4: write_data('T'); delayms(5); write_data('h'); delayms(5); write_data('u'); break; case 5: write_data('F'); delayms(5); write_data('r'); delayms(5); write_data('i'); break; case 6: write_data('S'); delayms(5); write_data('a'); delayms(5); write_data('t'); break; case 7: write_data('S'); delayms(5); write_data('u'); delayms(5); write_data('n'); break; } }
void time_change(void) { disp[0]=time_data[0]; disp[1]=time_data[0]/16; disp[2]=time_data[1]; disp[3]=time_data[1]/16; disp[4]=time_data[2]; disp[5]=time_data[2]/16; disp[6]=time_data[3]; disp[7]=time_data[3]/16; disp[8]=time_data[4]; disp[9]=time_data[4]/16; //时钟处理函数//年
//周 //月 //日 //时
disp[10]=time_data[5]; disp[11]=time_data[5]/16; disp[12]=time_data[6]; disp[13]=time_data[6]/16; } void display() { write_com(0x80+2); write_data(0x30+disp[1]); write_data(0x30+disp[0]); z(); write_com(0x80+5); write_data(0x30+disp[5]); write_data(0x30+disp[4]); write_com(0x80+8); write_data(0x30+disp[7]); write_data(0x30+disp[6]); write_com(0x80+0x40); write_data(0x30+disp[9]); write_data(0x30+disp[8]); write_com(0x80+0x40+3); write_data(0x30+disp[11]); write_data(0x30+disp[10]); write_com(0x80+0x40+6); write_data(0x30+disp[13]); write_data(0x30+disp[12]); /*write_com(0x80+0x40+9); write_data(0x30+disp[2]);*/ }
void main() { uchar i; init(); write_com(0x80+14); write_data('.'); //set_rtc(); while(1) { read_rtc(); display(); } }
//分 //秒
//时钟显示函数
//年
//周 //月
//日
//时
//分
//秒