|
多功能秒表加語音播報(bào)
正計(jì)時(shí)模式倒計(jì)時(shí)模式存儲(chǔ)和語音播報(bào)
單片機(jī)課設(shè)你加了語音就不會(huì)一樣了
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (21.42 KB, 下載次數(shù): 56)
下載附件
2018-12-20 17:09 上傳
單片機(jī)源碼如下:
#include<reg51.h> //頭文件
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit p1=P2^7; //定義數(shù)碼關(guān)位選
sbit p2=P2^6;
sbit p3=P2^5;
sbit p4=P2^4;
sbit dp=P0^7;
sbit yuyin=P1^0; //開始按鍵
sbit kaishi=P1^1; //開始按鍵
sbit jilu=P1^2; //記錄按鍵
sbit qingling=P1^3; //清零按鍵
sbit fangxiang=P1^4;//方向按鍵
sbit shezhi=P1^5; //設(shè)置按鍵
sbit zsd=P3^5; //指示燈
sbit fmq=P2^2; //蜂鳴器
uchar shuju[4]; //數(shù)碼管顯示變量
uchar code data_7seg[13]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xab,0xa3}; //共陽(yáng)數(shù)碼管顯示段碼
uchar idata shuju_fen[10]; //保存記錄的秒存儲(chǔ)器
uchar idata shuju_miao[10]; //保存記錄的10毫秒存儲(chǔ)器
uchar count;count1;count2;count3,fx=0;ks=0;sz=0;ss=0;a,b;biaozhi=0;moshi=0;naozhong=0;sss=0;sjd=0;jiwei=0;jishu=0;xuhuan;chakan=0;jw=0;wz=1; //變量
char fen,miao;fen1=0,miao1=0; //設(shè)置是的變量
sbit P_DATA = P2^0; //定義數(shù)據(jù)傳輸端口對(duì)應(yīng)語音芯片P03
uchar daima,bofang=0;
uchar ddd;
//一線,二線,三線有關(guān)
#define H 1 //定義1為高電平
#define L 0 //定義0為低電平
//////////////變量/////////////////
//bit flag = 1;
bit B_DATA; //傳輸數(shù)據(jù)一位
unsigned char SB_DATA = 0; //一字節(jié)公用數(shù)據(jù)緩存器
unsigned char S_DATA = 0x00;
void delay1s(void) //誤差 0us
{
unsigned char a,b,c;
for(c=167;c>0;c--)
for(b=171;b>0;b--)
for(a=16;a>0;a--);
_nop_(); //if Keil,require use intrins.h
}
void delay500ms(void) //誤差 0us
{
unsigned char a,b,c;
for(c=23;c>0;c--)
for(b=152;b>0;b--)
for(a=70;a>0;a--);
}
void delay5ms(void) //誤差 0us
{
unsigned char a,b;
for(b=19;b>0;b--)
for(a=130;a>0;a--);
}
void delay200us(void) //誤差 0us
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=97;a>0;a--);
}
/*--------------------------------------
;模塊名稱:Line_1A(void)
;功 能:實(shí)現(xiàn)一線單字節(jié)低位在前串口通信函數(shù)
;入 參:無
;出 參:0 返回主函數(shù)
;-------------------------------------*/
void Line_1A(unsigned char dat)
{
unsigned char i;
//********************************************************
P_DATA = 0;
delay5ms(); //拉低至少5ms
B_DATA = dat&0X01;
for(i=0;i<8;i++)
{
P_DATA = 1; //拉高數(shù)據(jù)傳輸線,準(zhǔn)備傳輸數(shù)據(jù)
if(B_DATA==0)
{ /*表示邏輯電平0*/
delay200us(); // 延時(shí)200us
P_DATA = 0;
delay200us(); // 延時(shí)600us
delay200us();
delay200us();
}
else
{ /*表示邏輯電平1*/
delay200us();
delay200us();
delay200us();
P_DATA = 0;
delay200us();
}
dat = dat>>1;
B_DATA = dat&0X01;
}
P_DATA = 1; //拉高電平
}
void mp3()
{ if (yuyin==0) //置零按鍵按下
{ ET1=1;
TR1=1;
if(fx==0)
Line_1A(14);
else
Line_1A(13);
delay1s();
delay1s();
if(fen/10==1)
{Line_1A(10);delay500ms();
if(fen%10>=1)
{Line_1A(fen%10); delay500ms(); }
}
else
if(fen/10>1)
{Line_1A(fen/10);delay500ms();
Line_1A(10);delay500ms();
if(fen%10>=1)
{Line_1A(fen%10); delay500ms(); }
}
else
{Line_1A(fen%10);delay500ms();}
Line_1A(11);
delay500ms();
if(miao/10==1)
{Line_1A(10);delay500ms();
if(miao%10>=1)
{Line_1A(miao%10); delay500ms(); }
}
else
if(miao/10>1)
{Line_1A(miao/10);delay500ms();
Line_1A(10);delay500ms();
if(miao%10>=1)
{Line_1A(miao%10); delay500ms(); }
}
else
{Line_1A(miao%10);delay500ms();}
Line_1A(12);
delay500ms();
}while(yuyin==0);
ET1=0;
TR1=0;
}
void qudou(void) //去抖延遲
{ int i;
for(i=0;i<2400;i++);
}
void Delay1ms(unsigned int xs) //顯示延遲程序
{ unsigned int i,j;
for(i=0;i<xs;i++)
for(j=0;j<0;j++);
}
void xianshi() //顯示程序
{ p1=0;p2=0;p3=0;p4=0;
P0=data_7seg[shuju[0]];
p1=1;p2=0;p3=0;p4=0;
Delay1ms(10);
p1=0;p2=0;p3=0;p4=0;
P0=data_7seg[shuju[1]];
p1=0;p2=1;p3=0;p4=0;
if(sss==0)
dp=0;
else
dp=1;
Delay1ms(10);
p1=0;p2=0;p3=0;p4=0;
P0=data_7seg[shuju[2]];
p1=0;p2=0;p3=1;p4=0;
Delay1ms(10);
p1=0;p2=0;p3=0;p4=0;
P0=data_7seg[shuju[3]];
p1=0;p2=0;p3=0;p4=1;
Delay1ms(10);
p1=0;p2=0;p3=0;p4=0;
zsd=!fx; //方向指示燈
}
void chakanmoshi() //查看記錄子程序
{if(jiwei==0) jw=0;
if(jiwei>0)
if(jiwei<=10) jw=jiwei;
if(jiwei>10) jw=10;
wz=1;
sss=0;
while(chakan==1)
{if(jw==0)
{shuju[0]=10;
shuju[1]=11;
shuju[2]=12;
shuju[3]=10;
sss=1;
}
else
{qingling=1; //按鍵按下查看上一數(shù)據(jù)
if(qingling==0)
{ qudou();
if(qingling==0)
{wz++;
if(wz>jw) wz=1;
}while(qingling==0);
}
fangxiang=1; //按鍵按下查看下一數(shù)據(jù)
if(fangxiang==0)
{ qudou();
if(fangxiang==0)
{wz--;
if(wz<=0) wz=jw;
}while(fangxiang==0);
}
shezhi=1; //記錄清零
if(shezhi==0)
{ qudou();
if(shezhi==0)
{jiwei=0;jw=0;wz=1;
}while(shezhi==0);
}
if(sss==0)
{shuju[0]=shuju_fen[jw-wz]/10; //顯示查看的數(shù)據(jù)轉(zhuǎn)成數(shù)碼管顯示數(shù)據(jù)
shuju[1]=shuju_fen[jw-wz]%10;
shuju[2]=shuju_miao[jw-wz]/10;
shuju[3]=shuju_miao[jw-wz]%10;
}
else
{shuju[0]=10;
shuju[1]=wz/10;
shuju[2]=wz%10;
shuju[3]=10;
}
}
xianshi();
jilu=1; //按下退出查看
if(jilu==0)
{ qudou();
if(jilu==0)
{chakan=0;
}while(jilu==0);
}
}
chakan=0;sss=0;count3=0;
}
void key()
{ kaishi=1; //按下切換開始和暫停
if(kaishi==0)
{ qudou();
if(kaishi==0)
{ks=!ks; //ks是開始標(biāo)志
}while(kaishi==0);
}
if(ks==1) //開始狀態(tài)
if(fx==0) //正計(jì)時(shí)方向
if(moshi==0) //模式為秒表模式
{jilu=1; //記錄按鍵按下
if(jilu==0) //記錄數(shù)據(jù)
{ qudou();
if(jilu==0)
{jiwei++; //把數(shù)據(jù)存儲(chǔ)到存儲(chǔ)器里
for(xuhuan=0;xuhuan<=8;xuhuan++)
{shuju_fen[9-xuhuan]=shuju_fen[8-xuhuan];
shuju_miao[9-xuhuan]=shuju_miao[8-xuhuan];}
shuju_fen[0]=fen;
shuju_miao[0]=miao;
}while(jilu==0);
}}
if(ks==0 && chakan==0)
mp3();
if(ks==0) //暫停狀態(tài)
{jilu=1; //記錄按鍵按下
if(jilu==0)
{ qudou();
if(jilu==0)
{chakan=1; //查看模式標(biāo)志,準(zhǔn)備進(jìn)入查看記錄子程序
}while(jilu==0);
}
}
if(chakan==1) chakanmoshi(); //進(jìn)入查看子程序
qingling=1; //清零按鍵按下,計(jì)時(shí)重新開始
if(qingling==0)
{ qudou();
if(qingling==0)
{if(fx==0)
{fen=0;miao=0;count=0;}
else
{fen=fen1;miao=miao1;count=0;}
}while(qingling==0);
}
if(ks==0) //暫停狀態(tài)
{fangxiang=1; //方向按鍵按下,改變計(jì)時(shí)方向,即正計(jì)時(shí)和倒計(jì)時(shí)
if(fangxiang==0)
{ qudou();
if(fangxiang==0)
{fx=!fx; //fx方向標(biāo)志
count=0;
fen1=0,miao1=0;
moshi=0;
}while(fangxiang==0);
}
}
if(ks==0)
{
shezhi=1; //設(shè)置按鍵按下
if(shezhi==0)
{ qudou();
if(shezhi==0)
{ sz=1;fen1=0,miao1=0;count1=0; //進(jìn)入設(shè)置子程序
}while(shezhi==0);
}
}
}
void key1() //設(shè)置時(shí)按鍵掃描程序
{ shezhi=1; //設(shè)置鍵按下
if(shezhi==0)
{ qudou();
if(shezhi==0)
{ sz++; //調(diào)整設(shè)置的目標(biāo)
if(sz==5) sz=0;
}while(shezhi==0);
}
jilu=1; //記錄按鍵按下,在設(shè)置時(shí)功能是加1
if(jilu==0)
{ qudou();
if(jilu==0)
{switch(sz)
{case 1:a=fen1/10;b=fen1%10; a++;if(a>=10) a=0;fen1=a*10+b;break;
case 2:a=fen1/10;b=fen1%10; b++;if(b>=10) b=0;fen1=a*10+b;break;
case 3:a=miao1/10;b=miao1%10; a++;if(a>=10) a=0;miao1=a*10+b;break;
case 4:a=miao1/10;b=miao1%10; b++;if(b>=10) b=0;miao1=a*10+b;break;
}
}while(jilu==0);
}
qingling=1; //清零按鍵按下,在設(shè)置時(shí)功能是減1
if(qingling==0)
{ qudou();
if(qingling==0)
{ switch(sz)
{case 1:a=fen1/10;b=fen1%10; a--;if(a<0) a=9;fen1=a*10+b;break;
case 2:a=fen1/10;b=fen1%10; b--;if(b<0) b=9;fen1=a*10+b;break;
case 3:a=miao1/10;b=miao1%10; a--;if(a<0) a=9;miao1=a*10+b;break;
case 4:a=miao1/10;b=miao1%10; b--;if(b<0) b=9;miao1=a*10+b;break;
}
}while(qingling==0);
}
if(ks==0)
{fangxiang=1; //方向按鍵按下,在設(shè)置時(shí)功能是保存數(shù)據(jù),并立即退出設(shè)置
if(fangxiang==0)
{ qudou();
if(fangxiang==0)
{ sz=0;
}while(fangxiang==0);
}
}
}
void shuju_date() //把要顯示的數(shù)據(jù)轉(zhuǎn)化成數(shù)碼管顯示的代碼
{if(sz==0)
{shuju[0]=fen/10;
shuju[1]=fen%10;
shuju[2]=miao/10;
shuju[3]=miao%10;}
else
{shuju[0]=fen1/10;
shuju[1]=fen1%10;
shuju[2]=miao1/10;
shuju[3]=miao1%10;
if(ss==1)
{if(sz==1) shuju[0]=10;
else if(sz==2) shuju[1]=10;
else if(sz==3) shuju[2]=10;
else if(sz==4) shuju[3]=10;
}
}
}
void panduan() //模式判斷子程序
{biaozhi=0; //進(jìn)入判斷標(biāo)志清零
if(fx==0) //方向?yàn)檎?jì)時(shí)
{if(miao1==0)
{if(fen1==0) moshi=0; //設(shè)置的時(shí)間為0,模式就為0:秒表模式
else moshi=1;fen=0;miao=0;} //設(shè)置的時(shí)間不為0,模式就為1:定時(shí)模式
else moshi=1;fen=0;miao=0;} //設(shè)置的時(shí)間不為0,模式就為1:定時(shí)模式
else
{fen=fen1;miao=miao1;} //方向?yàn)榈褂?jì)時(shí),模式就為2:倒計(jì)時(shí)模式
}
void jiegou() //結(jié)果處理子程序
{if(fx==0)
{if(moshi==0) //秒表模式
{while(fen>=100) //計(jì)時(shí)超過范圍,顯示“----”
{jishu=1;
if(sss==0)
{p1=0;p2=0;p3=0;p4=0;
P0=0xbf; //顯示“----”
p1=1;p2=0;p3=0;p4=0;
Delay1ms(10);
p1=0;p2=0;p3=0;p4=0;
P0=0xbf;
p1=0;p2=1;p3=0;p4=0;
Delay1ms(10);
p1=0;p2=0;p3=0;p4=0;
P0=0xbf;
p1=0;p2=0;p3=1;p4=0;
Delay1ms(10);
p1=0;p2=0;p3=0;p4=0;
P0=0xbf;
p1=0;p2=0;p3=0;p4=1;
Delay1ms(10);
p1=0;p2=0;p3=0;p4=0;
}
else
{p1=0;p2=0;p3=0;p4=0;
P0=0xff; //顯示“----”
p1=1;p2=0;p3=0;p4=0;
Delay1ms(10);
p1=0;p2=0;p3=0;p4=0;
P0=0xff;
p1=0;p2=1;p3=0;p4=0;
Delay1ms(10);
p1=0;p2=0;p3=0;p4=0;
P0=0xff;
p1=0;p2=0;p3=1;p4=0;
Delay1ms(10);
p1=0;p2=0;p3=0;p4=0;
P0=0xff;
p1=0;p2=0;p3=0;p4=1;
Delay1ms(10);
p1=0;p2=0;p3=0;p4=0;
}
fmq=sss;
kaishi=1; //開始按鍵按下
if(kaishi==0)
{ qudou();
if(kaishi==0)
{ks=10;fen=0;miao=0;sss=0;jishu=0; //計(jì)時(shí)清零,并返回秒表模式,等待開始計(jì)時(shí)
}while(kaishi==0);
}
}
fmq=1;
count2=0;
sss=0;
}
else //定時(shí)模式
{if(miao==miao1)
if(fen==fen1) naozhong=1; //時(shí)間到,鬧鐘標(biāo)志為1,鬧鐘開啟
while(naozhong==1) //進(jìn)入鬧鐘開啟狀態(tài)
{ jishu=1;
ks=0; //計(jì)時(shí)停止
if(sss==0) //以下顯示實(shí)現(xiàn)顯示閃爍(代碼)
{shuju[0]=fen/10;
shuju[1]=fen%10;
shuju[2]=miao/10;
shuju[3]=miao%10;
}
else
{shuju[0]=10;
shuju[1]=10;
shuju[2]=10;
shuju[3]=10;
}
fmq=sss;
xianshi(); //顯示
kaishi=1; //開始按鍵按下
if(kaishi==0)
{ qudou();
if(kaishi==0)
{naozhong=0;fen=0;miao=0;sss=0;jishu=0; //退出
}while(kaishi==0);
}
}
fmq=1;
count2=0;
sss=0;
}
}
else
{if(ks==1) //開始狀態(tài)
{if(fen==0)
if(miao==0) sjd=1;} //倒計(jì)時(shí)結(jié)束
while(sjd==1) //時(shí)間到處理
{ jishu=1;
ks=0; //計(jì)時(shí)停止
if(sss==0) //以下顯示實(shí)現(xiàn)顯示閃爍(代碼)
{shuju[0]=fen/10;
shuju[1]=fen%10;
shuju[2]=miao/10;
shuju[3]=miao%10;
}
else
{shuju[0]=10;
shuju[1]=10;
shuju[2]=10;
shuju[3]=10;
}
fmq=sss;
xianshi(); //顯示
kaishi=1; //開始按鍵按下
if(kaishi==0)
{ qudou();
if(kaishi==0)
{sjd=0;fen=fen1;miao=miao1;sss=0;jishu=0; //退出
}while(kaishi==0);
}
}
fmq=1;
count2=0;
sss=0;
}
}
void main() //主程序
{ TMOD=0x11; //定義中斷,用來計(jì)時(shí)
TH0=0x0D8;
TL0=0x0F0;
TR0=1;
ET0=1;
TH1=0x0FC;
TL1=0x18;
ET1=0;
TR1=0;
EA=1;
while(1)
{shuju_date(); //數(shù)據(jù)轉(zhuǎn)化成顯示代碼子程序
xianshi(); //顯示程序
key(); //按鍵掃描
while(sz>0) //進(jìn)入設(shè)置模式
{biaozhi=1; //退出設(shè)置時(shí),進(jìn)入判斷標(biāo)志
key1(); //設(shè)置按鍵掃描
shuju_date(); //數(shù)據(jù)轉(zhuǎn)化成顯示代碼子程序
xianshi(); //顯示程序
}
if(biaozhi==1) panduan(); //退出設(shè)置時(shí),進(jìn)入判斷模式
jiegou(); //計(jì)時(shí)結(jié)果處理
}
}
void time0(void) interrupt 1 //中斷計(jì)時(shí)
{ TH0 = 0x0D8;
TL0 = 0x0F0;
if(fx==1)
if(ks==1)
{if(fen==0)
if(miao==0) {sjd=1;ks=0;}}
if(ks==1)
{count++;
if(count==1)
{ count=0;
if(fx==0)
{miao++;
if(miao>=100) {miao=0;fen++;} // 正計(jì)時(shí)
}
else
{miao--;
if(miao<0) {fen--;miao=99;} //倒計(jì)時(shí)
}
}
}
if(sz>0) //設(shè)置時(shí)閃爍
{count1++;
if(count1==100)
{ss=!ss;
count1=0;
}
}
if(jishu==1)
{count2++;
if(count2==100)
{sss=!sss;
count2=0;
}
}
if(jw>0) //查看記錄是,顯示顯示切換
{count3++;
if(count3==100)
{sss=!sss;
count3=0;
}
}
}
void Timer1Interrupt(void) interrupt 3
{
TH1 = 0x0FC;
TL1 = 0x18;
switch(ddd)
{case 0:
p1=0;p2=0;p3=0;p4=0;
P0=data_7seg[shuju[0]];
p1=1;p2=0;p3=0;p4=0;
break;
case 1:
p1=0;p2=0;p3=0;p4=0;
P0=data_7seg[shuju[1]];
p1=0;p2=1;p3=0;p4=0;
if(data_7seg[shuju[1]]==0xab)
dp=1;
else if(chakan==1 && sss==1)
dp=1;
else
dp=0;
break;
case 2:
p1=0;p2=0;p3=0;p4=0;
P0=data_7seg[shuju[2]];
p1=0;p2=0;p3=1;p4=0;
break;
case 3:
p1=0;p2=0;p3=0;p4=0;
P0=data_7seg[shuju[3]];
p1=0;p2=0;p3=0;p4=1;
break;
}
ddd++;
if(ddd==4) ddd=0;
}
全部資料51hei下載地址:
電路仿真.rar
(23.87 KB, 下載次數(shù): 136)
2018-12-20 13:06 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|