微型计算机技术及应用实验指导书

时间:2015-12-19 19:02:54
【文件属性】:

文件名称:微型计算机技术及应用实验指导书

文件大小:2.54MB

文件格式:DOC

更新时间:2015-12-19 19:02:54

单片机

微型计算机技术及应用实验指导书#include #include #define uchar unsigned char #define somenop {_nop_();_nop_();_nop_();} uchar code overtemperature[]={"OVERTEMPERATURE!"}; uchar code digit[]={"0123456789"}; uchar mode,TH,TL,TN,TD,tempswitch; uchar Maxtemp=29,amode,alarmmode,minutes,hours,weeks,minutea,seconds,houra=12,days,months,years; sbit SCLK=P1^7; //DS1302时钟输入 sbit DATE=P2^3; //DS1302数据输入 sbit REST=P1^3; //DS1302复位端口 sbit SET=P3^0; //DS1302设置模式选择位 sbit RS=P2^0; sbit RW=P2^1; sbit E=P1^2; sbit BF=P0^7; sbit beep=P0^6; sbit ADD=P3^1; //增加 sbit RED=P3^2; //减小 sbit CANL=P3^3; sbit DQ=P1^4; bit IntDS18B20(void); uchar ReadDS18B20(void); void WriteDS18B20(unsigned char date); void ReadyreadDS18B20(void); void Display_Integer(unsigned char x); void Display_Decimal(unsigned char x); void displayovert(void); void Temperature(void); void delay1ms(int i) { int j,k; while(i--); for(j=76;j>1;j--); for(k=29;k>1;k--); } void delaynus(unsigned char n) { uchar i; for(i=0;i0;i--) { _nop_(); } } void baojing(uchar n) { uchar x,i; while(n--) { beep=0; P2|=0xa0; P2&=0x00; for(i=0;i<5;i++) { for(x=0;x<200;x++) { beep=~beep; P2|=0xa0; P2&=0x00; dely500(); } } for(i=0;i<3;i++) { for(x=0;x<200;x++) { beep=~beep; P2|=0xa0; P2&=0x00; dely500(); dely500(); } } } } /*******DS1302模块*************/ void Write1302(uchar date)//向1302写数据 { uchar i; SCLK=0; delaynus(2); for(i=0;i<8;i++) { DATE=date&0x01; SCLK=1; // delaynus(2); date>>=1; SCLK=0; // delaynus(2); } } void WriteSet1302(uchar cmd,uchar date) //根据相应的命令输入相应的数据 { REST=0; SCLK=0; REST=1; Write1302(cmd); delaynus(5); Write1302(date); DATE=0; REST=0; } uchar Read1302(void) //读取1302数据 { uchar i,date; SCLK=0; delaynus(2); for(i=0;i<8;i++) { date>>=1; if(DATE==1) date|=0x80; SCLK=1; // delaynus(2); SCLK=0; // delaynus(2); } return date; } uchar ReadSet1302(uchar cmd)//根据命令读取1302相应的值 { uchar date; REST=0; SCLK=0; REST=1; Write1302(cmd); delaynus(2); date=Read1302(); DATE=0; REST=0; return date; } void IntDS1302(void) //DS1302初始化 { uchar flag; flag= ReadSet1302(0x81); if(flag&0x80;) //判断时钟芯片是否关闭 { WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令 WriteSet1302(0x80,((0/10)<<4|(0))); //根据写秒寄存器命令字,写入秒的初始值 WriteSet1302(0x82,((50/10)<<4|(9))); //根据写分寄存器命令字,写入分的初始值 WriteSet1302(0x84,((20/10)<<4|(3))); //根据写小时寄存器命令字,写入小时的初始值 WriteSet1302(0x86,((30/10)<<4|(1))); //根据写日寄存器命令字,写入日的初始值 WriteSet1302(0x88,((0/10)<<4|(8))); //根据写月寄存器命令字,写入月的初始值 WriteSet1302(0x8a,((0/10)<<4|(7))); WriteSet1302(0x8c,((10/10)<<4|(2))); //根据写年寄存器命令字,写入年的初始值 WriteSet1302(0x90,0xa5); //打开充电功能 选择2K电阻充电方式 WriteSet1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令 } } /***************液晶显示模块*****************/ /*液晶忙检测*/ bit BusyTest(void) { bit result; RS=0; RW=1; E=1; somenop; result=BF; somenop; E=0; return result; } /*写指令*/ void Write_com(uchar command) { while(BusyTest()!=0); RS=0; RW=0; E=0; somenop; P0=command; somenop; E=1; somenop; E=0; } /*写地址*/ void Write_Address(uchar address) { Write_com(address|0x80); delay1ms(5); } /*写数据*/ void Write_Date(uchar date) { RS=1; RW=0; E=0; somenop; P0=date; somenop; E=1; somenop; E=0; delay1ms(1); } /*初始化*/ void Lcd_Int(void) { Write_com(0x38); Write_com(0x01); Write_com(0x06); Write_com(0x0c); } void displaymainpart(void)//显示液晶主要部分(不变化部分) { Write_Address(0x00); delay1ms(1); Write_Date('D'); Write_Date('A'); Write_Date(':'); delay1ms(1); Write_Address(0x07); delay1ms(1); Write_Date('-'); Write_Address(0x0A); Write_Date('-'); Write_Address(0x40); Write_Date('T'); Write_Date('E'); Write_Date(':'); Write_Address(0x45); Write_Date('-'); Write_Address(0x48); Write_Date('-'); Write_Address(0x03); Write_Date('2'); Write_Date('0'); Write_Address(0x4E); Write_Date('.'); } void display_week(uchar week)//写星期函数 { Write_Address(0x0E);//星期字符的显示位置 switch(week) { case 1:Write_Date('W');//星期数为1时显示 Write_Date('1'); break; case 2:Write_Date('W');//星期数据为2时显示 Write_Date('2'); break; case 3:Write_Date('W');//星期数据为3时显示 Write_Date('3'); break; case 4:Write_Date('W');//星期数据为4是显示 Write_Date('4');break; case 5:Write_Date('W');//星期数据为5时显示 Write_Date('5');break; case 6:Write_Date('W');//星期数据为6时显示 Write_Date('6');break; case 7:Write_Date('W');//星期数据为7时显示 Write_Date('7');break; } } void display_Second(char second) //在液晶上显示秒 { uchar i,j; i=second/10; j=second; Write_Address(0x49); Write_Date(digit[i]); Write_Date(digit[j]); delay1ms(1); } void display_Minute(char minute) //在液晶上显示分 { uchar i,j; i=minute/10; j=minute; Write_Address(0x46); Write_Date(digit[i]); Write_Date(digit[j]); delay1ms(1); } void display_Hour(char hour) //在液晶上显示时 { uchar i,j; i=hour/10; j=hour; Write_Address(0x43); Write_Date(digit[i]); Write_Date(digit[j]); delay1ms(1); } void display_Day(uchar day) //在液晶上显示日 { uchar i,j; i=day/10; j=day; Write_Address(0x0B); Write_Date(digit[i]); Write_Date(digit[j]); delay1ms(1); } void display_Month(uchar month) //在液晶上显示月 { uchar i,j; i=month/10; j=month; Write_Address(0x08); Write_Date(digit[i]); Write_Date(digit[j]); delay1ms(1); } void display_Year(uchar year) //在液晶上显示年 { uchar i,j; i=year/10; j=year; Write_Address(0x05); Write_Date(digit[i]); Write_Date(digit[j]); delay1ms(1); } void display_houra(unsigned char x) //闹钟小时部分显示 { unsigned char i,j; i=x/10; j=x; Write_Address(0x44); Write_Date(digit[i]); Write_Date(digit[j]); } void display_minutea(unsigned char x)//闹钟分钟部分显示 { unsigned char i,j; i=x/10; j=x; Write_Address(0x47); Write_Date(digit[i]); Write_Date(digit[j]); } void display_Time(void) //显示实时时间 { uchar value; Write_com(0x0c); value=ReadSet1302(0x81); //读取数据(1302的读寄存器与写寄存器不一样) seconds=(((value&0x70;)>>4)*10+(value&0x0f;)); //BCD码转十进制,输入BCD返回十进制 display_Second(seconds); value=ReadSet1302(0x83); minutes=(((value&0x70;)>>4)*10+(value&0x0f;)); display_Minute(minutes); value=ReadSet1302(0x85); hours=(((value&0x70;)>>4)*10+(value&0x0f;)); display_Hour(hours); value=ReadSet1302(0x8b); weeks=(((value&0x70;)>>4)*10+(value&0x0f;)); display_week(weeks); value=ReadSet1302(0x87); days=(((value&0x70;)>>4)*10+(value&0x0f;)); display_Day(days); value=ReadSet1302(0x89); months=(((value&0x70;)>>4)*10+(value&0x0f;)); display_Month(months); value=ReadSet1302(0x8D); years=(((value&0x70;)>>4)*10+(value&0x0f;)); display_Year(years); Temperature(); } void gbdisplay(uchar address) //时间调整时光标闪烁 { Write_Address(address); delay1ms(5); Write_com(0x0f); delay1ms(5); } void displaymaxt(uchar x) //显示最大温度 { uchar j,k; Write_com(0x0c); delay1ms(2); Write_Address(0x44); j=x/10; k=x; Write_Date(digit[j]); Write_Date(digit[k]); } /*****************时间调整部分*********************/ void hourset(void) //调时 { char timevalue,hour; delay1ms(500); //防止多次触发 WriteSet1302(0x8e,0x00);//将写保护去掉,确保能正常将调整后的数值写入DS1302 timevalue=ReadSet1302(0x85); //读取此时的数值 hour=(((timevalue&0x70;)>>4)*10+(timevalue&0x0f;)); //BCD码转十进制,输入BCD返回十进制 while(1) { if(ADD==0) { delay1ms(10); if(ADD==0) { hour++; while(ADD==0); } } if(RED==0) { delay1ms(10); if(RED==0) { hour--; if(hour<0) hour=23; while(RED==0); } } timevalue=(((hour)/10)<<4|(hour)); WriteSet1302(0x84,timevalue); delay1ms(1); display_Hour(hour); Write_Address(0x44); delay1ms(5); if(hour>23) hour=0; delay1ms(5); if(CANL==0) { mode=0; Write_com(0x0c); break; } if(SET==0) break; } WriteSet1302(0x8e,0x80); } void minuteset(void) //调分 { char timevalue,minute; delay1ms(500); WriteSet1302(0x8e,0x00); timevalue=ReadSet1302(0x83); minute=(((timevalue&0x70;)>>4)*10+(timevalue&0x0f;)); while(1) { if(ADD==0) { delay1ms(10); if(ADD==0) { minute++; if(minute>=60) timevalue=0; while(ADD==0); } } if(RED==0) { delay1ms(10); if(RED==0) { minute--; if(minute<0) minute=59; while(RED==0); } } timevalue=((minute/10)<<4|(minute)); WriteSet1302(0x82,timevalue); delay1ms(1); display_Minute(minute); Write_Address(0x47); delay1ms(5); if(minute>=60) minute=0; delay1ms(5); if(CANL==0) { mode=0; Write_com(0x0c); break; } if(SET==0) break; } WriteSet1302(0x8e,0x80); } void secondset(void) //秒归零 { char second; delay1ms(500); WriteSet1302(0x8e,0x00); while(1) { if(ADD==0) { delay1ms(10); if(ADD==0) { second++; while(ADD==0); } } delay1ms(1); display_Second(second); Write_Address(0x4A); delay1ms(5); if(CANL==0) { mode=0; Write_com(0x0c); break; } if(SET==0) break; } WriteSet1302(0x8e,0x80); } void weekset(void) //调周 { unsigned char weekvalue,week; delay1ms(500); WriteSet1302(0x8e,0x00); weekvalue=ReadSet1302(0x8b); week=(((weekvalue&0x70;)>>4)*10+(weekvalue&0x0f;)); while(1) { if(ADD==0) { delay1ms(10); if(ADD==0) { week++; if(week>=8) week=1; while(ADD==0); } } if(RED==0) { delay1ms(10); if(RED==0) { week--; if(week==0) week=7; while(RED==0); } } weekvalue=((week/10)<<4|(week)); WriteSet1302(0x8a,weekvalue); delay1ms(1); display_week(week); Write_Address(0x0f); delay1ms(5); if(week>=8) week=1; delay1ms(5); if(CANL==0) { mode=0; Write_com(0x0c); break; } if(SET==0) break; } WriteSet1302(0x8e,0x80); } void yearset(void) //调年 { unsigned char datevalue,year; delay1ms(500); WriteSet1302(0x8e,0x00); datevalue=ReadSet1302(0x8d); year=(((datevalue&0x70;)>>4)*10+(datevalue&0x0f;)); while(1) { if(ADD==0) { delay1ms(10); if(ADD==0) { year++; while(ADD==0); } } if(RED==0) { delay1ms(10); if(RED==0) { year--; while(RED==0); } } datevalue=((year/10)<<4|(year)); WriteSet1302(0x8c,datevalue); delay1ms(5); display_Year(year); delay1ms(5); Write_Address(0x06); delay1ms(5); if(CANL==0) { mode=0; Write_com(0x0c); break; } if(SET==0) break; } WriteSet1302(0x8e,0x80); } void monthset(void) //调月 { unsigned char datevalue,month; delay1ms(500); WriteSet1302(0x8e,0x00); datevalue=ReadSet1302(0x89); month=(((datevalue&0x70;)>>4)*10+(datevalue&0x0f;)); while(1) { if(ADD==0) { delay1ms(10); if(ADD==0) { month++; if(month>12) month=1; while(ADD==0); } } if(RED==0) { delay1ms(10); if(RED==0) { month--; if(month==0) month=12; while(RED==0); } } datevalue=((month/10)<<4|(month)); WriteSet1302(0x88,datevalue); delay1ms(1); display_Month(month); Write_Address(0x09); delay1ms(5); if(CANL==0) { mode=0; Write_com(0x0c); break; } if(SET==0) break; } WriteSet1302(0x8e,0x80); } void dayset(void) //调日 { unsigned char datevalue,day; delay1ms(500); WriteSet1302(0x8e,0x00); datevalue=ReadSet1302(0x87); day=(((datevalue&0x70;)>>4)*10+(datevalue&0x0f;)); while(1) { if(ADD==0) { delay1ms(10); if(ADD==0) { day++; if(day>31) day=1; while(ADD==0); } } if(RED==0) { delay1ms(10); if(RED==0) { day--; if(day==0) day=31; while(RED==0); } } datevalue=((day/10)<<4|(day)); WriteSet1302(0x86,datevalue); delay1ms(1); display_Day(day); Write_Address(0x0c); delay1ms(5); if(CANL==0) { mode=0; Write_com(0x0c); break; } if(SET==0) break; } WriteSet1302(0x8e,0x80); } void alarmhourset(void) //闹钟小时调整 { unsigned char value; value=houra; while(1) { if(ADD==0) { delay1ms(20); if(ADD==0) { Write_com(0x0c); delay1ms(5); value++; if(value>23) value=0; while(ADD==0); } } if(RED==0) { delay1ms(20); if(RED==0) { value--; if(value==0) value=23; while(RED==0); } } houra=value; display_houra(houra); gbdisplay(0x45); if(CANL==0) { delay1ms(500); break; } } } void alarmminuteset(void) //闹钟分钟调整 { while(1) { if(ADD==0) { delay1ms(20); if(ADD==0) { minutea++; if(minutea>59) minutea=0; while(ADD==0) ; } } if(RED==0) { delay1ms(20); if(RED==0) { minutea--; if(minutea==0) minutea=59; while(RED==0) ; } } display_minutea(minutea); gbdisplay(0x48); if(CANL==0) { delay1ms(500); break; } } } void TimeSet(void) //时间调整函数 { display_Time(); if(SET==0) { delay1ms(10); if(SET==0) { while(!SET); mode++; delay1ms(20); switch(mode) { case(1):{gbdisplay(0x44);hourset(); delay1ms(500);} break; case(2):{gbdisplay(0x47);minuteset();delay1ms(500);} break; case(3):{gbdisplay(0x49);secondset();delay1ms(500);} break; case(4):{gbdisplay(0x0f);weekset();delay1ms(500);} break; case(5):{gbdisplay(0x06);yearset();delay1ms(500);} break; case(6):{gbdisplay(0x09);monthset();delay1ms(500);} break; case(7):{gbdisplay(0x0c);dayset();delay1ms(500);} break; } if(mode==8) mode=0; } } } /***************显示温度模块********************/ uchar flag; uchar time; /**********************DS18B20初始化****************************/ bit IntDS18B20(void) { bit temp; DQ=1; for(time=0;time<2;time++); DQ=0; for(time=0;time<200;time++); DQ=1; for(time=0;time<10;time++); temp=DQ; for(time=0;time<200;time++); return temp; } /**************************读DS18B20**********************/ uchar ReadDS18B20(void) { uchar i; uchar dat; for(i=0;i<8;i++) { DQ=1; _nop_(); DQ=0; _nop_(); DQ=1; for(time=0;time<2;time++); dat>>=1; if(DQ==1) dat=dat|0x80; else dat=dat|0x00; for(time=0;time<10;time++); } return dat; } /*********************向DS18B20写数据**************************/ void WriteDS18B20(uchar date) { unsigned char i; for(i=0;i<8;i++) { DQ=1; _nop_(); DQ=0; DQ=date&0x01; for(time=0;time<10;time++); DQ=1; for(time=0;time<1;time++); date>>=1; } for(time=0;time<4;time++); } /*******************为读取温度做好准备************************/ void ReadyreadDS18B20(void) { IntDS18B20(); WriteDS18B20(0XCC); //跳过ROM WriteDS18B20(0X44);//启动温度转换 delay1ms(200); IntDS18B20(); WriteDS18B20(0XCC); WriteDS18B20(0XBE); //读取暂存器的内容,从0字节开始 } /*********************显示温度整数部分*************************/ void Display_Integer(uchar x) { unsigned char j,k; j=x/10; k=x; Write_Address(0x4C); if(flag==1) Write_Date('-'); Write_Date(digit[j]); Write_Date(digit[k]); } /************显示温度小数部分*********************/ void Display_Decimal(uchar x) { Write_Address(0x4F); Write_Date(digit[x]); } void displayovert(void) { unsigned char i; Write_com(0x01); delay1ms(10); Write_Address(0x03); delay1ms(10); Write_Date('W'); Write_Date('A'); Write_Date('R'); Write_Date('N'); Write_Date('I'); Write_Date('N'); Write_Date('G'); Write_Date('!'); Write_Address(0x40); while(overtemperature[i]!='\0') { Write_Date(overtemperature[i]); i++; } } /*******************温度主函数********************/ void Temperature(void) { unsigned char i; if(IntDS18B20()==0) { delay1ms(1); for(i=0;i<1;i++) { flag=0; ReadyreadDS18B20(); TL=ReadDS18B20(); TH=ReadDS18B20(); if((TH&0XF8;)!=0X00) { flag=1; TL=~TL; TH=~TH; TL+=1; if(TL>255) TH+=1; TN=TH*16+TL/16; TD=(TL)*10/16; } TN=TH*16+TL/16; TD=(TL)*10/16; Display_Integer(TN); //温度整数 Display_Decimal(TD); //小数 } if(tempswitch==1) { if(TN>=Maxtemp) { Write_Address(0x03); displayovert(); while(1) { baojing(1); if(CANL==0) { Write_com(0x01); break; } } } } } } void tempset(void) { if(ADD==0) { delay1ms(10); if(ADD==0) { Maxtemp++; while(ADD==0); } } if(RED==0) { delay1ms(10); if(RED==0) { Maxtemp--; while(RED==0); } } } void Maxtempset(void) //高温报警设置 { Write_com(0x01); delay1ms(10); Write_Address(0x03); delay1ms(10); Write_Date('T'); Write_Date('E'); Write_Date('M'); Write_Date('P'); Write_Address(0x09); Write_Date('S'); Write_Date('E'); Write_Date('T'); Write_Address(0x40); Write_Date('M'); Write_Date('A'); Write_Date('X'); Write_Date(':'); while(1) { if(SET==0) { delay1ms(20); if(SET==0) { Write_Address(0x4e); Write_com(0x0f); while(1) { if(ADD==0) { delay1ms(20); if(ADD==0) { Write_Address(0x4b); delay1ms(5); Write_Date('O'); Write_Date('N'); Write_Date(' '); tempswitch=1; } } if(RED==0) { delay1ms(20); if(RED==0) { Write_Address(0x4b); Write_Date('O'); Write_Date('F'); Write_Date('F'); tempswitch=0; } } if(CANL==0) { delay1ms(500); break; } } } } if(tempswitch==1) { Write_Address(0x4b); Write_Date('O'); Write_Date('N'); Write_Date(' '); tempset(); displaymaxt(Maxtemp); if(CANL==0) { Write_com(0x01); displaymainpart(); break; } } if(tempswitch==0) { Write_com(0x0c); Write_Address(0x4b); Write_Date('O'); Write_Date('F'); Write_Date('F'); } if(CANL==0) { Write_com(0x01); displaymainpart(); break; } } } void alarmswitchset(void) { while(1) { if(ADD==0) { delay1ms(100); if(ADD==0) { alarmmode=1; Write_Address(0x4c); Write_Date('O'); Write_Date('N'); Write_Date(' '); } } if(RED==0) { alarmmode=0; Write_Address(0x4c); Write_Date('O'); Write_Date('F'); Write_Date('F'); } if(CANL==0) { delay1ms(500); break; } } } /**************** 设置模块 ******************/ void Set(void) { // ENK = 0; if(SET==0) { delay1ms(10); if(SET==0) { Write_com(0x0f); delay1ms(1000); Write_com(0x0c); while(1) { TimeSet(); if(ADD==0) { delay1ms(20); if(ADD==0) { Write_com(0x01); Write_Address(0x00); delay1ms(5); Write_Date('S'); delay1ms(10); Maxtempset(); } } if(RED==0) { delay1ms(20); if(RED==0) { Write_com(0x01); delay1ms(5); Write_Address(0x01); delay1ms(10); Write_Date('T'); Write_Date('I'); Write_Date('M'); Write_Date('E'); Write_Address(0x09); Write_Date('S'); Write_Date('E'); Write_Date('T'); Write_Address(0x46); Write_Date('-'); display_houra(houra); display_minutea(minutea); if(alarmmode==1) { Write_Address(0x4c); Write_Date('O'); Write_Date('N'); Write_Date(' '); } if(alarmmode==0) { Write_Address(0x4c); Write_Date('O'); Write_Date('F'); Write_Date('F'); } while(1) { if(SET==0) { delay1ms(100); if(SET==0) { amode++; switch(amode) { case(1):{gbdisplay(0x45);alarmhourset();Write_com(0x0c);delay1ms(500);} break; case(2):{gbdisplay(0x48);alarmminuteset();Write_com(0x0c);delay1ms(500);} break; case(3):{gbdisplay(0x4c);alarmswitchset();Write_com(0x0c);delay1ms(500);} break; } if(amode==4) amode=0; } } if(CANL==0) { Write_com(0x01); delay1ms(5); displaymainpart(); break; } } } } if(CANL==0) { Write_Address(0x40); Write_Date(' '); Write_com(0x0c); break; } } } } } /***************主函数**********************/ void main() { IE=0X82; //打开定时中断 TMOD=0X01; //选择定时器0工作在方式1 TR0=0; //启动定时器0 bee IntDS1302(); //初始化DS1302 delay1ms(1); Lcd_Int(); //1602液晶初始化 delay1ms(2); while(1) { displaymainpart(); display_Time( ); Set( ); if(ADD==0) { Write_com(0x01); // Temperature(); Write_com(0x01); displaymainpart(); } if((hours==houra)&&(minutes==minutea)&&(seconds==0)) { if(alarmmode==1) { Write_com(0x01); delay1ms(5); Write_Address(0x03); Write_Date('T'); Write_Date('I'); Write_Date('M'); Write_Date('E'); Write_Address(0x08); Write_Date('U'); Write_Date('P'); Write_Date('!'); delay1ms(5); while(1) { baojing(1); if(CANL==0) { Write_com(0x01); delay1ms(5); displaymainpart(); break; } } } } } }


网友评论

  • 还以为是汇编代码来着。。。