仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (35.46 KB, 下載次數: 139)
下載附件
2021-7-13 19:04 上傳
如圖2-1所示,顯示模塊數據引腳接到P0口,由P0口控制顯示想要的數據;將顯示模塊的控制引腳接P1.5—P1.7,控制顯示的位置,從而達到顯示的效果。
圖2-1
2.1按鍵模塊
(1) K1—設置現在的時間,年閃爍,再按K1鍵月閃爍,依次日,星期,時,分,秒。
(2) K2—正常顯示時間模式下按下K2鍵顯示鬧鐘設置的時間,再按K1鍵依次年,月,日,時,分,秒閃爍。
(3) K3—在設置現在時間或鬧鈴時間模式下,K3負責增加功能,例如日閃爍時,每按一次K3鍵日期加1,加到31再從1開始。
(4) K4—在正常時間顯示模式下,K4為鬧鈴ON/OFF的狀態切換,設置為ON時連續三次發出“嘩”的一聲,設置為OFF發出“嘩”的一聲。
51hei.png (29.79 KB, 下載次數: 121)
下載附件
2021-7-13 19:27 上傳
程序流程圖
51hei.png (13.5 KB, 下載次數: 123)
下載附件
2021-7-13 19:28 上傳
單片機源程序如下:
#include<reg52.H>
#include<INTRINS.H>
#define TIME (0X10000-50000)
#define FLAG 0XEF //鬧鐘標志
//引腳連接圖
sbit rst=P3^5;
sbit clk=P3^4;
sbit dat=P3^3;
sbit rs=P1^5;
sbit rw=P1^6;
sbit e=P1^7;
sbit DQ=P1^4;
sbit P3_2=P3^2;
sbit ACC_7=ACC^7;
//全局變量及常量定義
unsigned char i=20,j,time1[16];
unsigned char alarm[2],time2[15],time[3];
unsigned char code Day[]={31,28,31,30,31,30,31,31,30,31,30,31};//12個月的最大日期(非閏年)
//音律表
unsigned int code table1[]={64260,64400,64524,64580,64684,64777,
64820,64898,64968,65030,65058,65110,65157,65178,65217};
//發聲部分的延時時間
unsigned char code table2[]={0x82,1,0x81,0xf4,0xd4,0xb4,0xa4,
0x94,0xe2,1,0xe1,0xd4,0xb4,0xc4,0xb4,4,0};
//LCD自建字
unsigned char code tab[]={0x10,0x11,0x12,0x1c,0x1c,0x12,0x11,0x11,
0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02,//年
0x0f,0x09,0x0f,0x09,0x0f,0x09,0x11,0x00,//月
0x0f,0x09,0x09,0x0f,0x09,0x09,0x0f,0x00};//日
unsigned char code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
//鬧鐘中用的全局變量
unsigned char th1,tl1;
unsigned char temp_data[2]={0x00,0x00}; // 讀出溫度暫放
bit flag; //18b20存在標志位
/***********11微秒延時函數**********/
void delay(unsigned int t)
{
for(;t>0;t--);
}
/***********18B20復位函數**********/
void RST18B20(void)
{
unsigned char i;
DQ=1;_nop_();_nop_();
DQ=0; //
delay(50); // 550us
DQ=1; //
delay(6); // 66us
for(i=0;i<0x30;i++)
{
if(!DQ)
goto d1;
}
flag=0; //清標志位,表示ds1820不存在
DQ=1;
return;
d1: delay(45); //延時500us
flag=1;
DQ=1; //置標志位,表示ds1820存在
}
/**********18B20寫命令函數*********/
//向 1-WIRE 總線上寫一個字節
void Write1Byte18B20(unsigned char val)
{
unsigned char i;
for (i=8; i>0; i--) //
{
DQ=1;_nop_();_nop_();
DQ=0;_nop_();_nop_();_nop_();_nop_();_nop_();//5us
DQ=val&0x01; //最低位移出
delay(6); //66us
val=val/2; //右移一位
}
DQ=1;
delay(1);
}
/*********18B20讀1個字節函數********/
//從總線上讀取一個字節
unsigned char Read1Byte18B20(void)
{
unsigned char i;
unsigned char value=0;
for (i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();
value>>=1;
DQ=0; //
_nop_();_nop_();_nop_();_nop_(); //4us
DQ=1;_nop_();_nop_();_nop_();_nop_(); //4us
if(DQ)
value|=0x80;
delay(6); //66us
}
DQ=1;
return(value);
}
/***********讀出溫度函數**********/
void Read18B20()
{
RST18B20(); //總線復位
if(!flag) //判斷ds1820是否存在?若ds18b20不存在則返回
return;
//Write1Byte18B20(0xCC); // Skip ROM
//Write1Byte18B20(0x44); // 發轉換命令
//delay(70);
Write1Byte18B20(0xCC); //發Skip ROM命令
Write1Byte18B20(0xBE); //發讀命令
temp_data[0]=Read1Byte18B20(); //溫度低8位
temp_data[1]=Read1Byte18B20(); //溫度高8位
RST18B20();
Write1Byte18B20(0xCC); // Skip ROM
Write1Byte18B20(0x44); // 發轉換命令
}
/***********溫度數據處理函數**********/
void DealTempData()
{
unsigned char n=0,m;
if(temp_data[1]>127)//負溫度求補碼
{
temp_data[1]=(256-temp_data[1]);
temp_data[0]=(256-temp_data[0]);
n=1;
}
time2[13]=ditab[temp_data[0]&0x0f]+'0';
time2[12]='.';
m=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);//
if(n)
{
m-=16;
}
time2[9]=m/100+'0';
time2[11]=m%100;
time2[10]=time2[11]/10+'0';
time2[11]=time2[11]%10+'0';
if(time2[9]=='0')//最高位為0時都不顯示
{
time2[9]=0x20;
if(n)//負溫度時最高位顯示"-"
{
time2[9]='-';
}
if(time2[10]=='0')
{
if(n)
{
time2[10]='-';
time2[9]=0x20;
}
else
time2[10]=0x20;
if(time2[11]=='0'&&time2[13]=='0')
time2[11]=time2[12]=0x20;
}
}
}
void delay1ms(unsigned char time) //延時1ms
{
unsigned char i,j;
for(i=0;i<time;i++)
{
for(j=0;j<110;j++);
}
}
//使能1602
void EnableLCD()
{
rs=0;
rw=0;
e=0;
delay1ms(3);
e=1;
}
//寫LCD函數
void WriteLCD(unsigned char i)
{
P0=i;
rs=1;
rw=0;
e=0;
delay1ms(2);
e=1;
}
//寫LCD內部地址函數
void WriteLCDRAM(unsigned char data *address,m)
{
unsigned char i,j;
for(i=0;i<m;i++,address++)
{
j=*address;
WriteLCD(j);
}
}
//LCD顯示
void LCDSHOW()
{
P0=0XC; //顯示器開、光標關
EnableLCD();
P0=0x80; //寫入顯示起始地址
EnableLCD();
WriteLCDRAM(time1,16);
P0=0xc1; //寫入顯示起始地址
EnableLCD();
WriteLCDRAM(time2,15);
}
//自建字函數庫
void DesignHZ()
{
unsigned char i;
.......余下內容見附件.................
51hei.png (8.69 KB, 下載次數: 129)
下載附件
2021-7-13 19:30 上傳
Proteus仿真程序51hei附件下載:
電子時鐘.zip
(236.75 KB, 下載次數: 291)
2021-7-13 16:12 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|