|
求高手改時(shí)鐘顯示閃爍程序 和DS3231低溫度程序 程序是在論壇里下載的 還想在修改哈 望高手幫幫忙
Altium Designer畫(huà)的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
F4)1PLOAPT)DBM(0YA`TL8Y.png (205.82 KB, 下載次數(shù): 52)
下載附件
2020-5-11 10:17 上傳
%7ZE08@NKIUK]YGKFP_D7.png (128.3 KB, 下載次數(shù): 66)
下載附件
2020-5-11 10:17 上傳
VHIS[RJNZ@D%T6DLPV)VC}N.png (221.56 KB, 下載次數(shù): 48)
下載附件
2020-5-11 10:17 上傳
單片機(jī)源程序如下:
- #include <reg52.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit SDA=P2^7; //數(shù)據(jù)傳送位SDA
- sbit SCL=P2^6; //時(shí)鐘控制位SCL
- sbit INT=P3^3; //中斷位
- sbit RESET=P3^2; //復(fù)位
- sbit smg4=P1^1; //位碼1聲明 分個(gè)位
- sbit smg3=P1^3; //位碼2聲明 分十位
- sbit smg2=P1^5; //位碼3聲明 時(shí)個(gè)位
- sbit smg1=P1^7; //位碼4聲明 時(shí)十位
- sbit k1=P1^4; //按鍵k1的聲明
- sbit k2=P1^6; //按鍵k2的聲明
- sbit k3=P3^7; //按鍵k3的聲明
- sbit bell=P3^5; //蜂鳴器聲明
- sbit gm=P2^1; //測(cè)光聲明,黑暗時(shí)等于1
- bit gm_en=0; //光敏使能信號(hào);
- bit ack; //應(yīng)答標(biāo)志位
- char code dis_code[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0X88,0X83,0XC6,0XA1,0X86,0X8E};//數(shù)碼管沒(méi)有按a-h的順序連接,自定義的顯示字庫(kù),0-9,A-F
- //0X28,0XEE,0X32,0XA2,0XE4,0XA1,0X21,0XEA,0X20,0XA0,0X60,0X25,0X37,0X26,0X31,0X71
- uchar bell_en=0,x=1;//鬧鐘使能信號(hào),任意鍵關(guān)閉鈴聲標(biāo)志位
- uchar tabtime[]={0x00,0x00,0x07,0x02,0x23,0x10,0x18}; //首次上電時(shí)默認(rèn)的時(shí)間2018年 星期二 10月23日 07:00:00
- uchar year,month,day,week,hour,minute,second,temperature; //從1302讀出的實(shí)時(shí)時(shí)間數(shù)據(jù)
- uchar gm_time=60,temp_en=0,n=0,a=0,b=0; //gm_time光敏控制亮度值,n是按鍵標(biāo)志位,a產(chǎn)生一個(gè)1秒的計(jì)時(shí),b控制字符閃爍,temp_en溫度顯示標(biāo)志
- uint t=0; //用來(lái)產(chǎn)生30秒的計(jì)時(shí)
- uint TtempH,TtempL; //定義溫度高位,低位
- char shi,fen,miao,b_shi=7,b_fen=0; //必須使用符號(hào)型:數(shù)據(jù)暫存單元shi/fen/miao,鬧鈴時(shí)間b_shi,b_fen,
- void baojing(); //報(bào)警函數(shù)
- void delay_50us(uint t); //延時(shí)50*T微妙函數(shù)的聲明
- void Start_I2C(); //I2C總線產(chǎn)生起始信號(hào)函數(shù)
- void Stop_I2C(); //I2C總線產(chǎn)生停止信號(hào)函數(shù)
- void Ack_I2C(bit a); //接收應(yīng)答信號(hào)函數(shù);
- void SendByte(uchar c); //向I2C總線寫(xiě)入一個(gè)字節(jié)的數(shù)據(jù)函數(shù)
- uchar RcvByte(); //字節(jié)數(shù)據(jù)接收函數(shù)
- uchar write_byte(uchar addr, uchar write_data);//將一個(gè)字節(jié)寫(xiě)入DS3231指定地址
- uchar read_byte(uchar addr); //從DS3231指定地址讀一個(gè)字節(jié)
- void Set_Time(); //設(shè)置時(shí)間
- void get_time(void); //讀取時(shí)間
- void get_Temperature(); //讀取溫度
- void show_Temperature(); //顯示溫度
- void init(); //初始化函數(shù)
- void timer0(); //定時(shí)器0中斷服務(wù)程序
- void display(uchar s,f); //顯示子程序
- void key(); //按鍵控制函數(shù)
- void baojing()//報(bào)警函數(shù)
- {
- uint j=10,i=10;
- bell=0;
- while(i--)display(shi,fen);
- bell=1;
- while(j--)display(shi,fen);
- }
- //函數(shù)名稱:void delay_50US(unsigned int t)
- //功能: 延時(shí)50*t(us)
- void delay_50us(uint t)
- {
- unsigned char j;
- for(;t>0;t--)
- {
- for(j=19;j>0;j--);
- }
- }
- void Start_I2C() //I2C總線產(chǎn)生起始信號(hào)函數(shù)
- {
- SDA=1; //拉高數(shù)據(jù)線,發(fā)送起始條件的數(shù)據(jù)信號(hào)
- SCL=1; //拉高時(shí)鐘線
- SDA=0; //在時(shí)鐘線為高電平時(shí),拉低數(shù)據(jù)線,產(chǎn)生起始信號(hào)
- SCL=0; //鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù)
- }
- void Stop_I2C() //I2C總線產(chǎn)生停止信號(hào)函數(shù)
- {
- SDA=0; //拉低數(shù)據(jù)線,發(fā)送結(jié)束條件的數(shù)據(jù)信號(hào)
- SCL=1; //拉高時(shí)鐘線,發(fā)送結(jié)束條件的時(shí)鐘信號(hào)
- SDA=1; //時(shí)鐘時(shí)線為高電平時(shí),拉高數(shù)據(jù)線,發(fā)送I2C總線結(jié)束信號(hào)
- }
- /********************************************************************
- 應(yīng)答子函數(shù)
- 函數(shù)原型: void I2CACK(bit a);
- 功能: 主控器進(jìn)行應(yīng)答信號(hào)(可以是應(yīng)答或非應(yīng)答信號(hào),由位參數(shù)a決定)
- ********************************************************************/
- void Ack_I2C(bit a) //接收應(yīng)答信號(hào)函數(shù);a是定義的一個(gè)位變量,來(lái)暫存應(yīng)答狀態(tài)。
- {
-
- if(a==0)
- SDA=0; //在此發(fā)出應(yīng)答或非應(yīng)答信號(hào)
- else
- SDA=1;
- SCL=1;
- SCL=0; //清時(shí)鐘線,鉗住I2C總線以便繼續(xù)接收
- }
- /*******************************************************************
- 字節(jié)數(shù)據(jù)發(fā)送函數(shù)
- 函數(shù)原型: void SendByte(uchar c);
- 功能: 將數(shù)據(jù)c發(fā)送出去,可以是地址,也可以是數(shù)據(jù),發(fā)完后等待應(yīng)答,并對(duì)
- 此狀態(tài)位進(jìn)行操作.(不應(yīng)答或非應(yīng)答都使ack=0)
- ack=1 發(fā)送數(shù)據(jù)正常,
- ack=0 被控器無(wú)應(yīng)答或損壞。
- ********************************************************************/
- void SendByte(uchar c) //向I2C總線寫(xiě)入一個(gè)字節(jié)的數(shù)據(jù)函數(shù)
- {
- uchar BitCnt;
-
- for(BitCnt=0;BitCnt<8;BitCnt++) //要傳送的數(shù)據(jù)長(zhǎng)度為8位
- {
- if((c<<BitCnt)&0x80)
- SDA=1; //判斷發(fā)送位
- else
- SDA=0;
- SCL=1; //置時(shí)鐘線為高,通知被控器開(kāi)始接收數(shù)據(jù)位
- SCL=0;
- }
-
- SDA=1; //8位發(fā)送完后釋放數(shù)據(jù)線,準(zhǔn)備接收應(yīng)答位
- SCL=1;
- if(SDA==1)
- ack=0;
- else
- ack=1; //判斷是否接收到應(yīng)答信號(hào)
- SCL=0;
- }
- /*******************************************************************
- 字節(jié)數(shù)據(jù)接收函數(shù)
- 函數(shù)原型: uchar RcvByte();
- 功能: 用來(lái)接收從器件傳來(lái)的數(shù)據(jù),并判斷總線錯(cuò)誤(不發(fā)應(yīng)答信號(hào)),
- 發(fā)完后請(qǐng)用應(yīng)答函數(shù)應(yīng)答從機(jī)。
- ********************************************************************/
- uchar RcvByte() //字節(jié)數(shù)據(jù)接收函數(shù)
- {
- uchar retc;
- uchar BitCnt;
-
- retc=0;
- SDA=1; //置數(shù)據(jù)線為輸入方式
- for(BitCnt=0;BitCnt<8;BitCnt++)
- {
- SCL=0; //置時(shí)鐘線為低,準(zhǔn)備接收數(shù)據(jù)位
- SCL=1; //置時(shí)鐘線為高使數(shù)據(jù)線上數(shù)據(jù)有效
- retc=retc<<1;
- if(SDA==1)
- retc=retc+1; //讀數(shù)據(jù)位,接收的數(shù)據(jù)位放入retc中
- }
- SCL=0;
- return(retc);
- }
-
-
- /***********將一個(gè)字節(jié)寫(xiě)入DS3231指定地址***********/
- uchar write_byte(uchar addr, uchar write_data)
- {
- Start_I2C();
- SendByte(0xD0);
- if (ack == 0)
- return 0;
-
- SendByte(addr);
- if (ack == 0)
- return 0;
-
- SendByte(write_data);
- if (ack == 0)
- return 0;
-
- Stop_I2C();
- return 1;
- }
- /************從DS3231指定地址讀一個(gè)字節(jié)************/
- uchar read_byte(uchar addr)
- {
- uchar read_data;
- Start_I2C();
- SendByte(0xD0);
- if(ack==0)
- return(0);
-
- SendByte(addr);
- if(ack==0)
- return(0);
-
- Start_I2C();
- SendByte(0xD1);
- if(ack==0)
- return(0);
- read_data = RcvByte();
- Ack_I2C(1);
- Stop_I2C();
- return read_data;
- }
-
- /**************************設(shè)置時(shí)間******************************************/
- void Set_Time()
- {
- uchar i;
- uchar ucAddr=0x00; //秒的地址
- for(i=0;i<7;i++)
- {
- write_byte(ucAddr,tabtime[i]);//從秒開(kāi)始連續(xù)寫(xiě)入秒分時(shí)星期日月年
- ucAddr+=1;
- }
- }
-
-
- /*********************讀取時(shí)間**********************/
- void get_time(void)
- {
- hour=read_byte(0x02)/16*10+read_byte(0x02)%16;
- minute=read_byte(0x01)/16*10+read_byte(0x01)%16; //因只顯示時(shí)、分,故可只讀取時(shí)、分
- year=read_byte(0x06)/16*10+read_byte(0x06)%16;
-
- /*
- uchar i;
- uchar ucCurtime[7];
- uchar ucAddr = 0x00; //秒地址
- for(i=0;i<7;i++)
- {ucCurtime[i]=0;}
-
- for(i=0; i<7; i++)
- {
- ucCurtime[i] = read_byte(ucAddr); //格式為: 從秒地址開(kāi)始連續(xù)讀取,秒分時(shí)星期日月年。
- ucAddr += 1;
- }
- year=ucCurtime[6]/16*10+ucCurtime[6]%16;
- month=ucCurtime[5]/16*10+ucCurtime[5]%16;
- day=ucCurtime[4]/16*10+ucCurtime[4]%16;
- week=ucCurtime[3]/16*10+ucCurtime[3]%16;
- hour=ucCurtime[2]/16*10+ucCurtime[2]%16;
- minute=ucCurtime[1]/16*10+ucCurtime[1]%16;
- second=ucCurtime[0]/16*10+ucCurtime[0]%16;
- */
- }
-
- /*********************讀取溫度**********************/
- void get_Temperature()
- {
- TtempH=read_byte(0X11); //讀溫度高字節(jié)
- //因數(shù)碼管位數(shù)只有四位,故溫度的小數(shù)部分不顯示,可以不用讀溫度低字節(jié)
- TtempL=read_byte(0x12); //原為注釋不用ox12 //讀溫度低字節(jié)
- TtempL=(TtempL>>6)*25; //原為注釋不用 //將BIT7,BIT6的數(shù)據(jù)移入BIT1,BIT0位;分辨率數(shù)值擴(kuò)大100倍便于整數(shù)運(yùn)算
-
- }
- void show_Temperature() //顯示溫度
- {
- if((TtempH&0X80)==0x80) //判斷首字節(jié)為1即為零下溫度
- {
- P0=0xBF; //0xbf第一位數(shù)碼管顯示“-”
- smg1=0;
- delay_50us(gm_time);
- smg1=1;
- //////
- P0=dis_code[TtempL/10];//送顯示斷碼 十位
- smg2=0;
- delay_50us(gm_time);
- smg2=1;
- P0=dis_code[TtempL%10];//送顯示斷碼 個(gè)位
- smg3=0;
- delay_50us(gm_time);
- smg3=1;
- P0=0xC6; //送顯示斷碼 ℃
- smg4=0;
- delay_50us(gm_time);
- smg4=1;
-
- }
- else
- smg1=1; //第一位數(shù)碼管不顯示
- if((TtempH/10)==0) //原為0 溫度低于10度時(shí),即為個(gè)位時(shí),第二位數(shù)碼管位不顯示
- smg2=1; //原為=1
- else
- {
- P0=dis_code[TtempH/10];//送顯示斷碼 十位
- smg2=0;
- delay_50us(gm_time);
- smg2=1;
- }
-
- P0=dis_code[TtempH%10];//送顯示斷碼 個(gè)位
- smg3=0;
- delay_50us(gm_time);
- smg3=1;
- P0=0xC6; //送顯示斷碼 ℃
- smg4=0;
- delay_50us(gm_time);
- smg4=1;
-
-
- }
- void init() //初始化函數(shù)
- {
- write_byte(0x0e,0x00); //設(shè)定DS3231的控制寄存器
- IE=0X82; //設(shè)定單片機(jī)的中斷允許控制寄存器,(1000 0010)
- TMOD=0X01; //0000 0001選擇定時(shí)器0的工作方式1 選擇定時(shí)器1的工作方式0
- TH0=(65536-50000)/256;//初值15536定時(shí)50mS
- TL0=(65536-50000)%256;
- TR0=1; //設(shè)定TCON的TR0位,開(kāi)啟定時(shí)器0
- }
- void timer0() interrupt 1 //定時(shí)器0中斷服務(wù)程序,用來(lái)設(shè)置冒號(hào)閃爍頻率
- {
- TH0=(65536-50000)/256;//進(jìn)入中斷重新賦初值15536
- TL0=(65536-50000)%256;//計(jì)數(shù)5萬(wàn)次(50毫秒)
- a++; //標(biāo)志位b,用來(lái)確定光標(biāo)閃爍頻率
- t++;
- if(t==600)t=0; //50ms*600次=30秒,用于溫度顯示,30秒一次
- if(t>520)temp_en=1; //溫度顯示持續(xù)3秒
- else temp_en=0;
- if(a==20)a=0;//a=20 時(shí)被清零 產(chǎn)生一個(gè)1秒的計(jì)時(shí)。
- }
- //四位數(shù)碼管顯示程序
- void display(uchar s,f)
- {
- if((s/10)<1) //小于10,第一位不顯示
- smg1=1;
- else
- {
- P0=dis_code[s/10];//送顯示斷碼 時(shí)的十位
- if((n==1||n==3)&&a<5)
- smg1=1; //鎖存數(shù)據(jù)
- else
- smg1=0;
- delay_50us(gm_time);
- smg1=1;
- }
- P0=dis_code[s%10]; //送顯示斷碼 時(shí)的個(gè)位
- if((n==1||n==3)&&a<5)
- smg2=1;
- else
- smg2=0; //鎖存數(shù)據(jù)
- delay_50us(gm_time);
- smg2=1;
-
-
-
- if((n==2||n==4)&&a<5)
- P0=0x7F; //字符閃爍,小點(diǎn)不閃
- else if(a>=10)
- P0=dis_code[f/10]-0x80; //小點(diǎn)閃爍,字符不閃
- else
- P0=dis_code[f/10]; //送顯示斷碼 分的十位
- smg3=0;
- delay_50us(gm_time);
- smg3=1;
- if((n==2||n==4)&&a<5)
- P0=0x7F; //字符閃爍,小點(diǎn)不閃
- else if(a>=10)
- P0=dis_code[f%10]-0x80; //小點(diǎn)閃爍,字符不閃
- else
- P0=dis_code[f%10]; //送顯示斷碼 分的個(gè)位
- smg4=0;
- delay_50us(gm_time);
- smg4=1;
- }
- void key() //按鍵控制函數(shù)
- {
-
- if(k1==0&&k2==0) //k1k2同時(shí)按下,切換鬧鈴開(kāi)關(guān) 并且在按下之后查看鬧鐘時(shí)間松手后恢復(fù)時(shí)間顯示
- {
- delay_50us(40);
- if(k1==0&&k2==0)
- {
- if(bell_en==1&&b_shi==hour&&b_fen==minute&&x==1)
- x=0; //如果處于響零狀態(tài),就任意鍵關(guān)閉響鈴
- shi=b_shi;
- fen=b_fen;
- bell_en=!bell_en;
- if(bell_en==1) //使能的話報(bào)警兩聲
- {
-
- baojing();
- baojing();
- }
- else
- {
-
- baojing(); //無(wú)效的話報(bào)警一聲
- }
- while(k1==0&&k2==0)
- display(shi,fen);//等待松手
- shi=hour;
- fen=minute;
- }
- }
- if(k1==0&&k3==0) //k1k3同時(shí)按下,切換光控功能
- {
- delay_50us(40);
- if(k1==0&&k3==0)
- {
- gm_en=!gm_en;
- if(bell_en==1&&b_shi==hour&&b_fen==minute&&x==1)
- x=0; //如果處于響零狀態(tài),就任意鍵關(guān)閉響鈴
- if(gm_en==1) //使能的話報(bào)警兩聲
- {
- baojing();
- baojing();
- }
- else baojing(); //無(wú)效的話報(bào)警一聲
- while(k1==0&&k3==0)
- display(88,88);//等待松手
- }
- }
-
-
- if(k2==0&&k3==0) //K2,K3同時(shí)按下,進(jìn)入 調(diào)時(shí)間 和 鬧鈴狀態(tài)
- { //功能鍵k1被按下
- delay_50us(40); //消抖延時(shí)
- if(k2==0&&k3==0)
- {
- if(bell_en==1&&b_shi==hour&&b_fen==minute&&x==1)
- x=0; //如果處于響零狀態(tài),就任意鍵關(guān)閉響鈴
- while(k2==0&&k3==0)
- n=1;
-
- }
- //要加入數(shù)字閃爍代碼
- }
-
-
-
-
- if(n==0)//狀態(tài)0,正常顯示時(shí)間
- {
- b=a; //b是控制小數(shù)點(diǎn)閃爍的
- shi=hour;
- fen=minute;
- }
-
- if(n==1) //狀態(tài)1:調(diào)節(jié)時(shí)間的"時(shí)"
- {
- b=10;
-
- if(k1==0)
- {
- delay_50us(40); //消抖延時(shí)
- if(k1==0)
- {
- while(k1==0)
- n=2;
- }
- }
-
- if(k2==0)
- {
- delay_50us(40); //消抖延時(shí)
- if(k2==0)//k2被按下
- shi=shi+1; //小時(shí)加一
- if(shi>=24)
- shi=0; //達(dá)到24清零
- while(k2==0)
- display(shi,fen);
- }
-
- if(k3==0)
- {
- delay_50us(40); //消抖延時(shí)
- if(k3==0) //k3被按下
- shi--; //小時(shí)減一
- if(shi<0)
- shi=23;//小于0,重新賦值
- while(k3==0)
- display(shi,fen);
- }
- }
-
- if(n==2)//狀態(tài)2:調(diào)節(jié)時(shí)間的"分"
- {
- b=10;
-
- if(k1==0)
- {
- delay_50us(40); //消抖延時(shí)
- if(k1==0)
- {
- while(k1==0)
- n=3;
- }
- tabtime[2]=shi/10*16+shi%10;
- tabtime[1]=fen/10*16+fen%10;
-
- hour=shi;
- minute=fen;
- Set_Time();//設(shè)置DS1302的初始時(shí)間
-
- }
-
-
- if(k2==0)//k2被按下
- {
- delay_50us(40); //消抖延時(shí)
- if(k2==0)
- fen++;//分加一
- if(fen>=60)
- fen=0;//分到達(dá)60 分清零
- while(k2==0)
- display(shi,fen);
- }
-
- if(k3==0)//k3被按下
- {
- delay_50us(40); //消抖延時(shí)
- if(k3==0)
- fen--;//分減一
- if(fen<0)
- fen=59;//分小于0,分重新賦值59
- while(k3==0)
- display(shi,fen);
- }
-
- }
-
-
- if(n==3)//狀態(tài)三:調(diào)節(jié)鬧鈴"時(shí)"
- {
- b=10;
- shi=b_shi;
- fen=b_fen;
-
- if(k1==0)
- {
- delay_50us(40); //消抖延時(shí)
- if(k1==0)
- {
- while(k1==0)
- n=4;
- }
- }
-
- if(k2==0)//k2被按下
- {
- delay_50us(40); //消抖延時(shí)
- if(k2==0)
- b_shi++;//鬧鈴時(shí)間加一
- if(b_shi>=24)
- b_shi=0;//鬧鈴時(shí)間清零
- while(k2==0)
- display(shi,fen);
- }
-
- if(k3==0)//k3被按下
- {
- delay_50us(40); //消抖延時(shí)
- if(k3==0)
- b_shi--;//鬧鈴時(shí)間減一
- if(b_shi<0)
- b_shi=23;//鬧鈴時(shí)間
- while(k3==0)
- display(shi,fen);
- }
- }
-
-
- if(n==4)//狀態(tài)四 :調(diào)節(jié)鬧鈴的"分"
- {
- b=10;
- shi=b_shi;
- fen=b_fen;
-
- if(k1==0)
- {
- delay_50us(40); //消抖延時(shí)
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
51hei.png (8.18 KB, 下載次數(shù): 42)
下載附件
2020-5-11 14:40 上傳
所有資料51hei提供下載:
0.8寸數(shù)碼管 PCB 電路圖 程序.rar
(3.56 MB, 下載次數(shù): 82)
2020-5-11 10:18 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|