|
電路原理圖如下:
單片機(jī)源程序如下:
- /*-------------------------------------------
- 程序名: 32*8點(diǎn)陣屏電子鐘
- 編寫人: 杜洋
- CPU說明: MCS-51(AT89S52) 12MHZ
- 接口說明: DS1302、DS18B20
- 修改日志:
- NO.1-20051215 完成LED驅(qū)動(dòng)、顯示切換、時(shí)鐘溫度讀取
- NO.2-20051216 完成整點(diǎn)報(bào)時(shí)、填加注釋信息
- NO.3-20051220 完成了調(diào)時(shí)、按鍵音等所以的功能(沒有鬧鐘)
- NO.3-20051221 增加了十位為0時(shí)的消隱功能
- --------------------------------------------*/
- //------------------------------定義頭文件
- #include <reg51.h>//MCS-51單片機(jī)
- //------------------------------定義縮寫字符
- #define uchar unsigned char
- #define uint unsigned int
- //------------------------------定義揚(yáng)聲器接口,低電平使能
- sbit Bell_Out = P1 ^ 5;//揚(yáng)聲器驅(qū)動(dòng)
- //------------------------------定義DS18B20音
- sbit DQ = P1 ^ 6;//ds1820data(單總線)
- //------------------------------定義DS1302時(shí)鐘接口
- sbit clock_clk = P3 ^ 5;//ds1302_clk(時(shí)鐘線)
- sbit clock_dat = P3 ^ 6;//ds1302_dat(數(shù)據(jù)線)
- sbit clock_Rst = P3 ^ 7;//ds1302_Rst(復(fù)位線)
- //-----------------------------定義數(shù)據(jù)口
- #define Led_13 P0 //第1、3屏數(shù)據(jù)口
- #define Led_24 P2 //第2、4屏數(shù)據(jù)口
- #define Led_E P1 //74HC154的BCD列驅(qū)動(dòng)(P1.0~P1.4)
- sbit Led_EA = P1 ^ 4;//顯示列驅(qū)動(dòng)器(74HC154)使能
- //-----------------------------獨(dú)立鍵盤定義
- sbit Add_Key = P3 ^ 1;//前位加1鍵
- sbit Add2_Key = P3 ^ 0;//后位加1鍵
- sbit OK_Key = P3 ^ 2;//確定鍵
- sbit int_Key = P3 ^ 3;//中斷入口
- //-----------------------------定義累加器A中的各位
- sbit a0 = ACC ^ 0;
- sbit a1 = ACC ^ 1;
- sbit a2 = ACC ^ 2;
- sbit a3 = ACC ^ 3;
- sbit a4 = ACC ^ 4;
- sbit a5 = ACC ^ 5;
- sbit a6 = ACC ^ 6;
- sbit a7 = ACC ^ 7;
- //------------------------------------定義全局變量
- bit txx = 0;
- uchar settime;//定義標(biāo)志位
- uchar yy,mo,dd,xq,hh,mm,bn;//定義時(shí)間映射全局變量(專用寄存器)
- static uchar timecount = 0;//定義靜態(tài)軟件計(jì)數(shù)器變量
- static uchar pp = 0;//定義靜態(tài)小時(shí)更新用數(shù)據(jù)變量
- //------------------------------------函數(shù)聲明(按字母順序排列)
- void Beep(void);
- void Beep_key(void);
- void Beep_set(void);
- void clearRAM (void);
- uchar clock_in(void);
- void clock_out(uchar dd);
- void Delay(int num);
- void DelayM(uint a);
- void display (void);
- void display_s (void);
- void Init_1302(void);
- void int1 (void);
- void putin (uchar u);
- uchar read_clock(uchar ord);
- void read_clockS(void);
- void Set_time(unsigned char sel);
- void setput (uchar k);
- void Timer0(void);
- void Timer0_Init(void);
- void write_clock(uchar ord, uchar dd);
- uchar DL (uchar);
- uchar DSS (void);
- //-----------------------------定義顯示緩沖寄存器(32個(gè)字節(jié)全局變量)
- uchar Ledplay [35];//
- //-----------------------------定義字符數(shù)據(jù)表單(二維數(shù)組)
- uchar code no[][10]={
- //-----------------------------------數(shù)字字符表
- {0x7E,0xFF,0x81,0x81,0xFF,0x7E,0},//0
- {0x82,0xFF,0xFF,0x80,0}, //1
- {0xC6,0xE7,0xB1,0x99,0x8F,0x86,0},//2
- {0x42,0xC3,0x89,0x89,0xFF,0x76,0},//3
- {0x30,0x28,0xA6,0xFF,0xFF,0xA0,0},//4
- {0x4F,0xCF,0x89,0x89,0xF9,0x71,0},//5
- {0x7E,0xFF,0x89,0x8B,0xFB,0x70,0},//6
- {0x03,0x03,0xF9,0xFF,0x07,0},//7
- {0x76,0xFF,0x89,0x89,0xFF,0x76,0},//8
- {0x0E,0xDF,0xD1,0x91,0xFF,0x7E,0},//9
- //-----------------------------------星期字符表
- {0x10,0x10,0x10,0x10,0x10,0x10,0x18,0x10,0},//一10
- {0x40,0x44,0x44,0x44,0x44,0x44,0x44,0x40,0},//二
- {0x82,0x92,0x92,0x92,0x92,0x92,0x82,0x80,0},//三
- {0xFE,0xA2,0x9E,0x82,0x9E,0xA2,0xFE,0},//四
- {0x80,0x89,0xFF,0x89,0x89,0x89,0xF9,0x80,0},//五
- {0x88,0x68,0x38,0x0E,0x38,0x68,0x88,0},//六
- {0xFE,0x92,0x92,0x92,0x92,0xFE,0},//日 10+6
- //-----------------------------------特殊字符表
- {0x6C,0x6C,0},//“:” 17
- {0x18,0x18,0x18,0x18,0},//“-” 18
- {0x06,0x06,0x78,0xFC,0x84,0x84,0x84,0x80,0},//“oC” 19
- {0x02,0x8E,0xFC,0xFC,0x8E,0x02,0},//“Y”(在調(diào)時(shí)時(shí)表示年)20
- {0x80,0x7E,0x15,0x15,0x95,0xFF,0},//“月”21
- {0xFE,0x92,0x92,0x92,0x92,0xFE,0}//“日”22
- };
- //-----------------------------------開機(jī)畫面,顯示“DYDIY”
- uchar code dydiy[]={//顯示“DYDIY”
- 0x82,0xFE,0xFE,0x82,0xFE,0x7C,0,
- 0x02,0x8E,0xFC,0xFC,0x8E,0x02,0,
- 0x82,0xFE,0xFE,0x82,0xFE,0x7C,0,
- 0x82,0xFE,0xFE,0x82,0,
- 0x02,0x8E,0xFC,0xFC,0x8E,0x02,0,0x99
- };
- //---------------------------------------延時(shí)函數(shù) 2uS/次
- void Delay(int num){
- for (;num>0;num--);
- }
- //---------------------------------------延時(shí)函數(shù) 1MS/次
- void DelayM(unsigned int a){
- unsigned char i;
- while( --a != 0){
- for(i = 0; i < 125; i++); //一個(gè) ; 表示空語句,CPU空轉(zhuǎn)。
- } //i 從0加到125,CPU大概就耗時(shí)1毫秒
- }
- //---------------------------------------1302驅(qū)動(dòng)程序(底層協(xié)議)
- void clock_out(unsigned char dd){
- ACC=dd;
- clock_dat=a0; clock_clk=1; clock_clk=0;
- clock_dat=a1; clock_clk=1; clock_clk=0;
- clock_dat=a2; clock_clk=1; clock_clk=0;
- clock_dat=a3; clock_clk=1; clock_clk=0;
- clock_dat=a4; clock_clk=1; clock_clk=0;
- clock_dat=a5; clock_clk=1; clock_clk=0;
- clock_dat=a6; clock_clk=1; clock_clk=0;
- clock_dat=a7; clock_clk=1; clock_clk=0;
- }
- //---------------------------------------DS1302寫入字節(jié)(底層協(xié)議)
- unsigned char clock_in(void){
- clock_dat=1;
- a0=clock_dat;
- clock_clk=1; clock_clk=0; a1=clock_dat;
- clock_clk=1; clock_clk=0; a2=clock_dat;
- clock_clk=1; clock_clk=0; a3=clock_dat;
- clock_clk=1; clock_clk=0; a4=clock_dat;
- clock_clk=1; clock_clk=0; a5=clock_dat;
- clock_clk=1; clock_clk=0; a6=clock_dat;
- clock_clk=1; clock_clk=0; a7=clock_dat;
- return(ACC);
- }
- //----------------------------------------DS1302讀數(shù)據(jù)(底層協(xié)議)
- uchar read_clock(uchar ord){
- uchar dd=0;
- clock_clk=0;
- clock_Rst=0;
- clock_Rst=1;
- clock_out(ord);
- dd=clock_in();
- clock_Rst=0;
- clock_clk=1;
- return(dd);
- }
- //---------------------------------------常用時(shí)鐘數(shù)據(jù)讀取
- void read_clockS(void){
- mm = read_clock(0x83);//讀取分鐘數(shù)據(jù)
- hh = read_clock(0x85);//小時(shí)
- dd = read_clock(0x87);//日
- mo = read_clock(0x89);//月
- xq = read_clock(0x8b);//星期
- yy = read_clock(0x8d);//年
- }
- //*---------------------------------------DS1302寫數(shù)據(jù)(底層協(xié)議)
- void write_clock(uchar ord, uchar dd){
- clock_clk=0;
- clock_Rst=0;
- clock_Rst=1;
- clock_out(ord);
- clock_out(dd);
- clock_Rst=0;
- clock_clk=1;
- }
- //--------------------------------------------------調(diào)時(shí)用加1程序
- void Set_time(unsigned char sel){ //根據(jù)選擇調(diào)整的相應(yīng)項(xiàng)目加1并寫入DS1302
- signed char address,item;
- signed char max,mini;
- if(sel==7) {address=0x80; max=0;mini=0;} //秒7
- if(sel==6) {address=0x82; max=59;mini=0;} //分鐘6
- if(sel==5) {address=0x84; max=23;mini=0;} //小時(shí)5
- if(sel==3) {address=0x86; max=31;mini=1;} //日3
- if(sel==2) {address=0x88; max=12;mini=1;} //月2
- if(sel==1) {address=0x8c; max=99; mini=0;} //年1
- if(sel==4) {address=0x8a; max=7;mini=1;} //星期4
- //讀取1302某地址上的數(shù)值轉(zhuǎn)換成10進(jìn)制賦給item
- item=((read_clock(address+1))/16)*10 + (read_clock(address+1))%16;
- item++;//數(shù)值加1
- if(item>max) item=mini;//查看數(shù)值有效范圍
- if(item<mini) item=max;
- write_clock(0x8e,0x00);//允許寫操作
- write_clock(address,(item/10)*16+item%10);//轉(zhuǎn)換成16進(jìn)制寫入1302
- write_clock(0x8e,0x80);//寫保護(hù),禁止寫操作
- }
- //--------------------------------------------設(shè)置1302的初始時(shí)間
- void Init_1302(void){//(2005年12月20日12時(shí)00分00秒星期二)
- write_clock(0x8e,0x00);//允許寫操作
- write_clock(0x8c,0x05);//年
- write_clock(0x8a,0x02);//星期
- write_clock(0x88,0x12);//月
- write_clock(0x86,0x20);//日
- write_clock(0x84,0x12);//小時(shí)
- write_clock(0x82,0x00);//分鐘
- write_clock(0x80,0x00);//秒
- write_clock(0x90,0xa5);//充電
- write_clock(0x8e,0x80);//禁止寫操作
- }
- //--------------------------------------------揚(yáng)聲器--整點(diǎn)報(bào)時(shí)
- void Beep(void){//BELL
- uchar a;//定義變量用于發(fā)聲的長度設(shè)置
- Led_EA = 1;//關(guān)列顯示驅(qū)動(dòng),防止屏幕出現(xiàn)亂碼
- for(a=60;a>0;a--){//第一個(gè)聲音的長度
- Bell_Out = ~Bell_Out;//取反揚(yáng)聲器驅(qū)動(dòng)口,以產(chǎn)生音頻
- Delay(100);//音調(diào)設(shè)置延時(shí)
- }
- for(a=100;a>0;a--){//同上
- Bell_Out = ~Bell_Out;
- Delay(80);//
- }
- for(a=100;a>0;a--){//同上
- Bell_Out = ~Bell_Out;
- Delay(30);//
- }
- }
- //--------------------------------------------揚(yáng)聲器--設(shè)置報(bào)警
- void Beep_set(void){//BELL
- uchar a;//定義變量用于發(fā)聲的長度設(shè)置
- Led_EA = 1;//關(guān)列顯示驅(qū)動(dòng),防止屏幕出現(xiàn)亂碼
- for(a=250;a>0;a--){//第一個(gè)聲音的長度
- Bell_Out = ~Bell_Out;//取反揚(yáng)聲器驅(qū)動(dòng)口,以產(chǎn)生音頻
- Delay(20);//音調(diào)設(shè)置延時(shí)
- }
- for(a=100;a>0;a--){//同上
- Bell_Out = ~Bell_Out;
- Delay(80);//
- }
- }
- //----------------------------------------揚(yáng)聲器--按鍵音
- void Beep_key(void){
- uchar a;//定義變量用于發(fā)聲的長度設(shè)置
- Led_EA = 1;//關(guān)列顯示驅(qū)動(dòng),防止屏幕出現(xiàn)亂碼
- for(a=100;a>0;a--){//聲音的長度
- Bell_Out = ~Bell_Out;
- Delay(50);//音調(diào)設(shè)置延時(shí)
- }
- }
- //----------------------------------------32個(gè)寄存器清空(0x00)
- void clearRAM (void){//寄存器清空函數(shù)
- uchar a;//定義變量用于清空數(shù)據(jù)指針
- for(a=0;a<32;a++){//指向32個(gè)寄存器
- Ledplay[a] = 0;//將指向的寄存器清空
- }
- }
- //----------------------------------------將字符裝入顯示寄存器
- void putin (uchar u){//字符載入函數(shù)
- uchar a = 0;//定義變量用于數(shù)據(jù)提取指針
- do{
- Ledplay[bn] = no[u][a];//將二維數(shù)組中的一組數(shù)據(jù)放入顯示緩沖區(qū)
- a++;//換下一個(gè)提取字節(jié)
- bn++;//換下一個(gè)顯示緩沖字節(jié)
- }
- while(no[u][a] != 0);//當(dāng)顯示數(shù)據(jù)為0時(shí)結(jié)束循環(huán)
- bn++;//換下一個(gè)顯示緩沖字節(jié)
- Ledplay[bn] = 0;//顯示一列的空位,便于字符區(qū)分
- }
- //------------------------------------調(diào)時(shí)切換
- void setput (uchar k){
- switch(k){//K為0調(diào)整日期,K為1調(diào)整時(shí)間,K為2調(diào)整年和星期
- case 0:{
- read_clockS();//調(diào)用時(shí)鐘芯片驅(qū)動(dòng)函數(shù),讀出時(shí)鐘數(shù)據(jù)并放入相應(yīng)的寄存器
- clearRAM();//清空顯示緩沖區(qū)數(shù)據(jù)
- bn = 0;//顯示位累加寄存器清零(從頭開始寫入顯示緩沖區(qū))
- if(mo/16 != 0){
- putin(mo/16);//顯示月值(十位,為0時(shí)消隱)
- }
- putin(mo%16);//顯示月值(個(gè)位)
- putin(21);//顯示橫杠“月”
- if(dd/16 != 0){
- putin(dd/16);//顯示日值(十位,為0時(shí)消隱)
- }
- putin(dd%16);//顯示日值(個(gè)位)
- putin(22);//顯示“日”
- }break;
- case 1:{
- read_clockS();//調(diào)用時(shí)鐘芯片驅(qū)動(dòng)函數(shù),讀出時(shí)鐘數(shù)據(jù)并放入相應(yīng)的寄存器
- clearRAM();//清空顯示緩沖區(qū)數(shù)據(jù)
- bn = 0;//顯示位累加寄存器清零(從頭開始寫入顯示緩沖區(qū))
- //if(hh/16 != 0){
- putin(hh/16);//顯示小時(shí)值(十位,為0時(shí)消隱)
- //}
- putin(hh%16);//顯示小時(shí)值(個(gè)位)
- putin(17);//顯示冒號(hào)“:”
- putin(mm/16);//顯示分鐘值(十位)
- putin(mm%16);//顯示分鐘值(個(gè)位)
- }break;
- case 2:{
- read_clockS();//調(diào)用時(shí)鐘芯片驅(qū)動(dòng)函數(shù),讀出時(shí)鐘數(shù)據(jù)并放入相應(yīng)的寄存器
- clearRAM();//清空顯示緩沖區(qū)數(shù)據(jù)
- bn = 0;//顯示位累加寄存器清零(從頭開始寫入顯示緩沖區(qū))
- putin(yy/16);//顯示年(十位)
- putin(yy%16);//顯示年(個(gè)位)
- putin(20);//顯示“Y”表示年
- putin(xq+9);//顯示星期數(shù)據(jù)
- }break;
- default:{//數(shù)據(jù)不附時(shí)退出
- }
- }
- Beep_key();//按鍵音
- }
- //----------------------------------------32*8點(diǎn)陣顯示驅(qū)動(dòng)
- void display (void){//點(diǎn)陣屏驅(qū)動(dòng)函數(shù)
- uchar ac,aa=7;//定義兩個(gè)數(shù)據(jù)變量
- for(ac=0x28;ac<0x30;ac++){//掃描后兩塊LED屏(由于P1.5接揚(yáng)聲器所以高4位為2,旨在關(guān)聲音)
- Led_E = ac;//用ac值驅(qū)動(dòng)使能列信號(hào)
- Led_24 = DL(Ledplay[aa+8]);//將顯示寄存器數(shù)據(jù)寫入2、4屏(嵌入DL匯編是為了翻轉(zhuǎn)字節(jié)數(shù)據(jù),如果接線正確可省去)
- Led_13 = Ledplay[aa];//將顯示寄存器數(shù)據(jù)寫入1、3屏
- Delay(60);//延時(shí)1.2微秒
- Led_13 = 0;//數(shù)據(jù)總線清空
- Led_24 = 0;
- aa--;//aa減1,換下一列顯示
- }
- aa = 23;//指定后16個(gè)數(shù)據(jù)的提取
- for(ac=0x20;ac<0x28;ac++){//掃描前兩塊LED屏
- Led_E = ac;//用ac值驅(qū)動(dòng)使能列信號(hào)
- Led_24 = DL(Ledplay[aa+8]);//將顯示寄存器數(shù)據(jù)寫入2、4屏
- Led_13 = Ledplay[aa];//將顯示寄存器數(shù)據(jù)寫入1、3屏
- Delay(60);//延時(shí)1.2微秒
- Led_13 = 0;//數(shù)據(jù)總線清空
- Led_24 = 0;
- aa--;//aa減1,換下一列顯示
- }
- }
- //--------------------------------------------32*8點(diǎn)陣反色顯示驅(qū)動(dòng)(表示調(diào)時(shí))
- void display_s (void){//點(diǎn)陣屏驅(qū)動(dòng)函數(shù)
- uchar ac,aa=7;//定義兩個(gè)數(shù)據(jù)變量
- for(ac=0x28;ac<0x30;ac++){//掃描后兩塊LED屏(由于P1.5接揚(yáng)聲器所以高4位為2,旨在關(guān)聲音)
- Led_E = ac;//用ac值驅(qū)動(dòng)使能列信號(hào)
- Led_24 = ~DL(Ledplay[aa+8]);//將顯示寄存器數(shù)據(jù)反色寫入2、4屏(嵌入DL匯編是為了翻轉(zhuǎn)字節(jié)數(shù)據(jù),如果接線正確可省去)
- Led_13 = ~Ledplay[aa];//將顯示寄存器數(shù)據(jù)反色寫入1、3屏
- Delay(60);//延時(shí)1.2微秒
- Led_13 = 0;//數(shù)據(jù)總線清空
- Led_24 = 0;
- aa--;//aa減1,換下一列顯示
- }
- aa = 23;//指定后16個(gè)數(shù)據(jù)的提取
- for(ac=0x20;ac<0x28;ac++){//掃描前兩塊LED屏
- Led_E = ac;//用ac值驅(qū)動(dòng)使能列信號(hào)
- Led_24 = ~DL(Ledplay[aa+8]);//將顯示寄存器數(shù)據(jù)反色寫入2、4屏
- Led_13 = ~Ledplay[aa];//將顯示寄存器數(shù)據(jù)反色寫入1、3屏
- Delay(60);//延時(shí)1.2微秒
- Led_13 = 0;//數(shù)據(jù)總線清空
- Led_24 = 0;
- aa--;//aa減1,換下一列顯示
- }
- }
- //-------------------------------------------------------定時(shí)器0初始化
- void Timer0_Init(void){//定時(shí)器0初始(主函數(shù)中被調(diào)用一次)
- TMOD=0x01;//定時(shí)器方式設(shè)置(定時(shí)器工作方式1-16位定時(shí))
- TH0=(65535-50000)/256;//50MS
- TL0=(65535-50000)%256;
- EA=1;//開總中斷
- ET0=1;//開定時(shí)器0中斷允許
- TR0=1;//啟動(dòng)定時(shí)器0
- }
- //===============================================定時(shí)器中斷函數(shù)(產(chǎn)生顯示切換)
- void Timer0(void) interrupt 1 using 0{//定時(shí)器中斷入口,使用第1工作組寄存器
- TH0=(65535-50000)/256; //50ms定時(shí)(定時(shí)器工作方式1)
- TL0=(65535-50000)%256;
- timecount++;//軟件計(jì)數(shù)加1
- if(timecount == 20){//軟件計(jì)數(shù)加到20時(shí)顯示日期(1S)
- Led_EA = 1;//關(guān)列顯示驅(qū)動(dòng),防止屏幕出現(xiàn)亂碼
- read_clockS();//調(diào)用時(shí)鐘芯片驅(qū)動(dòng)函數(shù),讀出時(shí)鐘數(shù)據(jù)并放入相應(yīng)的寄存器
- clearRAM();//清空顯示緩沖區(qū)數(shù)據(jù)
- bn = 0;//顯示位累加寄存器清零(從頭開始寫入顯示緩沖區(qū))
- if(mo/16 != 0){//為0時(shí)消隱
- putin(mo/16);//顯示月值(十位,為0時(shí)消隱)
- }
- putin(mo%16);//顯示月值(個(gè)位)
- putin(21);//顯示“月”
- if(dd/16 != 0){//為0時(shí)消隱
- putin(dd/16);//顯示日值(十位,為0時(shí)消隱)
- }
- putin(dd%16);//顯示日值(個(gè)位)
- putin(22);//顯示“日”
- }
- if(timecount == 40){//軟件計(jì)數(shù)加到40時(shí)顯示時(shí)間(2S)
- Led_EA = 1;//關(guān)列顯示驅(qū)動(dòng),防止屏幕出現(xiàn)亂碼
- clearRAM();//清空顯示緩沖區(qū)數(shù)據(jù)
- bn = 0;//顯示位累加寄存器清零(從頭開始寫入顯示緩沖區(qū))
- if(hh > 6 && hh < 22){//整點(diǎn)報(bào)時(shí)設(shè)為早6時(shí)到晚22時(shí)之間
- if(pp != hh){//當(dāng)小時(shí)值更新時(shí)則啟動(dòng)報(bào)時(shí)
- pp = hh;//將新的小時(shí)值放入更新寄存器
- Beep();//啟動(dòng)報(bào)時(shí)
- }
- }
- //if(hh/16){//為0時(shí)消隱
- putin(hh/16);//顯示小時(shí)值(十位,為0時(shí)消隱)
- //}
- putin(hh%16);//顯示小時(shí)值(個(gè)位)
- putin(17);//顯示冒號(hào)“:”
- putin(mm/16);//顯示分鐘值(十位)
- putin(mm%16);//顯示分鐘值(個(gè)位)
- }
- if(timecount > 80){////軟件計(jì)數(shù)加到80時(shí)顯示時(shí)間(1S)
- uchar ty = 0;//定義溫度寄存器變量
- timecount = 0;//軟件計(jì)數(shù)清零
- Led_EA = 1;//關(guān)列顯示驅(qū)動(dòng),防止屏幕出現(xiàn)亂碼
- ty = DSS();//將DSS匯編程序取得的溫度值放入溫度寄存器變量
- clearRAM();//清空顯示緩沖區(qū)數(shù)據(jù)
- bn = 0;//顯示位累加寄存器清零(從頭開始寫入顯示緩沖區(qū))
- if(ty >99){//當(dāng)溫度高于99度或未發(fā)現(xiàn)溫度傳感器(DS18B20)時(shí)顯示“--”
- putin(18);//顯示“--”
- putin(18);
- }
- else{//溫度小于99度并發(fā)現(xiàn)溫度傳感器(DS18B20)時(shí),顯示溫度值
- if(ty/10 != 0){//為0時(shí)消隱
- putin(ty/10);//溫度值的十位
- }
- putin(ty%10);//溫度值的個(gè)位
- }
- putin(19);//顯示攝氏度符號(hào)“oC”
- putin(xq+9);//顯示星期數(shù)據(jù)
- }
- }
- //===============================================外中斷0,調(diào)時(shí)開關(guān)(P3.3)
- void int1 (void) interrupt 2 {//中斷入口2(INT1)
- uchar a;//定義延時(shí)長度
- for(a=100;a>0;a--){//延時(shí)處理,防止誤按(長按2秒后有效)
- display_s ();//反色顯示表示按鍵有效
- }
- if(int_Key == 0){//進(jìn)入鬧鐘設(shè)置界面
- Beep_set();//調(diào)時(shí)提示音
- if(settime == 0x77){//如果調(diào)時(shí)標(biāo)志為0說明當(dāng)正為正常顯示狀態(tài)
- ET0 = 0;//關(guān)定時(shí)器中斷(停止顯示切換)
- TR0 = 0;
- settime = 0;//變?yōu)檎{(diào)時(shí)的反色顯示
- setput(0);//顯示清0后的內(nèi)容
- }
- else{//如果調(diào)時(shí)標(biāo)志為1說明當(dāng)正為調(diào)時(shí)顯示狀態(tài)
- ET0 = 1;//開定時(shí)器中斷(開啟顯示切換)
- TR0 = 1;
- settime = 0x77;//變?yōu)檎o@示
- }
- while(int_Key == 0){//等待調(diào)時(shí)鍵釋放
- display ();//不釋放時(shí)調(diào)用屏幕顯示
- }
- }
- }
- //===============================================主函數(shù),產(chǎn)生點(diǎn)陣顯示
- void main(void){ //主函數(shù)
- uchar a = 0;//定義變量用于數(shù)據(jù)提取指針
- Beep();//啟動(dòng)發(fā)出報(bào)時(shí)音(測(cè)試揚(yáng)聲器)
- do{//顯示開機(jī)畫面“DYDIY”
- Ledplay[bn] = dydiy[a];//將二維數(shù)組中的一組數(shù)據(jù)放入顯示緩沖區(qū)
- a++;//換下一個(gè)提取字節(jié)
- bn++;//換下一個(gè)顯示緩沖字節(jié)
- }
- while(dydiy[a] != 0x99);//當(dāng)顯示數(shù)據(jù)為0時(shí)結(jié)束循環(huán)
- timecount = 41;//將顯示切換值調(diào)到41,使開機(jī)畫面停留2秒
- Timer0_Init();//定時(shí)器初始化
- IT1 = 0;//外中斷1下沉觸發(fā)
- EX1 = 1;//開外中斷1(調(diào)時(shí)鍵)
- settime = 0x77;//顯示標(biāo)志為0表示正常顯示
- //-------------------------------------主循環(huán)體
- while(1){//
- static uchar k = 0;
- if(settime == 0x77) {//顯示標(biāo)志為0表示正常顯示
- display ();//正常顯示驅(qū)動(dòng)
- //正常顯示時(shí)同時(shí)按下Add、Add2、OK三個(gè)鍵則初始化時(shí)間
- if(Add_Key == 0 && Add2_Key ==0 && OK_Key == 0 ){
- DelayM(100);//延時(shí)去抖動(dòng)
- if(Add_Key == 0 && Add2_Key ==0 && OK_Key == 0 ){
- Beep_set();//提示音
- Init_1302();//調(diào)用時(shí)間初始化函數(shù)
- }
- }
- }
- else{//顯示標(biāo)志為1表示調(diào)時(shí)狀態(tài)
- display_s();//調(diào)時(shí)顯示驅(qū)動(dòng)
- if(OK_Key == 0) {//調(diào)時(shí)切換鍵按下切換調(diào)時(shí)的內(nèi)容
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
匯編語言代碼:
- MAINP SEGMENT CODE ;程序段
- PUBLIC MAIN ;入口地址,跳轉(zhuǎn)到DL標(biāo)號(hào)處執(zhí)行匯編程序
- RSEG MAINP ;程序段
- ;這是關(guān)于DS18B20的讀寫程序,數(shù)據(jù)腳IN,晶振12MHZ
- ;溫度傳感器18B20匯編程序,采用器件默認(rèn)的12位轉(zhuǎn)化,最大轉(zhuǎn)化時(shí)間750微秒
- ;可以將檢測(cè)到的溫度直接顯示到AT89C51開發(fā)實(shí)驗(yàn)板的兩個(gè)數(shù)碼管上
- ;顯示溫度00到99度,很準(zhǔn)確哦~~無需校正!
- ;單片機(jī)內(nèi)存分配申明!
- TEMPER_L EQU 29H;用于保存讀出溫度的低8位
- TEMPER_H EQU 28H;用于保存讀出溫度的高8位
- in equ P3.3
- MAIN:
- LCALL GET_TEMPER;調(diào)用讀溫度子程序
- ;進(jìn)行溫度顯示,這里我們考慮用網(wǎng)站提供的兩位數(shù)碼管來顯示溫度
- ;顯示范圍00到99度,顯示精度為1度
- ;因?yàn)?2位轉(zhuǎn)化時(shí)每一位的精度為0.0625度,我們不要求顯示小數(shù)所以可以拋棄29H的低4位
- ;將28H中的低4位移入29H中的高4位,這樣獲得一個(gè)新字節(jié),這個(gè)字節(jié)就是實(shí)際測(cè)量獲得的溫度
- ;這個(gè)轉(zhuǎn)化溫度的方法可是我想出來的哦~~非常簡潔無需乘于0.0625系數(shù)
- MOV A,29H
- MOV B,28H
- MOV C,B.0;將28H中的最低位移入C
- RRC A
- MOV C,B.1
- RRC A
- MOV C,B.2
- RRC A
- MOV C,B.3
- RRC A
- MOV 29H,A
- RET
- ; 這是DS18B20復(fù)位初始化子程序
- INIT_1820:
- SETB IN
- NOP
- CLR IN
- ;主機(jī)發(fā)出延時(shí)537微秒的復(fù)位低脈沖
- MOV R1,#3
- TSR1:MOV R0,#107
- DJNZ R0,$
- DJNZ R1,TSR1
- SETB IN;然后拉高數(shù)據(jù)線
- NOP
- NOP
- NOP
- MOV R0,#25H
- TSR2:
- JNB IN,TSR3;等待DS18B20回應(yīng)
- DJNZ R0,TSR2
- LJMP TSR4 ; 延時(shí)
- TSR3:
- ;SETB FLAG1 ; 置標(biāo)志位,表示DS1820存在
- LJMP TSR5
- TSR4:
- ;CLR FLAG1 ; 清標(biāo)志位,表示DS1820不存在
- LJMP TSR7
- TSR5:
- MOV R0,#117
- TSR6:
- DJNZ R0,TSR6 ; 時(shí)序要求延時(shí)一段時(shí)間
- TSR7:
- SETB IN
- RET
- ; 讀出轉(zhuǎn)換后的溫度值
- GET_TEMPER:
- SETB IN
- LCALL INIT_1820;先復(fù)位DS18B20
- ;JB FLAG1,TSS2
- ;CLR P1.2
- ;RET ; 判斷DS1820是否存在?若DS18B20不存在則返回
- TSS2:
- ;CLR P1.3;DS18B20已經(jīng)被檢測(cè)到!!!!!!!!!!!!!!!!!!
- MOV A,#0CCH ; 跳過ROM匹配
- LCALL WRITE_1820
- MOV A,#44H ; 發(fā)出溫度轉(zhuǎn)換命令
- LCALL WRITE_1820
- ;這里通過調(diào)用顯示子程序?qū)崿F(xiàn)延時(shí)一段時(shí)間,等待AD轉(zhuǎn)換結(jié)束,12位的話750微秒
- ;LCALL D1MS;DISPLAY
- LCALL INIT_1820;準(zhǔn)備讀溫度前先復(fù)位
- MOV A,#0CCH ; 跳過ROM匹配
- LCALL WRITE_1820
- MOV A,#0BEH ; 發(fā)出讀溫度命令
- LCALL WRITE_1820
- LCALL READ_18200; 將讀出的溫度數(shù)據(jù)保存到35H/36H
- RET
- ;寫DS18B20的子程序(有具體的時(shí)序要求)
- WRITE_1820:
- MOV R2,#8;一共8位數(shù)據(jù)
- CLR C
- WR1:
- CLR IN
- MOV R3,#6
- DJNZ R3,$
- RRC A
- MOV IN,C
- MOV R3,#23
- DJNZ R3,$
- SETB IN
- NOP
- DJNZ R2,WR1
- SETB IN
- RET
- ; 讀DS18B20的程序,從DS18B20中讀出兩個(gè)字節(jié)的溫度數(shù)據(jù)
- READ_18200:
- MOV R4,#2 ; 將溫度高位和低位從DS18B20中讀出
- MOV R1,#29H ; 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)
- RE00:
- MOV R2,#8;數(shù)據(jù)一共有8位
- RE01:
- CLR C
- SETB IN
- NOP
- NOP
- CLR IN
- NOP
- NOP
- NOP
- SETB IN
- MOV R3,#9
- RE10:
- DJNZ R3,RE10
- MOV C,IN
- MOV R3,#23
- RE20:
- DJNZ R3,RE20
- RRC A
- DJNZ R2,RE01
- MOV @R1,A
- DEC R1
- DJNZ R4,RE00
- RET
- end
復(fù)制代碼
所有資料51hei提供下載:
3208LED點(diǎn)陣屏電子鐘制作全資料.rar
(2.19 MB, 下載次數(shù): 46)
2018-9-17 10:09 上傳
點(diǎn)擊文件名下載附件
|
|