❶ 利用單片機(STC89C52)設計倒計時數字鍾
#include<reg51.h>
#define uchar unsigned char
uchar code ledtab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//0-9
unsigned char sec=0,min=0,hour=24,scanled;
unsigned char key,mode,time;
unsigned char disdat[8];
unsigned char alarm[3]={23,59,0},dly;
sbit keyhu=P1^0;
sbit keyhd=P1^1;
sbit keymu=P1^2;
sbit keymd=P1^3;
sbit keysu=P1^4;
sbit keysd=P1^5;
sbit keyst=P1^6;
sbit fmq=P3^0;
bit flag=0;
void delay(unsigned int x)
{
unsigned int i,j;
for(i=0;i<x;i++)
for(j=0;j<120;j++);
}
void dischg()
{
disdat[0]=sec%10;
disdat[1]=sec/10;
disdat[2]=min%10;
disdat[3]=min/10;
disdat[4]=hour%10;
disdat[5]=hour/10;
}
void t0isr() interrupt 1//秒計時
{
TH0=0x3c;
TL0=0xb0;
time++;
switch(mode)
{
case 0:
if(time==20)
{
time=0;
sec++;
if(sec>59)
{
sec=0;
min++;
if(min>59)
{
min=0;
hour++;
if(hour>23)hour=0;
}
}
}
break;
case 1:
if(time==20)
{
time=0;
if(sec>0 && flag==0)sec--;
else if(min>0 && flag==0){sec=59;min--;}
else if(hour>0 && flag==0){sec=59;min=59;hour--;}
if((hour == alarm[0]) && (min == alarm[1]) && (sec == alarm[2])){fmq=1;flag=1;dly++;}
}
break;
}
if(dly>=2){fmq=0;flag=0;TR0=0;dly=0;}
dischg();
}
void t1isr() interrupt 3//顯示
{
TH1=0xec;
TL1=0x78;
switch(scanled)
{
case 0:
P2=0x20;
P0=~ledtab[disdat[5]];
break;
case 1:
P2=0x10;
P0=~ledtab[disdat[4]]&0x7f;
break;
case 2:
P2=0x08;
P0=~ledtab[disdat[3]];
break;
case 3:
P2=0x04;
P0=~ledtab[disdat[2]]&0x7f;
break;
case 4:
P2=0x02;
P0=~ledtab[disdat[1]];
break;
case 5:
P2=0x01;
P0=~ledtab[disdat[0]];
break;
default:break;
}
scanled++;
scanled%=6;
}
main()
{
TMOD=0x11;
TH0=0x3c;
TL0=0xb0;
TH1=0xec;
TL1=0x78;
TR1=1;
TR0=0;
ET0=1;
ET1=1;
EA=1;
fmq=0;
scanled=0;
time=0;
mode=1;
dischg();
while(1)
{
if(keyhu==0)
{
while(keyhu==0);
TR0=0;
hour++;
hour%=24;
}
if(keyhd==0)
{
while(keyhd==0);
TR0=0;
if(hour>0)hour--;
if(hour==0)hour=23;
}
if(keymu==0)
{
while(keymu==0);
TR0=0;
min++;
min%=60;
}
if(keymd==0)
{
while(keymd==0);
TR0=0;
if(min>0)min--;
if(min==0)min=59;
}
if(keysu==0)
{
while(keysu==0);
TR0=0;
sec++;
sec%=60;
}
if(keysd==0)
{
while(keysd==0);
TR0=0;
if(sec>0)sec--;
if(sec==0)sec=59;
}
if(keyst==0)
{
while(keyst==0);
TR0=~TR0;
}
dischg();
}
}
❷ 一、基於單片機的電子時鍾設計 設計內容:1、用LCD液晶作為顯示設備(30分)
http://blog.163.com/asm_c/blog/static/2482031132012330340436/
參考。
❸ 用單片機設計一個時鍾,可顯示時和分,可以調時間,也要有鬧鍾功能,要有設計的電路圖
其實不用定時中斷也能實現功能:
#include<reg51.h> 主函數
unsigned char tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};定義0-9數組
unsigned int tmp;定義變數
void delay(unsigned int xms)定義延時函數
{unsigned int j,i;
for(i=0;i<xms;i++)
for(j=0;j<100;j++);
}
void disp()定義子函數
{
P1=tmp;
delay(1);
P2=0xff;
tmp=tmp<<1;
}
void main( )
{
unsigned char z,s=00,m=00,h=00;給時鍾初始值
while(1)
{
for(z=0;z<100;z++)
{
tmp=0x01;
P2=tab[h/10];小時顯示
disp();
P2=tab[h%10];
disp();
P2=tab[m/10];分鍾顯示
disp();
P2=tab[m%10];
disp();
P2=tab[s/10];秒顯示
disp();
P2=tab[s%10];
disp();
}
s++;
while(s==60)秒進一位,到60清0
{
m++;
s=00;
}
while(m==60)分鍾進一位,到60清0
{
h++;
m=00;
}
while(h==24)小時進一位,到24清0
{
h=00;
}
}
}
❹ 用單片機設計一個數字時鍾
#include <REG51.H>#include <intrins.h> #define uint unsigned int#define uchar unsigned charsbit DS1302_CLK = P1^7; //實時時鍾時鍾線引腳 sbit DS1302_IO = P1^6; //實時時鍾數據線引腳 sbit DS1302_RST = P1^5; //實時時鍾復位線引腳sbit wireless_1 = P3^0;sbit wireless_2 = P3^1;sbit wireless_3 = P3^2;sbit wireless_4 = P3^3; //無線控制sbit ACC0 = ACC^0;sbit ACC7 = ACC^7;char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year; //秒,分,時到日,月,年位閃的計數sbit Set = P2^0; //模式切換鍵sbit Up = P2^1; //加法按鈕sbit Down = P2^2; //減法按鈕sbit out = P2^3; //立刻跳出調整模式按鈕sbit DQ = P1^0; //溫度傳送數據IO口char done,count,temp,flag,up_flag,down_flag;uchar temp_value; //溫度值uchar TempBuffer[5],week_value[2]; void show_time(); //液晶顯示程序/***********1602液晶顯示部分子程序****************///Port Definitions**********************************************************sbit LcdRs = P2^5;sbit LcdRw = P2^6;sbit LcdEn = P2^7;sfr DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.數據埠 //內部等待函數**************************************************************************unsigned char LCD_Wait(void){ LcdRs=0; LcdRw=1; _nop_(); LcdEn=1; _nop_(); LcdEn=0; return DBPort; }//向LCD寫入命令或數據************************************************************#define LCD_COMMAND 0 // Command#define LCD_DATA 1 // Data#define LCD_CLEAR_SCREEN 0x01 // 清屏#define LCD_HOMING 0x02 // 游標返回原點void LCD_Write(bit style, unsigned char input){ LcdEn=0; LcdRs=style; LcdRw=0; _nop_(); DBPort=input; _nop_();//注意順序 LcdEn=1; _nop_();//注意順序 LcdEn=0; _nop_(); LCD_Wait(); } //設置顯示模式************************************************************#define LCD_SHOW 0x04 //顯示開#define LCD_HIDE 0x00 //顯示關 #define LCD_CURSOR 0x02 //顯示游標#define LCD_NO_CURSOR 0x00 //無游標 #define LCD_FLASH 0x01 //游標閃動#define LCD_NO_FLASH 0x00 //游標不閃動 void LCD_SetDisplay(unsigned char DisplayMode){ LCD_Write(LCD_COMMAND, 0x08|DisplayMode); } //設置輸入模式************************************************************#define LCD_AC_UP 0x02#define LCD_AC_DOWN 0x00 // default #define LCD_MOVE 0x01 // 畫面可平移#define LCD_NO_MOVE 0x00 //default void LCD_SetInput(unsigned char InputMode){ LCD_Write(LCD_COMMAND, 0x04|InputMode);} //初始化LCD************************************void LCD_Initial(){ LcdEn=0; LCD_Write(LCD_COMMAND,0x38); //8位數據埠,2行顯示,5*7點陣 LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //開啟顯示, 無游標 LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏 LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC遞增, 畫面不動} //液晶字元輸入的位置************************void GotoXY(unsigned char x, unsigned char y){ if(y==0) LCD_Write(LCD_COMMAND,0x80|x); if(y==1) LCD_Write(LCD_COMMAND,0x80|(x-0x40));} //將字元輸出到液晶顯示void Print(unsigned char *str){ while(*str!='\0') { LCD_Write(LCD_DATA,*str); str++; }} /***********DS1302時鍾部分子程序******************/typedef struct __SYSTEMTIME__{ unsigned char Second; unsigned char Minute; unsigned char Hour; unsigned char Week; unsigned char Day; unsigned char Month; unsigned char Year; unsigned char DateString[11]; unsigned char TimeString[9];}SYSTEMTIME; //定義的時間類型SYSTEMTIME CurrentTime; #define AM(X) X#define PM(X) (X+12) // 轉成24小時制#define DS1302_SECOND 0x80 //時鍾晶元的寄存器位置,存放時間#define DS1302_MINUTE 0x82#define DS1302_HOUR 0x84 #define DS1302_WEEK 0x8A#define DS1302_DAY 0x86#define DS1302_MONTH 0x88#define DS1302_YEAR 0x8C void DS1302InputByte(unsigned char d) //實時時鍾寫入一位元組(內部函數){ unsigned char i; ACC = d; for(i=8; i>0; i--) { DS1302_IO = ACC0; //相當於匯編中的 RRC DS1302_CLK = 1; DS1302_CLK = 0; ACC = ACC >> 1; } } unsigned char DS1302OutputByte(void) //實時時鍾讀取一位元組(內部函數){ unsigned char i; for(i=8; i>0; i--) { ACC = ACC >>1; //相當於匯編中的 RRC ACC7 = DS1302_IO; DS1302_CLK = 1; DS1302_CLK = 0; } return(ACC); } void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要寫的數據{ DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1; DS1302InputByte(ucAddr); // 地址,命令 DS1302InputByte(ucDa); // 寫1Byte數據 DS1302_CLK = 1; DS1302_RST = 0;} unsigned char Read1302(unsigned char ucAddr) //讀取DS1302某地址的數據{ unsigned char ucData; DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1; DS1302InputByte(ucAddr|0x01); // 地址,命令 ucData = DS1302OutputByte(); // 讀1Byte數據 DS1302_CLK = 1; DS1302_RST = 0; return(ucData);} void DS1302_GetTime(SYSTEMTIME *Time) //獲取時鍾晶元的時鍾數據到自定義的結構型數組{ unsigned char ReadValue; ReadValue = Read1302(DS1302_SECOND); Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_MINUTE); Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_HOUR); Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_DAY); Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_WEEK); Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_MONTH); Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_YEAR); Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); } void DateToStr(SYSTEMTIME *Time) //將時間年,月,日,星期數據轉換成液晶顯示字元串,放到數組里DateString[]{ if(hide_year<2) //這里的if,else語句都是判斷位閃爍,<2顯示數據,>2就不顯示,輸出字元串為 2007/07/22 { Time->DateString[0] = '2'; Time->DateString[1] = '0'; Time->DateString[2] = Time->Year/10 + '0'; Time->DateString[3] = Time->Year%10 + '0'; } else { Time->DateString[0] = ' '; Time->DateString[1] = ' '; Time->DateString[2] = ' '; Time->DateString[3] = ' '; } Time->DateString[4] = '/'; if(hide_month<2) { Time->DateString[5] = Time->Month/10 + '0'; Time->DateString[6] = Time->Month%10 + '0'; } else { Time->DateString[5] = ' '; Time->DateString[6] = ' '; } Time->DateString[7] = '/'; if(hide_day<2) { Time->DateString[8] = Time->Day/10 + '0'; Time->DateString[9] = Time->Day%10 + '0'; } else { Time->DateString[8] = ' '; Time->DateString[9] = ' '; } if(hide_week<2) { week_value[0] = Time->Week%10 + '0'; //星期的數據另外放到 week_value[]數組里,跟年,月,日的分開存放,因為等一下要在最後顯示 } else { week_value[0] = ' '; } week_value[1] = '\0'; Time->DateString[10] = '\0'; //字元串末尾加 '\0' ,判斷結束字元} void TimeToStr(SYSTEMTIME *Time) //將時,分,秒數據轉換成液晶顯示字元放到數組 TimeString[];{ if(hide_hour<2) { Time->TimeString[0] = Time->Hour/10 + '0'; Time->TimeString[1] = Time->Hour%10 + '0'; } else { Time->TimeString[0] = ' '; Time->TimeString[1] = ' '; } Time->TimeString[2] = ':'; if(hide_min<2) { Time->TimeString[3] = Time->Minute/10 + '0'; Time->TimeString[4] = Time->Minute%10 + '0'; } else { Time->TimeString[3] = ' '; Time->TimeString[4] = ' '; } Time->TimeString[5] = ':'; if(hide_sec<2) { Time->TimeString[6] = Time->Second/10 + '0'; Time->TimeString[7] = Time->Second%10 + '0'; } else { Time->TimeString[6] = ' '; Time->TimeString[7] = ' '; } Time->DateString[8] = '\0';} void Initial_DS1302(void) //時鍾晶元初始化{ unsigned char Second=Read1302(DS1302_SECOND); if(Second&0x80) //判斷時鍾晶元是否關閉 { Write1302(0x8e,0x00); //寫入允許 Write1302(0x8c,0x07); //以下寫入初始化時間 日期:07/07/25.星期: 3. 時間: 23:59:55 Write1302(0x88,0x07); Write1302(0x86,0x25); Write1302(0x8a,0x07); Write1302(0x84,0x23); Write1302(0x82,0x59); Write1302(0x80,0x55); Write1302(0x8e,0x80); //禁止寫入 } } /***********ds18b20子程序*************************/ /***********ds18b20延遲子函數(晶振12MHz )*******/ void delay_18B20(unsigned int i){ while(i--);} /**********ds18b20初始化函數**********************/ void Init_DS18B20(void) { unsigned char x=0; DQ = 1; //DQ復位 delay_18B20(8); //稍做延時 DQ = 0; //單片機將DQ拉低 delay_18B20(80); //精確延時 大於 480us DQ = 1; //拉高匯流排 delay_18B20(14); x=DQ; //稍做延時後 如果x=0則初始化成功 x=1則初始化失敗 delay_18B20(20);} /***********ds18b20讀一個位元組**************/ unsigned char ReadOneChar(void){ uchar i=0; uchar dat = 0; for (i=8;i>0;i--) { DQ = 0; // 給脈沖信號 dat>>=1; DQ = 1; // 給脈沖信號 if(DQ) dat|=0x80; delay_18B20(4); } return(dat);} /*************ds18b20寫一個位元組****************/ void WriteOneChar(uchar dat){ unsigned char i=0; for (i=8; i>0; i--) { DQ = 0; DQ = dat&0x01; delay_18B20(5); DQ = 1; dat>>=1; }} /**************讀取ds18b20當前溫度************/ void ReadTemp(void){ unsigned char a=0; unsigned char b=0; unsigned char t=0; Init_DS18B20(); WriteOneChar(0xCC); // 跳過讀序號列號的操作 WriteOneChar(0x44); // 啟動溫度轉換 delay_18B20(100); // this message is wery important Init_DS18B20(); WriteOneChar(0xCC); //跳過讀序號列號的操作 WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度 delay_18B20(100); a=ReadOneChar(); //讀取溫度值低位 b=ReadOneChar(); //讀取溫度值高位 temp_value=b<<4; temp_value+=(a&0xf0)>>4; }void temp_to_str() //溫度數據轉換成液晶字元顯示{ TempBuffer[0]=temp_value/10+'0'; //十位 TempBuffer[1]=temp_value%10+'0'; //個位 TempBuffer[2]=0xdf; //溫度符號 TempBuffer[3]='C'; TempBuffer[4]='\0';}void Delay1ms(unsigned int count){ unsigned int i,j; for(i=0;i<count;i++) for(j=0;j<120;j++);} /*延時子程序*/void mdelay(uint delay){ uint i; for(;delay>0;delay--) {for(i=0;i<62;i++) //1ms延時. {;} }}
❺ 哪位有基於單片機的數字鍾的設計開題報告
相關資料:
多功能數字鍾設計
一 簡介
時鍾, 自從它發明的那天起,就成為人類的朋友,但隨著時間的推移,人們對它的功能又提出了新的要求,怎樣讓時鍾更好的為人民服務,怎樣讓我們的老朋友煥發青春呢?這就要求人們不斷設計出新型時鍾。本方案設計的多功能電子鍾除了傳統的顯示時間功能之外還可以測試溫度、電網頻率、電壓、並提供了過壓報警、非接觸止鬧等功能。其中溫度採用AD590溫度感測器電路測得,非接觸止鬧則採用紅外控制技術實現。
二 方案論證
時鍾模塊方案
方案一 基本門電路搭建 用基本門電路來實現數字鍾,電路結構復雜,故障系數大,不易調試。
方案二 單片機編程 用單片機設計電路,由於使用軟硬體結合的方式,所以電路結構簡單、調試也相對方便。與第一種方案比較優點是非常明顯的。我們選擇了第二種方案
測溫模塊方案
方案一 熱電阻測溫 熱電阻測量溫度,精度和靈敏度都可以,但是它的電阻值與溫度的線性關系不好.不便用數字的方法處理。
方案二 熱電偶測溫 熱電偶是溫度測量中應用最廣泛的一種感測器 .在一般的測量和控制中,常用於中高溫的溫度檢測.在 測量中需要溫度的冷端補償,在數字電子中實現不方便
方案三 AD590加運算放大器 二端式半導體溫度感測器 AD590的工作電壓要求不高,測溫的范圍比較寬最重要的是它的輸出電流是緊隨溫度變化的電流源,所以它的線性非常好.我們選擇了這種方案。
測電壓模塊方案
方案一 取樣測試。用高速的取樣電壓取樣,可得電壓的峰值與主頻率,並根據其電壓大小進行相應的報警操作。此方案功能實現復雜,造價相對較高,不適合一般的家用。
方案二 測得電壓有效值 測電壓的有效值的方法比較簡單,可以把一段時間內的電壓的整體情況反映出來 ,但不能測出電壓的瞬時變化的情況,對電網的突然沖擊不能測出.
方案三 測得峰值推得有效值。交流電經過整流濾波後得到直流電壓大小就是交流電的峰值,分壓測出此電壓大小,後根據交流電有效值和峰值的關系可推得有效值。這種方案採用的電路簡單,實現方便,易於調試,精度較高, 為我們的設計採用。
非接觸止鬧模塊方案
方案一 聲音止鬧
聲音代替肢體給人帶來了很大便利,但是要採用聲控裝置不得不考慮外界雜訊對正常聲音信號帶來的干擾,而這一點又很難控制,因此雖然聲控方便,但在這里不太適用所以割捨。
方案二 紅外止鬧
紅外控制技術現在已被廣泛地應用到各個領域,此技術有其獨特的特點,首先操作方便抗干擾性好、探測靈敏度高、工作濕度范圍寬設計電路有不太復雜,造價也不高,由於這些特點我們選用了紅外遙控來止鬧。
顯示模塊方案
方案一 段碼顯示。段碼顯示需要專門的驅動,增大了硬體電路,調試不易。而且用段碼表示不夠直觀,因此不採用這種方案
方案二 單片機控制液晶顯示。控制部分集成在單片機內軟體調試,硬體集成度大,為本方案所採用。
綜上所述得到以下方塊圖:
三 各模塊功能
單片機控制顯示部分:液晶顯示片上顯示時間、電壓、溫度,鍵盤控制,鍵盤如下圖所示:
調節 ↑
鬧鈴 ↓
鬧鈴鍵用來設置鬧鈴,鬧鈴響時按下鬧鈴鍵可用來止鬧,平時鬧鈴鍵可用來設置鬧鈴的開關,鬧鈴關時按下此鍵鬧鈴功能將被打開,反之鬧鈴功能將被關閉。需要調節時間時,按動調節按鈕,顯示片上需要設置的時間值以閃爍的方式出現,以示區別,表示當前調節內容,再次按動,跳至下個需要設置的時間值,我們可以通過切換選擇我們需要調整的時間部分,然後按「上」「下」按鈕進行設定。其中時鍾部分以二十四或十二小時(AM/PM)制顯示。
此外單片機還控制溫度和電壓的測量,通過測溫端和測電壓端輸出的電壓,由相應的函數關系求得被測端的被測參數,然後顯示在液晶顯示屏上.
測溫部分
原理方塊圖:
溫度檢測電路的設計,電路圖如下:
測溫元件使用溫度感測器AD590。A/D590在0℃時輸出的電流I=273 uA,溫度T每增加1℃,I增加1u A。輸出的電壓變化為:
Δv=1uA×R2
系統要求電壓變化范圍在0—5伏,可解得R2<62.5K,設計中R2採用了52K的電阻。
當溫度為-10攝氏度時,要求輸出電壓盡量接近於0 V,
U0=(It-Vcc/R1) ×R2=0
由上述公式,得R1約為56k,本設計中取R1=56.3
3.A/D轉換及顯示電路的設計。本設計中所採用的單片機內置十位A/D轉換器,顯示電路也是通過編程單片機控制,控製程序見附錄。
電壓測量及欠壓過壓報警
電壓測試電路如下:
交流電經變壓器後,經半波整流後分壓測得電壓。電路圖如下:
在變壓器的中線上引出15v的交流電壓,經過二極體以後相當濾掉了 負向電壓。當電壓從峰值下降到一定程度時,電容C1開始放電。取R3*C1>60ns,電阻上得到約等於交流電峰值的直流電壓,分壓後測得輸出電壓,有電路連接和交流電峰值、有效值的關系,
把三極體的基極接到單片機的一個控制口上,控制電容放電,保證每次的采樣結果的正確性,也可以防止放電電流對電源的影響。由於我們已經知道現在用的是標準的電源,所以我們可以用電源的有效值計算出電壓的最大值用於電壓的上下限的報警。
我們用計數器接在J2 J3兩端,通過每分鍾計的的高電平或低電平個數就可以得出電網的頻率。
非接觸止鬧:我們用紅外控制技術控制鬧鍾的關閉。發射電路如下圖
其中38khz方波發生電路由555接成,經74ls08後由三極體驅動兩個發光二極體,當按鈕按下時,發出控制光線。
接收電路如下圖所示:
當接收到紅外信號時,OUT端產生低電平信號,傳到控制端,實現止鬧功能。
單片機控制系統原理圖如下:
控制系統主要由單片機應用電路、存儲器介面電路、LCD顯示介面電路、鍵盤電路、模擬量輸入輸出介面電路、供電電路及程序下載和調試介面電路組成。其中單片機應用電路是系統工作的核心,它主要負責控制各個部分協調工作.由於系統構成介面較多,為了更好的組織各個功能部件正常工作,我們選用功能強大的AVR單片機作為主控CPU.它集各種存儲器(FLASH,RAM,EEPROM)、模擬器件(A/D轉換器,模擬比較器)於一體,同時還集成了各種匯流排控制器等數字通信器件,是真正的片上系統(SOC).由於本系統涉及各種數字和模擬電子器件的應用,因此使用此單片機作為本系統的主控CPU,使開發速度大大提高。
四 系統調試過程與測試結果
本實驗需要調試的主要有兩部分:溫度測試部分的調試和電壓測試部分的調試
溫度測試部分
實驗數據如下
溫度T(℃) 理論AD590輸出電流(uA) 理論電壓值Ut (V) 實際電壓值Uo (V)
0 273 0.416 0.640
10 283 0.930 0.790
20 293 1.444 1.568
26.4 299.4 1.795 2.07
27.5 3090.5 1.852 2.10
30 303 1.985 2.35
40 313 2.471 3.130
50 323 2.985 3.312
60 333 3.499 3.845
70 343 4.013 4.378
100 373 5.62 5.98
表中AD590輸出理論電流值由AD590本身的性質決定,理論電壓輸出則由模擬軟體模擬計算得到。可以看出,理論電壓和實際電壓有明顯的差別,實際輸出電壓高於理論算得的電壓值,經不斷分析測試可作如下總結:由於系統本身工作產生熱量,使得AD590所測溫度高於環境溫度,但可以看出,實際電壓值與溫度依然呈線性關系變化,於是對測得數據進行一元線性回歸處理,用最小二乘法求得此線性關系的斜率和初象,得到輸出電壓與溫度變化之間的函數變化關系如下:
T=(100Uo-64)/5.34
在所得式中代入測得數據計算,其誤差都不超過1攝氏度,可驗證所得式的正確性。將此公式寫入單片機控製程序中,就可以根據輸入的電壓變化得到相應的溫度值。
電壓調試部分:
測輸入交流電壓和輸出交流電壓的值,調10K電位器,市的交流輸入為15是電壓在2.5V到3V之間。保持電位器不變化,測得輸入輸出電壓關系,得出相應函數關系。輸入電壓為十五伏時一邊調電位器,一邊觀察輸出電壓。接入輸出電壓的電阻為2.17時輸出電壓在要求范圍。這時測輸入電壓輸出電壓值如下表:
輸入經變壓器後的交流電壓Ui』 (v) 輸出直流電壓Uo (v)
19.7 3.64
16.3 3
15 2.71
11.7 2.12
7.1 1.25
由表中數據可得以下結論:輸入和輸出約成正比變化,而經變壓器後的電流是原電流的3/22,在由上述關系可得
Vi=Vo*80.2
測試過程中,經變壓器後的交流電壓和輸出的直流電壓線性關系符合得很好,上式作為最後的結果被寫在程序中.
五 結束語
這款多功能計數器採用了現在廣泛使用用的單片機技術為核心,軟硬體結合,使硬體部分大為簡化,提高了系統穩定性,並採用大屏幕液晶顯示、紅外遙控裝置和電壓報警裝置使人機交互簡便易行,較為有效地完成了題目的要求。
其他相關:
http://www.bysj120.cn/lunwen/jsj/3151.html
僅供參考,請自借鑒
希望對您有幫助
❻ 單片機電子時鍾設計
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>#define INT8U unsigned char
#define INT16U unsigned int
#define k1() ((PIND & (1<<PD0))==0x00)
#define k2() ((PIND & (1<<PD1))==0x00)
#define k3() ((PIND & (1<<PD2))==0x00)
#define k4() ((PIND & (1<<PD3))==0x00)
#define k5() ((PIND & (1<<PD4))==0x00)
#define k6() ((PIND & (1<<PD5))==0x00)
#define k7() ((PIND & (1<<PD6))==0x00)
#define k8() ((PIND & (1<<PD7))==0x00)const INT8U seg[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};
INT8U seg11[]={0,0,0x40,0,0,0x40,0,0};
INT8U ja;
INT8U key=0xff;
INT8U h,m,s,m1,d;
INT16U y; void hour1()
{
if (++h>23) {h=0;day();}
seg11[0]=seg[h/10];
seg11[1]=seg[h%10];
} void minute1()
{
if (++m>59)
{m=0;<br> hour1();<br> }
seg11[3]=seg[m/10];
seg11[4]=seg[m%10];
} void second1() {
if (++s>59)
{ s=0;
minute1();
}
seg11[6]=seg[s/10];
seg11[7]=seg[s%10];
} const INT8U Days1[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
const INT8U Days2[]={0,31,29,31,30,31,30,31,31,30,31,30,31};
void year()
{if (++y>9999) y=0;<br> <br> seg11[0]=seg[y/1000];<br> seg11[1]=seg[y%1000/100];<br> seg11[2]=seg[y%100/10];<br> seg11[3]=seg[y%10];<br> } void month1()
{
if (++m1>12)
{m1=0;<br> year();<br> }
seg11[4]=seg[m1/10];
seg11[5]=seg[m1%10];
} void day()
{ INT8U DAY;
DAY=(( y%4==0 && y%100!=0 )||( y%400==0 ) ) ? Days1[m1]:Days2[m1];//判斷閏年
if(++d>DAY)
{ d=0;
month1();
}
seg11[6]=seg[d/10];
seg11[7]=seg[d%10];
} //時間函數
void time()
{
seg11[0]=seg[h/10];
seg11[1]=seg[h%10];
seg11[3]=seg[m/10];
seg11[4]=seg[m%10];
seg11[6]=seg[s/10];
seg11[7]=seg[s%10];
PORTA=0x00;
PORTA=seg11[ja]; PORTB=~(1<<ja);
ja=(ja+1)&0x07;
_delay_ms(5); }
//日期
void date()
{ seg11[0]=seg[y/1000];
seg11[1]=seg[y%1000/100];
seg11[2]=seg[y%100/10];
seg11[3]=seg[y%10];
seg11[4]=seg[m1/10];
seg11[5]=seg[m1%10];
seg11[6]=seg[d/10];
seg11[7]=seg[d%10];
//seg11[2]=seg11[5]=0x00;
PORTA=0x00;
PORTA=seg11[ja];
PORTB=~(1<<ja);
ja=(ja+1)&0x07;
_delay_ms(3);
}
int main()
{ INT8U ja=0;
DDRA=0xff; PORTA=0xff;
DDRB=0xff; PORTB=0xff;
DDRD=0x00; PORTD=0xff;PIND=0x00;
MCUCR=0X0A;//MCU 控制寄存器- MCUCR
GICR=0XC0; //通用中斷控制寄存器- GICR ASSR=0x08;
TCCR2=0x04;
TCNT2=0;
TIMSK=_BV(TOIE2)|_BV(TOIE0); d=26;y=2000;m1=2;
h=m=s=12;
sei();
while(1)
{ time();
if(k1())
/{ while(k1()); hour1(); }
if(k8())
{ while(k8());
while(2)//日期循環
{
date();
if(k8())
{while(k8());break;} }
}
}}
ISR(TIMER2_OVF_vect) {
if( seg11[2]==0x40)
{
seg11[2]=seg11[5]=0x00;
}
else
{ seg11[2]=seg11[5]=0x40;
second1();
}
}
❼ 基於單片機的數字鍾 論文設計
ORG 0000H ;程序入口地址
LJMP START
ORG 000BH ;定時器0中斷入口地址
LJMP TIMER_0
ORG 0300H
/*****程序開始,初始化*****/
START:
SETB 48H ;使用一個bit位用於調時閃爍標志
SETB 47H ;使用一個bit位用於產生脈沖用於調時快進時基
MOV R1,#0 ;調整選擇鍵功能標志:0正常走時、1調時、2調分、3調秒
MOV 20H,#00H ;用於控制秒基準時鍾源的產生
MOV 21H,#00H ;清零秒寄存器
MOV 22H,#00H ;清零分寄存器
MOV 23H,#00H ;清零時寄存器
MOV 24H,#00H ;用於控制調時閃爍的基準時鍾的產生
MOV IP,#02H ;IP,IE初始化
MOV IE,#82H
MOV TMOD,#01H ;設定定時器0工作方式1
MOV TH0,#3CH
MOV TL0,#0B0H ;賦定時初值,定時50ms
SETB TR0 ;啟動定時器0
MOV SP,#40H ;重設堆棧指針
/*****主程序*****/
MAIN:
LCALL DISPLAY ;調用顯示子程序
LCALL KEY_SCAN ;調用按鍵檢測子程序
JZ MAIN ;無鍵按下則返回重新循環
LCALL SET_KEY ;調用選擇鍵處理子程序
JB 46H,MAIN ;如果已進行長按調整(調時快進),則不再執行下面的單步調整
LCALL ADD_KEY ;調用增加鍵處理子程序,加一
LCALL DEC_KEY ;調用減少鍵處理子程序,減一
LJMP MAIN ;重新循環
/*****定時器中斷服務程序*****/
TIMER_0:
PUSH ACC
PUSH PSW ;保護現場
MOV TH0,#3CH
MOV TL0,#0B0H ;重新賦定時初值
CPL 47H ;產生脈沖用於調時快進時基
INC 24H
MOV A,24H
CJNE A,#10,ADD_TIME ;產生0.5秒基準時鍾,用於調時閃爍
CPL 48H ;取反調時閃爍標志位
MOV 24H,#00H
ADD_TIME: ;走時
INC 20H
MOV A,20H
CJNE A,#20,RETI1 ;產生1秒基準時鍾
MOV 20H,#00H ;一秒鍾時間到,清零20H
MOV A,21H
ADD A,#01H
DA A ;作十進制調整
MOV 21H,A
CJNE A,#60H,RETI1
MOV 21H,#00H ;一分鍾到
MOV A,22H
ADD A,#01H
DA A
MOV 22H,A
CJNE A,#60H,RETI1
MOV 22H,#00H ;一小時到
MOV A,23H
ADD A,#01H
DA A
MOV 23H,A
CJNE A,#24H,RETI1
MOV 23H,#00H ;到24點,清零小時
RETI1:
POP PSW
POP ACC ;恢復現場
RETI ;中斷返回
/*****顯示處理*****/
DISPLAY:
MOV A,21H ;秒
ANL A,#0FH
MOV 2FH,A ;轉換出秒個位,存入2FH
MOV A,21H
ANL A,#0F0H
SWAP A
MOV 2EH,A ;轉換出秒十位,存入2EH
JB 46H,MIN ;如果長按按鍵(調時快進),則跳過閃爍處理程序
CJNE R1,#3,MIN ;如果R1為3,閃爍秒位待調整
JB 48H,MIN
MOV 2FH,#0AH ;使該位為10,查表得到使該位不顯示的輸出
MOV 2EH,#0AH
MIN:
MOV A,22H ;分
ANL A,#0FH
MOV 2DH,A ;轉換出分個位,存入2DH
MOV A,22H
ANL A,#0F0H
SWAP A
MOV 2CH,A ;轉換出分十位,存入2CH
JB 46H,HOUR ;如果長按按鍵(調時快進),則跳過閃爍處理程序
CJNE R1,#2,HOUR ;如果R1為2,閃爍分位待調整
JB 48H,HOUR
MOV 2DH,#0AH ;使該位為10,查表得到使該位不顯示的輸出
MOV 2CH,#0AH
HOUR:
MOV A,23H ;時
ANL A,#0FH
MOV 2BH,A ;轉換出時個位,存入2BH
MOV A,23H
ANL A,#0F0H
SWAP A
MOV 2AH,A ;轉換出時十位,存入2AH
JB 46H,DISP ;如果長按按鍵(調時快進),則跳過閃爍處理程序
CJNE R1,#1,DISP ;如果R1為1,閃爍時位待調整
JB 48H,DISP
MOV 2BH,#0AH ;使該位為10,查表得到使該位不顯示的輸出
MOV 2AH,#0AH
/*****數碼管動態掃描顯示*****/
DISP:
MOV DPTR,#TABLE
MOV A,2FH
MOVC A,@A+DPTR
MOV P0,A
setb P2.7
LCALL DELAY
clr P2.7 ;顯示秒個位
MOV A,2EH
MOVC A,@A+DPTR
MOV P0,A
setb P2.6
LCALL DELAY
clr P2.6 ;顯示秒十位
MOV A,#0BFH
MOV P0,A
setb P2.5
LCALL DELAY
clr P2.5 ;顯示"-"
MOV A,2DH
MOVC A,@A+DPTR
MOV P0,A
setb P2.4
LCALL DELAY
clr P2.4 ;顯示分個位
MOV A,2CH
MOVC A,@A+DPTR
MOV P0,A
setb P2.3
LCALL DELAY
clr P2.3 ;顯示分十位
MOV A,#0BFH
MOV P0,A
setb P2.2
LCALL DELAY
clr P2.2 ;顯示"-"
MOV A,2BH
MOVC A,@A+DPTR
MOV P0,A
setb P2.1
LCALL DELAY
clr P2.1 ;顯示時個位
MOV DPTR,#TABLE1 ;該位使用TABLE1以消除前置0
MOV A,2AH
MOVC A,@A+DPTR
MOV P0,A
setb P2.0
LCALL DELAY
clr P2.0 ;顯示時十位
RET
/*****按鍵檢測子程序*****/
KEY_SCAN:
CLR 46H ;關閉長按調整(調時快進)標志
MOV P1,#0FFH ;將P1口設置成輸入狀態
MOV A,P1
CPL A
ANL A,#07H ;P1口低3位連接3個按鍵,只判斷該3位
JZ EXIT_KEY ;無鍵按下則返回
LCALL DELAY ;延時去抖動
MOV A,P1 ;重新判斷
CPL A
ANL A,#07H
JZ EXIT_KEY ;鍵盤去抖動
MOV R5,A ;臨時將鍵值存入R5
MOV R4,#00H ;用於控制調時快進速度
;設置為00H是為了在進入長按處理前加長延時區分用戶的長按與短按,防止誤快進
LOOP: ;進入長按處理
LCALL DISPLAY ;使長按時顯示正常
MOV A,P1
CPL A
ANL A,#07H
JB 47H,LOOP1
INC R4 ;調時快進間隔時間基準加1
LOOP1:
CJNE R1,#03H,LOOP2 ;如果調秒時長按,則不處理
LJMP LOOP3
LOOP2:
CJNE R4,#99H,LOOP3
MOV R4,#70H ;確認用戶長按後,重新設定起始值,加快調時快進速度
SETB 46H ;長按調整(調時快進)標志
LCALL ADD_KEY
LCALL DEC_KEY
LOOP3:
JNZ LOOP ;等待鍵釋放
MOV A,R5 ;輸出鍵值
RET
EXIT_KEY:
RET
/*****延時子程序*****/
DELAY:
MOV R7,#150
DJNZ R7,$
RET
/*****選擇鍵處理子程序*****/
SET_KEY:
CJNE R5,#01H,EXIT ;選擇鍵鍵值
INC R1 ;調整選擇功能標志加一
CJNE R1,#4,EXIT
MOV R1,#0
MOV 24H,#00H ;調時閃爍基準清零
RET
/*****增加鍵處理子程序*****/
ADD_KEY:
CJNE R5,#02H,EXIT ;增加鍵鍵值
CJNE R1,#01H,NEXT1 ;選擇鍵功能標志為1,調時,否則跳出
MOV A,23H
ADD A,#01H
DA A
MOV 23H,A
CJNE A,#24H,EXIT
MOV 23H,#00H
NEXT1:
CJNE R1,#02H,NEXT2 ;選擇鍵功能標志為2,調分,否則跳出
MOV A,22H
ADD A,#01H
DA A
MOV 22H,A
CJNE A,#60H,EXIT
MOV 22H,#00H
NEXT2:
CJNE R1,#03H,EXIT ;選擇鍵功能標志為3,調秒,否則跳出
MOV 21H,#00H ;如增加鍵按下直接清零秒
RET
/*****減少鍵處理子程序*****/
DEC_KEY:
CJNE R5,#04H,EXIT ;減少鍵鍵值
CJNE R1,#01H,NEXT3 ;選擇鍵功能標志為1,調時,否則跳出
MOV A,23H
ADD A,#99H
DA A
MOV 23H,A
CJNE A,#99H,EXIT
MOV 23H,#23H
NEXT3:
CJNE R1,#02H,NEXT4 ;選擇鍵功能標志為2,調分,否則跳出
MOV A,22H
ADD A,#99H
DA A
MOV 22H,A
CJNE A,#99H,EXIT
MOV 22H,#59H
NEXT4:
CJNE R1,#03H,EXIT ;選擇鍵功能標志為3,調秒,否則跳出
MOV 21H,#00H ;如較少鍵按下直接清零秒
RET
/*****萬用返回子程序*****/
EXIT:
RET
/*****數碼管字形編碼表*****/
TABLE:
DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH ;字形顯示編碼
TABLE1:
DB 0FFH,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH ;小時位的十位數編碼,該位如果為0則不顯示
END ;程序結束
❽ 基於單片機的數字時鍾設計方案
數字鍾〔★〕這里用了兩種編租肆寫方法(即匯編語言與C語言)
(1. 開機時,顯示12:00:00的時間開始計時;
(2. P0.0/AD0控制「秒」的調整,每按一次加1秒;
(3. P0.1/AD1控制「分」的調整,每按一次加1分;
(4. P0.2/AD2控制「時」的調整,每按一次加1個小時;
2. 電路原理圖
3. 系統板上硬體連線
(1. 把「單片機系統」區域中的P1.0-P1.7埠用8芯排線連接到「動態數碼顯示」區域中的A-H埠上;
(2. 把「單片機系統:區域中的P3.0-P3.7埠用8芯排線連接到「動態數碼顯示」區域中的S1-S8埠上;
(3. 把「單片陵型碧機系統」區域中的P0.0/AD0、P0.1/AD1、P0.2/AD2埠分別用導線連接到「獨立式鍵盤」區域中尺舉的SP3、SP2、SP1埠上;
4. 相關基本知識
(1. 動態數碼顯示的方法
(2. 獨立式按鍵識別過程
(3. 「時」,「分」,「秒」數據送出顯示處理方法
5. 程序框圖
6. 匯編源程序
SECOND EQU 30H
MINITE EQU 31H
HOUR EQU 32H
HOURK BIT P0.0
MINITEK BIT P0.1
SECONDK BIT P0.2
DISPBUF EQU 40H
DISPBIT EQU 48H
T2SCNTA EQU 49H
T2SCNTB EQU 4AH
TEMP EQU 4BH
ORG 00H
LJMP START
ORG 0BH
LJMP INT_T0
START: MOV SECOND,#00H
MOV MINITE,#00H
MOV HOUR,#12
MOV DISPBIT,#00H
MOV T2SCNTA,#00H
MOV T2SCNTB,#00H
MOV TEMP,#0FEH
LCALL DISP
MOV TMOD,#01H
MOV TH0,#(65536-2000) / 256
MOV TL0,#(65536-2000) MOD 256
SETB TR0
SETB ET0
SETB EA
WT: JB SECONDK,NK1
LCALL DELY10MS
JB SECONDK,NK1
INC SECOND
MOV A,SECOND
CJNE A,#60,NS60
MOV SECOND,#00H
NS60: LCALL DISP
JNB SECONDK,$
NK1: JB MINITEK,NK2
LCALL DELY10MS
JB MINITEK,NK2
INC MINITE
MOV A,MINITE
CJNE A,#60,NM60
MOV MINITE,#00H
NM60: LCALL DISP
JNB MINITEK,$
NK2: JB HOURK,NK3
LCALL DELY10MS
JB HOURK,NK3
INC HOUR
MOV A,HOUR
CJNE A,#24,NH24
MOV HOUR,#00H
NH24: LCALL DISP
JNB HOURK,$
NK3: LJMP WT
DELY10MS:
MOV R6,#10
D1: MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
RET
DISP:
MOV A,#DISPBUF
ADD A,#8
DEC A
MOV R1,A
MOV A,HOUR
MOV B,#10
DIV AB
MOV @R1,A
DEC R1
MOV A,B
MOV @R1,A
DEC R1
MOV A,#10
MOV @R1,A
DEC R1
MOV A,MINITE
MOV B,#10
DIV AB
MOV @R1,A
DEC R1
MOV A,B
MOV @R1,A
DEC R1
MOV A,#10
MOV @R1,A
DEC R1
MOV A,SECOND
MOV B,#10
DIV AB
MOV @R1,A
DEC R1
MOV A,B
MOV @R1,A
DEC R1
RET
INT_T0:
MOV TH0,#(65536-2000) / 256
MOV TL0,#(65536-2000) MOD 256
MOV A,#DISPBUF
ADD A,DISPBIT
MOV R0,A
MOV A,@R0
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P1,A
MOV A,DISPBIT
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV P3,A
INC DISPBIT
MOV A,DISPBIT
CJNE A,#08H,KNA
MOV DISPBIT,#00H
KNA: INC T2SCNTA
MOV A,T2SCNTA
CJNE A,#100,DONE
MOV T2SCNTA,#00H
INC T2SCNTB
MOV A,T2SCNTB
CJNE A,#05H,DONE
MOV T2SCNTB,#00H
INC SECOND
MOV A,SECOND
CJNE A,#60,NEXT
MOV SECOND,#00H
INC MINITE
MOV A,MINITE
CJNE A,#60,NEXT
MOV MINITE,#00H
INC HOUR
MOV A,HOUR
CJNE A,#24,NEXT
MOV HOUR,#00H
NEXT: LCALL DISP
DONE: RETI
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,40H
TAB: DB 0FEH,0FDH,0FBH,0F7H,0EFH,0DFH,0BFH,07FH
END
7. C語言源程序
#include <AT89X51.H>
unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x00};
unsigned char dispbitcode[]={0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f};
unsigned char dispbuf[8]={0,0,16,0,0,16,0,0};
unsigned char dispbitcnt;
unsigned char second;
unsigned char minite;
unsigned char hour;
unsigned int tcnt;
unsigned char mstcnt;
unsigned char i,j;
void main(void)
{
TMOD=0x02;
TH0=0x06;
TL0=0x06;
TR0=1;
ET0=1;
EA=1;
while(1)
{
if(P0_0==0)
{
for(i=5;i>0;i--)
for(j=248;j>0;j--);
if(P0_0==0)
{
second++;
if(second==60)
{
second=0;
}
dispbuf[0]=second%10;
dispbuf[1]=second/10;
while(P0_0==0);
}
}
if(P0_1==0)
{
for(i=5;i>0;i--)
for(j=248;j>0;j--);
if(P0_1==0)
{
minite++;
if(minite==60)
{
minite=0;
}
dispbuf[3]=minite%10;
dispbuf[4]=minite/10;
while(P0_1==0);
}
}
if(P0_2==0)
{
for(i=5;i>0;i--)
for(j=248;j>0;j--);
if(P0_2==0)
{
hour++;
if(hour==24)
{
hour=0;
}
dispbuf[6]=hour%10;
dispbuf[7]=hour/10;
while(P0_2==0);
}
}
}
}
void t0(void) interrupt 1 using 0
{
mstcnt++;
if(mstcnt==8)
{
mstcnt=0;
P1=dispcode[dispbuf[dispbitcnt]];
P3=dispbitcode[dispbitcnt];
dispbitcnt++;
if(dispbitcnt==8)
{
dispbitcnt=0;
}
}
tcnt++;
if(tcnt==4000)
{
tcnt=0;
second++;
if(second==60)
{
second=0;
minite++;
if(minite==60)
{
minite=0;
hour++;
if(hour==24)
{
hour=0;
}
}
}
dispbuf[0]=second%10;
dispbuf[1]=second/10;
dispbuf[3]=minite%10;
dispbuf[4]=minite/10;
dispbuf[6]=hour%10;
dispbuf[7]=hour/10;
}
❾ 基於單片機的數字時鍾設計開題報告
//我這里有一個定時的鬧鍾,你把蜂鳴器的中斷改為LED就行了,可以通過P2^0--P2^3實現秒錶的顯示和以及調時調分和調節鬧鍾以及鬧鍾的開關,有問題可以給我留言QQ834589429
#include<reg52.h>//包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
codeunsignedchartab[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//共陰數碼管0-9
sbitA1=P2^0;
sbitA2=P2^1;
sbitA3=P2^2;
sbitA4=P2^3;
sbitbeep=P1^4;
unsignedcharShiwan;
unsignedcharWanwei;
unsignedcharQianwei;
unsignedcharBaiwei;
unsignedcharShiwei;//定義十位
unsignedcharGewei,Naoling1,Naoling2,Naoling3,Naoling4;//定義個位
staticunsignedcharhour=12,minute=30,second=0,count=0;
staticunsignedcharalarmhour=12,alarmminute=29,i=0,j=0,k;
/******************************************************************/
/*延時函數*/
/******************************************************************/
voiddelay(unsignedintcnt)
{
while(--cnt);
}
voidxianshi(void)
{
Gewei=tab[second%10];//個位顯示處理
Shiwei=tab[second/10];//十位顯示值處理
if(second%2==0)
{
Baiwei=tab[minute%10];
Qianwei=tab[minute/10];//千位
}
else
{
Baiwei=(tab[minute%10]|0x80);//百位顯示處理:加點的字碼
Qianwei=(tab[minute/10]|0x80);
}
if(second%2!=0)
{
Wanwei=tab[hour%10];
Shiwan=tab[hour/10];
}
else
{
Wanwei=(tab[hour%10]|0x80);
Shiwan=(tab[hour/10]|0x80);
}
Naoling1=~tab[alarmhour%10];
Naoling2=~tab[alarmhour/10];
Naoling3=~tab[alarmminute%10];
Naoling4=~tab[alarmminute/10];
}
voidtimer0()interrupt3using1
{
TH1=0x3c;//中斷設置初始化
TL1=0xb0;
if(alarmhour==hour&&alarmminute==minute&&j==1)
{
beep=0;
}
}
/******************************************************************/
/*定時器中斷函數*/
/******************************************************************/
voidtimer1()interrupt1using0
{
TH0=0xd8;//重新賦值
TL0=0xf0;
count++;
xianshi();
if(count==99)//100x10ms=1S,大致延時時間
{
count=0;
second++;//秒加1
if(second==60)
minute++;
{
if(second==60)
second=0;
{
if(minute==60)
hour++;
{
if(minute==60)
minute=0;
{
if(hour==24)
hour=0;
}
}
}
}
}
}
/******************************************************************/
/*主函數*/
/******************************************************************/
voidmain()
{
TMOD|=0x01;//定時器設置10msin12Mcrystal,工作在模式1,16位定時
TH0=0xd8;
TL0=0xf0;
IE=0x82;//打開中斷
TR0=1;//打開定時開關
xianshi();
EA=1;ET0=1;TMOD|=0x21;TR0=1;//開中斷總開關,計數器0允許中斷,設置中斷模式,啟動計數器0
ET1=1;TR1=1;
while(1)
{
{
if(!A3)
{
delay(10000);
if(!A3)
{
i++;if(i==7)i=0;
xianshi();
}
}
}
{
if(!A4)
{
delay(10000);
if(!A4)
{
i--;if(i==255)i=6;
xianshi();
}
}
}
switch(i)
{
case0://正常顯示控制
{
P1=0x1e;//片選個位
P0=~Baiwei;//顯示個位
delay(300);//短暫延時
P1=0x1d;//片選十位
P0=~Qianwei;//顯示十位
delay(300);//短暫延時
P1=0x1b;//片選百位
P0=~Wanwei;//顯示百位
delay(300);//短暫延時
P1=0x17;//片選千位
P0=~Shiwan;//顯示千位
delay(300);//短暫延時
P1=0x1f;
P0=0xff;
delay(300);
};break;
case1://調分控制
{
if(second%2!=0)
{
P1=0x1e;//片選個位
P0=~Baiwei;//顯示個位
delay(300);//短暫延時
P1=0x1d;//片選十位
P0=~Qianwei;//顯示十位
delay(300);//短暫延時
P1=0x1f;
P0=0xff;
delay(300);
}
else
delay(300);
delay(300);
{
if(!A1)
{
delay(10000);//消抖
if(!A1)
{
minute++;if(minute==61)minute=0;
xianshi();
}
}//按鍵處理
}
{
if(!A2)
{
delay(10000);//消抖
if(!A2)
{
minute--;if(minute==255)minute=59;
xianshi();
}
}
}
};break;
case2://調時控制
{
if(second%2==0)
{
P1=0x1b;//片選百位
P0=~Wanwei;//顯示百位
delay(300);//短暫延時
P1=0x17;//片選千位
P0=~Shiwan;//顯示千位
delay(300);//短暫延時
P1=0x1f;
P0=0xff;
delay(300);
}
else
delay(300);
delay(300);
{
if(!A1)
{
delay(10000);//消抖
if(!A1)
{
hour++;if(hour==24)hour=0;
xianshi();
}
}//按鍵處理
}
{
if(!A2)
{
delay(10000);//消抖
if(!A2)
{
hour--;if(hour==255)hour=23;
xianshi();
}
}
}
};break;
case3://秒顯示控制
{
P1=0x1e;//片選個位
P0=~Gewei;//顯示個位
delay(300);//短暫延時
P1=0x1d;//片選十位
P0=~Shiwei;//顯示十位
delay(300);//短暫延時
P1=0x1f;
P0=0xff;
delay(300);
delay(300);
delay(300);
};break;
case4://鬧鍾控制
{
if((!A1)||(!A2))
{
delay(10000);
if((!A1)||(!A2))j++;
if(j==2)
j=0;
}
switch(j)
{
case0:{
P1=0x1e;//片選個位
P0=~0x71;//顯示個位
delay(300);//短暫延時
P1=0x1d;//片選十位
P0=~0x71;//顯示十位
delay(300);//短暫延時
P1=0x1b;//片選百位
P0=~0x3f;//顯示百位
delay(300);//短暫延時
P1=0x17;//片選千位
P0=~0x40;//顯示千位
delay(300);//短暫延時
delay(300);
};break;
case1:{
P1=0x1e;//片選個位
P0=~0x37;//顯示個位
delay(300);//短暫延時
P1=0x1d;//片選十位
P0=~0x3f;//顯示十位
delay(300);//短暫延時
P1=0x1b;//片選百位
P0=0xff;//顯示百位
delay(300);//短暫延時
P1=0x17;//片選千位
P0=~0x40;//顯示千位
delay(300);//短暫延時
delay(300);
}
}
};break;
case5://鬧鈴分鍾調整
{
{
P1=0x1e;
P0=Naoling3;
delay(300);
P1=0x1d;
P0=Naoling4;
delay(300);
P1=0x1f;
P0=0xff;
delay(300);
delay(300);
delay(300);
}
{
if(!A1)
{
delay(10000);//消抖
if(!A1)
{
alarmminute++;if(alarmminute==61)alarmminute=0;
}
}//按鍵處理
}
{
if(!A2)
{
delay(10000);//消抖
if(!A2)
{
alarmminute--;if(alarmminute==255)alarmminute=59;
}
}
}
};break;
case6://鬧鈴小時調整
{
{
P1=0x1b;
P0=Naoling1;
delay(300);
P1=0x17;
P0=Naoling2;
delay(300);
P1=0x1f;
P0=0xff;
delay(300);
delay(300);
delay(300);
}
{
if(!A1)
{
delay(10000);//消抖
if(!A1)
{
alarmhour++;if(alarmhour==24)alarmhour=0;
}
}//按鍵處理
}
{
if(!A2)
{
delay(10000);//消抖
if(!A2)
{
alarmhour--;if(alarmhour==255)alarmhour=23;
}
}
};break;
default:break;
}
}
}
}
❿ 求單片機數字鍾的設計程序及電路模擬圖!急!急!急!急!
呵呵呵,你走運了,我做過課後作業,有問題以再問我
帶調時間的數字鍾
定時器1s觸發中斷一次,計時+1,主程序負責傳輸時間到led及檢測按鍵,其他見注釋。
左面有器件列表,這個是protenus模擬
ORG 0000H
AJMP MAIN
ORG 000BH
LJMP T0INT
ORG 001BH
LJMP T1INT
ORG 0100H
MAIN: MOV TMOD,#51H ;T0定時器方式1,T1計數器方式1
MOV TCON,#54H ;開定時計數器,T1邊沿觸發
MOV TH0,#4BH ;(65536-19453)*1.085=50MS,晶振11.0592MHZ
MOV TL0,#0FFH ;去掉了裝載畝擾初值用的機器周期
MOV TH1,#0FFH ;滿10溢出,1S
MOV TL1,#0F6H
MOV IE,#8AH ;開中斷
MOV R7,#04H ;預置13:58:00 的時
MOV R2,#13H
MOV A,R2
LCALL DISPLAY
MOV R7,#02H ;預置13:58:00 的分
MOV R1,#58H
MOV A,R1
LCALL DISPLAY
CHECKKEY:LCALL KEY1
LCALL KEY2
LCALL KEY3
LCALL KEY4
AJMP CHECKKEY
;;;;;;;;;;中斷;;;;;;;;;;;;;;;;;;;;;;
T0INT: MOV TH0,#4BH
MOV TL0,#0FDH
CPL P2.0
RETI
T1INT: MOV TH1,#0FFH
MOV TL1,#0F6H
PUSH ACC
CPL P2.1
MOV A,R0 ;R0計秒鍾,通過A調整為BCD碼
ADD A,#1
DA A
MOV R0,A
CJNE R0,#60H,MIAO
MOV R0,#00H
MOV A,R1 ;R1計分鍾,通過A調整為BCD碼
ADD A,#1
DA A
MOV R1,A
CJNE R1,#60H,FEN
MOV R1,#00H
MOV A,R2 ;R2計時鍾,通過A調整為BCD碼
ADD A,#1
DA A
MOV R2,A
CJNE R2,#24H,SHI
MOV R2,#00H
SHI: MOV R7,#04H
MOV A,R2
LCALL DISPLAY
FEN: MOV R7,#02H
MOV A,R1
LCALL DISPLAY
MIAO: MOV R7,#01H
MOV A,R0
LCALL DISPLAY
POP ACC
RETI
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;顯示
;A--顯示BCD碼,R7--選擇數碼管
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DISPLAY:MOV P1,R7
MOV SCON,#0
MOV SBUF,A
JNB TI,$
CLR TI
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;按鍵檢測與執行程序
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
KEY1: JB P0.0,DONE1 ;檢測P0.0口按鍵,若沒按下,則結束
LCALL DELAY ;延時去抖
JB P0.0,DONE1 ;再次檢測,若沒按下,則結束
JNB P0.0,$ ;等待按鍵松開
CPL EA ;開關定時中斷
DONE1: RET
KEY2: JB EA,DONE2 ;若EA=1,則調時間按鍵無效
JB P0.1,DONE2 ;檢測P0.0口按鍵,棗敬若沒按下凳耐慎,則結束
LCALL DELAY ;延時去抖
JB P0.1,DONE2 ;再次檢測,若沒按下,則結束
MOV A,R2 ;R2計時鍾+1,通過A調整為BCD碼
ADD A,#1
DA A
CJNE A,#24H,CHECK2
MOV A,#00H
CHECK2: MOV R2,A
MOV R7,#04H ;顯示改後的時間
MOV A,R2
LCALL DISPLAY
DONE2: RET
KEY3: JB EA,DONE3
JB P0.2,DONE3
LCALL DELAY
JB P0.2,DONE3
MOV A,R1 ;R1計分鍾+1,通過A調整為BCD碼
ADD A,#1
DA A
CJNE A,#60H,CHECK3
MOV A,#00H
CHECK3: MOV R1,A
MOV R7,#02H ;顯示改後的時間
MOV A,R1
LCALL DISPLAY
DONE3: RET
KEY4: JB EA,DONE4
JB P0.3,DONE4
LCALL DELAY
JB P0.3,DONE4
MOV A,R0 ;R0計秒鍾+1,通過A調整為BCD碼
ADD A,#1
DA A
CJNE A,#60H,CHECK4
MOV A,#00H
CHECK4: MOV R0,A
MOV R7,#01H ;顯示改後的時間
MOV A,R0
LCALL DISPLAY
DONE4: RET
;;;;;;;;DELAY;;;;;;;;;;;;;;;;;;
DELAY: MOV R4,#0FFH
DL: MOV R5,#0FFH
DJNZ R5,$
DJNZ R4,DL
RET