單片機(jī)實(shí)驗(yàn)總結(jié)_第1頁
單片機(jī)實(shí)驗(yàn)總結(jié)_第2頁
單片機(jī)實(shí)驗(yàn)總結(jié)_第3頁
單片機(jī)實(shí)驗(yàn)總結(jié)_第4頁
單片機(jī)實(shí)驗(yàn)總結(jié)_第5頁
已閱讀5頁,還剩89頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

心得:1.勞勞逸(腦力勞動,體力勞動,娛

樂活動)2.發(fā)現(xiàn)問題,解決問題就是在你的

大腦中建立廣泛的聯(lián)系3.條縷清晰的做事風(fēng)

格會讓你的大腦變得異常秩序,清晰。做到

了此三點(diǎn)你的大腦會一天天聰明,清楚,靈

活起來。反過來有秩序的大腦將會使你的行

為更加利索,清晰。

注意:我的人生需注意1.不要口出妄語,只

要腳踏實(shí)地。2.不要輕易生氣,不要輕易露

出邪惡的表情。3.不要做作要自然。4.不要

猥瑣,慌張,要大方,放松,鎮(zhèn)定,讓自己

盡量多的處在禪定狀態(tài)中

2010年5月8日

單片機(jī)學(xué)習(xí)中的問題總結(jié):(天才可以被訓(xùn)練出來,任何人可以在任何領(lǐng)域取得驚人的

成就,只要你對你所從事的領(lǐng)域感興趣,并能長久地保持專注,并具有吃苦耐勞的精神。你

的成功與否取決于你的思維方式(習(xí)慣)訓(xùn)練的過程是一個不斷積累模式的過程,而解決問

題的過程最后就變成了對模式進(jìn)行識別的過程。訓(xùn)練到最后拿到一個問題你可以在0.8秒內(nèi)

迅速再現(xiàn)頭腦中類似的模式并憑借直覺給出解決問題的絕佳方式。那樣你就是一個天才(后

天培養(yǎng)的人才)

說明:黑色的程序代表沒有問題可以直接用,綠色代代存正缺陷而要改進(jìn),紫色代表自創(chuàng)的

程序精華!紅色代表要交代的重點(diǎn)內(nèi)容

4.22

1.%bx代表什么數(shù)據(jù)類型呢?

2.串口調(diào)試時有時會發(fā)送和接收不一?

3.直接對P1口取反可以實(shí)現(xiàn)滅亮的時間對等,但是通過對P1口賦值則比較復(fù)雜!

4.做計數(shù)顯示于LED上的實(shí)驗(yàn)的時候不太明白當(dāng)按下鍵后P3.4被拉低但是當(dāng)松開手的時候

是什么因素導(dǎo)致了此口被抬為高電平呢詳見D:\dpj\shiyanji\lessonl_4\計數(shù)器實(shí)驗(yàn)????

5.在利用單片機(jī)進(jìn)行音樂播放的時候需要注意一下幾點(diǎn):1.對于音樂的編碼是遵循音調(diào)常數(shù),

節(jié)拍常數(shù),音調(diào)常數(shù),節(jié)拍常數(shù),的順序進(jìn)行的數(shù)組組合。2.音樂的最小單元是音

符,每個音符又分為音高和音長,其中控制音高的稱為音調(diào)常數(shù)(共21個),控制音長的叫

節(jié)拍常數(shù)(共7個分別為四分之一拍0x10,半拍0x20,3/4拍0x30,1拍0x40,1又1/2拍0x60,2

拍0x80,4拍0x100),其中這兩個常數(shù)變量又分別由控制節(jié)拍常數(shù)變量的定時器中斷服務(wù)子

程序和控制頻率常數(shù)變量的延時程序來控制。

6.驅(qū)動三極管一般只工作在飽和和截止兩種狀態(tài)下,只有當(dāng)三極管用在放大電路中時才工作

在放大區(qū)。

7.注意DOFLY的板子采用的是:1.利用573鎖存器來驅(qū)動段,利用三八譯碼器來驅(qū)動位選。

8.松手檢測和松手處理不是同一個概念。松手去抖操作一般不進(jìn)行。硬件按鍵去抖有:1.濾

波去抖和雙穩(wěn)態(tài)去抖!所謂的雙穩(wěn)態(tài)即為RS觸發(fā)器,所謂的濾波即為在按鍵之后加入一個

濾波器和一個反向器以實(shí)現(xiàn)在鍵按下后輸出正規(guī)的方波。

9.LCD液晶顯示器依據(jù)內(nèi)容分為段式,點(diǎn)陣式,以及字符式其中字符式應(yīng)用最為簡單。進(jìn)一

步可學(xué)習(xí)圖案式LCD.1602內(nèi)部的控制驅(qū)動器是HD44780.DDRAM:用于存放LCD要顯示的

數(shù)據(jù),只要將標(biāo)準(zhǔn)的ASCII碼送入DDRAM中內(nèi)部的控制電路將自動將數(shù)據(jù)送到顯示器上

進(jìn)行顯示。

10.總結(jié):要學(xué)會使用別人編好的功能程序包!例如LCD顯示驅(qū)動功能程序包!12c總線驅(qū)

動功能程序包。

二.經(jīng)典程序收集

(1)利用定時計數(shù)器0實(shí)現(xiàn)計數(shù)功能

#include<reg52.h>

voidmain()

{TMOD=0X05;

TH0=0;

TL0=0;

TF0=0;

IE=0;

TR0=l;

//init();

while(l)

{Pl=TL0;

/*if(p34==0)

(

p34=l;

temp++;

Pl=temp;

}*/

問題與思考:誰來講P3.4口的點(diǎn)評拉高?按鍵抖動問題在此難道不需要予以考慮嗎?為什

么沒有加入去抖程序卻沒有抖動?此處的初值不用反復(fù)復(fù)是因?yàn)槟J(rèn)為0.

(2)定時計數(shù)器1的計數(shù)功能實(shí)驗(yàn)

1#include<reg52.h>

2#defineucharunsignedchar

3//uchartemp;

4//sbitp34=P3A4;

5//voidinit();

6uchari=0;

7voidmain()

8{TMOD=0X60;

91THl=0xfe;

101TLl=0xfe;

111TF1=O;

121TR1=1;

131//init();

141while(l)

151

161(

172while(!TFl);

182TF1=O;

192++i;

202Pl=i;

212/*if(p34==0)

222{

232p34=l;

242temp++;

252Pl=temp;

262}*/

272)

281)

問題與思考一:同上此處的初始值不用反復(fù)復(fù)由于使用的工作方式2.

(3)串口通信實(shí)驗(yàn):利用P3.0,P3.1實(shí)現(xiàn)字符串的發(fā)送。

#include<reg52.h>

#include<intrins.h>

#defineucharunsignedchar

#defineuintunsignedint

uchartrdata[]={'8';0,;c,;5,;r,0x0d,0x0a,0x00);

voidmain()

(

uinti,j;

SCON=0X40;

PCON=0;

//REN=1;〃有沒有它也是不影響串口通信的因?yàn)樗辉趩纹瑱C(jī)接收的時候才要求必須置

TMOD=0X20;

TH1=OXE6;

TL1=OXE6;

//TI=1;//說明:有沒有這個都不影響串口通信且位為有硬件置一

TR1=1;

while(l)

i=0;

while(trdata[i]!=OxOO)

{

SBUF=trdata[i];

while(TI==O);

TI=O;

i++;

)

for(j=0;j<50000;j++);

)

)

說明:當(dāng)TI=1且SBUF=,A,時便啟動了串口的發(fā)送計算機(jī)將接受到單片機(jī)發(fā)過來的數(shù)據(jù)Ao

REN=1;雖說對于發(fā)送而言可有可無但是最好還是加上吧!

(4)數(shù)碼管的動態(tài)十分交替顯示123456和050906的規(guī)范化程序

#include<reg52.h>

#defineucharunsignedchar

ucharcodedula[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

ucharcodewela[]={0x00,0x0i,0x02,0x03,0x04,0x05};

uchara,b,flag,temp;

sbitp37=P3A7;

voiddelay(uchar);

voiddisplay(uchar,uchar);

voidinit();

voidmain()

(

while(l)

(

uchari;

for(i=0;i<90;i++)

(

display(6,l);

delay(2);

display(5,2);

delay(2);

display(4,3);

delay(2);

display(3,4);

delay(2);

display(2,5);

delay(2);

display。,6);

delay(2);

for(i=0;i<90;i++)

{

display(6,0);

delay(2);

display(5,5);

delay(2);

display(4,0);

delay(2);

display(3,9);

delay(2);

display(2,0);

delay(2);

display(l,6);

delay(2);

)

)

)

voiddelay(ucharx)

(

ucharj;

for(;x>0;x-)

for(j=0;j<125;j++);

}

voiddisplay(uchara,ucharnum)

(

switch(a)

(

case6:p37=l,P0=dula[num],P2=wela[0],p37=0;break;

case5:p37=l,P0=dula[num],P2=wela[l],p37=0;break;

case4:p37=l,P0=dula[num],P2=wela[2],p37=0;break;

case3:p37=hP0=dula[num],P2=wela[3],p37=0;break;

case2:p37=l,P0=dula[num],P2=wela[4],p37=0;break;

case1:p37=l,P0=dula[num],P2=wela[5],p37=0;break;

default:break;

)

)

思考:用此程序?qū)崿F(xiàn)比起我原來寫的那個程序要好不必寫兩個顯示函數(shù)了減少了程序的篇幅

提高了效率,而且使得整個程序看上去整齊劃一非常之規(guī)范,利用子函數(shù)實(shí)現(xiàn)特定的功能實(shí)

現(xiàn)模塊化程序設(shè)計的思路必須得以貫徹,子程序的效率也要必須得以提高!

注意:此程序在延遲時間上并不準(zhǔn)確的實(shí)現(xiàn)一秒顯示,顯示123456為480ms顯示050906

為480ms因此從一個123456到另一個持續(xù)時間為960毫秒小于一秒。

(5)自編的高效矩陣鍵盤檢測程序

#include<reg52.h>

#defineucharunsignedchar

ucharcode

table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0

x76,0x38,0x3e,0x6e,0x00};

uchartemp=0;

//sbitp37=P3A7;

voiddelay(uchar);

voiddisplayO;

ucharkeyscan();

voidmain()

(

P2=0x02;

while(l)

(

display();

)

)

voiddelay(ucharx)

(

ucharj;

for(;x>0;x-)

for(j=0;j<125;j++);

)

ucharkeyscan()

(

P3=0x0f;

temp=P3&0x0f;

if(temp!=0x0f)

(

delay(lO);

temp=P3&0x0f;

if(temp!=0x0f)

(

temp=P3&0x0f;

P3=OxfO;

P3=P3&OxfO;

if(P3!=OxfO)

(

delay(lO);

P3=P3&0xf0;

if(P3!=0xft))

temp=temp+P3;

returntemp;

voiddisplayO

uchartemp;

temp=keyscan();

switch(temp)

case0x7e:P0=table[1];break;

case0x7d:P0=table[2];break;

case0x7b:P0=table[3];break;

case0x77:P0=table[4];break;

case0xbe:P0=table[5];break;

case0xbd:P0=table[6];break;

case0xbb:P0=table[7];break;

case0xb7:P0=table[8J;break;

case0xde:P0=table[9];break;

caseOxdd:PO=table[10];break;

caseOxdb:PO=table[11];break;

case0xd7:P0=table[l2];break;

case0xee:P0=table[13];break;

caseOxed:PO=table[14];break;

caseOxeb:P0=table[15];break;

case0xe7:PO=table[16];break;

說明:其高效體現(xiàn)在:1.代碼量少。注意:P3可以作為如變量temp一樣使用。另外鍵盤的

工作方式有三種1.程序控制掃描2.定時掃瞄3.中斷掃描。其中前兩中方式或多或少對CPU

造成一定的浪費(fèi)。而方式3則最高效。

(6)LCD驅(qū)動程序包

#include<reg52.h>

#include<intrins.h>

#defineucharunsignedchar

#defineuintunsignedint

sbitrs=P2A4;

sbitrw=P2A5;

sbite=P2A6;

#definedataportP0

constucharnodisp=0;〃無顯示;

constucharnocur=l;//有顯示但無光標(biāo);

constucharcurNoFlash=2;//有光標(biāo)但無閃爍;

constucharcurflash=3;〃有光標(biāo)且有閃爍;

voidlcdpos(uchar,uchar);〃確定光標(biāo)的位置;

voidlcdwd(uchar);〃寫字符;

voidlcdwc(uchar);〃送控制字且檢測忙信號;

voidlcdwcn(uchar);//送控制字但不檢測忙信號;

voidmdelay(uchar);//延遲子程序;

voidwaitidle。;//正常讀/寫操作之前的檢測LCD控制狀態(tài);

//延遲子程序;

voidmdelay(ucharj)

(

uinti=0;

for(;j>0;j-)

for(i=0;i<125;i++);

)

//實(shí)現(xiàn)寫字符功能將某個字符顯示與ypos行xpos列。

voidwritechar(ucharc,ucharxpos,ucharypos)

(

lcdpos(xpos,ypos);〃調(diào)用光標(biāo)設(shè)置子程序;

lcdwd(c);〃調(diào)用寫字符子程序;

)

//功能在制定的位置顯示字符串;

voidwritestring(uchar*s,ucharxpos,ucharypos)

(

uchari;

if(*s==,\O')

return;

for(i=0;;i++)

(

if(*(s+i)=='\O,)

break;

writechar(*(s+i),xpos,ypos);

xpos++;

if(xpos>=15)

break;

//設(shè)置光標(biāo)的功能;

voidsetcur(ucharpara)

mdelay(2);

switch(para)

case0:{lcdwc(0x08);break;}

case1:{lcdwc(0x0c);break;}

case2:{lcdwc(0x0e);break;}

case3:{lcdwc(0x0f);break;}

default:break;

)

)

〃實(shí)現(xiàn)清屏功能的子函數(shù)

voidclrlcd()

(

Icdwc(0x01);〃調(diào)用送控制字子程序;

)

〃正常讀寫之前的檢測led控制狀態(tài);

voidwaitidle()

(

uchartmp;

rs=O;

rw=l;

e=l;

_nop_();

for(;;)

(

tmp=dataport;

tmp&=0x80;

if(tmp==0)

break;

)

e=0;

)

〃實(shí)現(xiàn)寫字符功能;

voidIcdwd(ucharc)

(

waitidle();

rs=l;

rw=0;

dataport=c;

e=l;

_nop_();

_nop_();

e=0;

)

〃送控制字子程序(檢測忙信號);

voidledwc(ucharc)

waitidle();

lcdwcn(c);//調(diào)用送控制字子程序(不檢測忙信號);

)

〃送控制字子程序(不檢測忙信號);

voidlcdwcn(ucharc)

(

rs=O;

rw=0;

dataport=c;

e=l;

_nop_();

e=0;

)

〃設(shè)置第xpos,ypos光標(biāo)所在的地址;

voidIcdpos(ucharxpos,ucharypos)

(

uchartmp;

xpos&=0x0f;

ypos&=0x01;

if(ypos==0)

tmp=xpos;

else

tmp=xpos+0x40;

tmp|=0x80;

lcdwc(tmp);

)

//復(fù)位LCD控制器;

voidlcdreset()

(

mdelay(15);

lcdwc(0x38);

lcdwc(0x08);

lcdwc(OxOl);

lcdwc(0x06);

lcdwc(OxOc);

)

//----------------------以下是用led實(shí)現(xiàn)現(xiàn)實(shí)一個字符串的主函數(shù)

voidmain()

(

ucharxpos,ypos;

uchar*s="8Oc5I!";

xpos=8;

ypos=0;

lcdreset();

clrlcd();

setcur(curflash);

writestring(s,xpos,ypos);

for(;;)

{;}

---------------------以下實(shí)現(xiàn)讓字母人圍繞著LCD屏轉(zhuǎn)動

voidmain()

charxpos,ypos;

while(l)

p37=0;

ypos=0;

for(xpos=0;xpos<=15;xpos++)

(

lcdreset();

clrlcd();

setcur(nocur);

writechar('A;xpos,ypos);

mdelay(3000);

if(xpos==15)

(

lcdreset();

clrlcd();

setcur(nocur);

ypos=l;

//lcdwc(0xl8);

for(xpos=15;xpos>=0;xpos—)

lcdreset();

clrlcd();

setcur(nocur);

writechar('A',xpos,ypos);

mdelay(3000);

if(xpos==-l)

break;

ypos=0;

----------------實(shí)現(xiàn)上行動態(tài)顯示婁浩很性感,下行靜態(tài)顯示80C51----------------------------

添加以上的LCD顯示驅(qū)動包。。。。。。。。。

voidmain()

(

uchars[]="louhaoissexy!";

charxpos,ypos;

lcdreset();

clrlcd();

setcur(nocur);

writestring("80c511',6,1);

while(l)

(

p37=0;

ypos=0;

for(xpos=0;xpos<=15;xpos++)

(

writechar(s[xposj,xpos,ypos);

mdelay(5000);

if(xpos==15)

{lcdreset();

clrlcd();

setcur(nocur);

writestring(M80c5

break;

)

}

)

)

說明:LCD顯示比起9段數(shù)碼顯示更加高級且由于有了現(xiàn)成的驅(qū)動程序包因而用戶只需要

把握如何與驅(qū)動程序之間建立聯(lián)系(接口)便可以了!在其他的工程項(xiàng)目應(yīng)用場合要盡量使

用led來顯示,當(dāng)然是在成本允許的情況下!(用戶只需關(guān)注以下幾點(diǎn):1.寫字符函數(shù)

writechar(uchars,ucharxpos,ucharypos)2.寫字符串函數(shù)writestring(uchar*s,ucharxpos,uchar

ypos)3.setcur(ucharset)在使用時只需對函數(shù)中的各個參數(shù)作出合理的設(shè)置便可其他的程序

則套用周堅(jiān)老師的模式便可!)

(7)12c總線驅(qū)動程序包

啟動HC總線

---------------------------------*/

voidstart(void)

sda=l;

_nop_();_nop_();

scl=1;

_nop_();_nop_();_nop_();_nop_();_nop_();

sda=0;

_nop_();_nop_();__nop_();_nop_();_nop_();

scl=0;

)

停止nc總線

--------------------------------------------------*/

voidstop(void)

(

sda=0;

_nop_();

scl=l;

_nop_();_nop_();_nop_();_nop_();_nop_();

sda=1;

_nop_();_nop_();_nop_();_nop_();_nop_();

scl=0;

)

應(yīng)答IIC總線

--------------------*/

voidack(void)

sda=0;

_nop_();_nop_();_nop_();

scl=l;

_nop_();_nop_();_nop_();_nop_();_nop_();

scl=0;

_nop__();_nop_();

非應(yīng)答nc總線

-----------------------*/

voidnoack(void)

(

sda=l;

_nop_();_nop_();_nop_();

scl=1;

_nop_();_nop_();_nop_();_nop_();_nop_();

scl=0;

_nop_();_nop_();

發(fā)送一個字節(jié)

--------------------------------------------------*/

voidsend(unsignedcharc)

(

unsignedcharbitcounter=8;

unsignedchartemp;

temp=c;

scl=0;

_nop.();_nop_();_nop_();_nop_();_nop_();

if((temp&0x80)==0x80)

sda=l;

else

sda=0;

scl=l;

temp=c?l;

c=temp;

bitcounter—;

while(bitcounter);

scl=0;

讀入一個字節(jié)并返回

--------------------------*/

unsignedcharread(void)

unsignedchartemp=O;

unsignedchartemp1=0;

unsignedcharbitcounter=8;

sda=l;

do

(

scl=0;

_nopj);_nop_();_nop_();_nop_();_nop_();

scl=l;

_nop__();_nop_();_nop_();_nop_();_nop_();

if(sda)

temp=temp|0x01;

else

temp=temp&0xfe;

if(bitcounter-l)

(

templ=temp?l;

temp=temp1;

)

bitcounter—;

)

while(bitcounter);

return(temp);

寫入數(shù)據(jù)

-----------------------------------------*/

voidwr_to_rom(unsignedcharshuju[],unsignedcharaddress,unsignedcharnum)

(

unsignedchari;

unsignedchar*pshuju;

pshuju=shuju;

fbr(i=0;i<num;i4-+)

(

start();

send(addwr);〃寫入芯片地址

ack();

send(address+i);〃寫入存儲地址

ack();

send(*(pshuju+i));〃寫數(shù)據(jù)

ack();

stop();

mdelay(20);

讀出數(shù)據(jù)

--------------------------------------------------*/

voidrd_from_rom(unsignedcharshuju[],unsignedcharaddress,unsignedcharnum)

(

unsignedchari;

unsignedchar*pshuju;

pshuju=shuju;

fbr(i=O;i<num;i++)

(

start();〃寫入芯片地址

send(addwr);

ack();

send(address+i);〃寫入存儲地址

ack();

start();

send(addrd);〃讀入地址

ack();

*(pshuju+i)=read();〃讀數(shù)據(jù)

scl=0;

noack();

stop();

)

)

說明:以上程序?yàn)镮2C總線驅(qū)動程序(模擬)用時只需關(guān)注其中的兩個函數(shù)便可:

rd_from_rom(shuzu[],address,num)^nwr_to_rom(shuzu[],address,num).12c總線的應(yīng)用還需要繼

續(xù)進(jìn)行練習(xí)我僅僅只是一知半解而己!而且還有周堅(jiān)老師的一個實(shí)驗(yàn)沒有完成以后繼續(xù)

做?I?11??111

-------------------------以下為利用12c總線實(shí)現(xiàn)的對EEPROM的讀和寫-------------

voidmain()

(

ucharnum[]={0x7f,0x6f,0x77,0x06,0x5b};

uchari;

wp=0;〃關(guān)寫保護(hù)如若開則寫不進(jìn);

wr_to_rom(num,1,4);

for(i=0;i<5;i++)

num[iJ=0x3f;

P2=0x03;

rd_from_rom(num,1,5);

for(i=0;i<5;i++)

p37=l;

PO=num[i];

mdelay(lOOO);

p37=O;

)

)

注:參考浩豚公司的師訪程序!

(8)數(shù)碼管999數(shù)字計數(shù)程序(帶有消影功能)非定時器應(yīng)用

#include<reg52.h>

#defineuintunsignedint

#defineucharunsignedchar

voiddelay(uint);

sbitp37=P3A7;

ucharbai,shi,ge;

uintnum=0,a;

ucharwela[J={0x00,0x01,0x02};

ucharcodeshuma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

voidmain()

(

while(l)

(

for(num=0;num<1000;num++)

{

bai=num/100;

shi=num%100/10;

ge=num%10;

for(a=200;a>0;a--)//a的值可以實(shí)現(xiàn)數(shù)字顯示速度的快慢;

(

P2=wela[2];

p37=l;

P0=shuma[ge];

p37=0;

delay(lOO);

PO=Oxff;//消影

P2=wela[l];

p37=l;

PO=shuma[shiJ;

p37=0;

delay(lOO);

PO=Oxff;//消影

P2=wela[0];

p37=l;

PO=shumafbai];

p37=0;

delay(lOO);

PO=Oxff;//消影

voiddelay(uinti)〃用延時程序?qū)崿F(xiàn)數(shù)碼管的動態(tài)顯示;

(

while(i—);

)

注:消影功能即是讓數(shù)碼管的不該亮的部分熄滅;

(9)按鍵計數(shù)程序(待改進(jìn)不太穩(wěn)定而且只能計數(shù)太5次)〃有待改進(jìn)的程月:用綠色

#include<reg52.h>

#include<intrins.h>

#defineuintunsignedint

#defineucharunsignedchar

voiddelay(uint);

voidinit();

sbitp37=P3八7;

sbitp34=P3A4;

ucharbai.shi,ge;

uintnum,temp;

ucharwela|]={0x00,0x01,0x02};

ucharcodeshuma[]={0x3f\0x06,0x5b,0x4f,0x66t0x6d.0x7d,0x07,0x7f,0x6f|;

voidmain()

init();

whiled)

temp+=TH0;

temp=_crol_(temp.8):

temp+=TL0;

num=temp;

ge=num%10:

shi=num%100/10;

bai=num/i00;

P2=wela[0];

p37=l;

P()=shuma[baiJ;

p37=0;

PO=Oxff;

delay(250);

P2=wela[l]:

p37=l;

PO=shuma[shi];

p37=O;

PO=Oxff;

delay(250);

P2=wela[2];

p37=l;

PO=shuma[ge];

p37=O;

PO=Oxff;

delay(250);

)

)

voiddelay(uinti)

|

while。一);

)

voidinit()

{

TMOD=0X05;//jishuqi0工作方式1:(16位定時計數(shù)器)

//EA=1;

//ET()=I;

THO=255;

TL0=255;

TF0=0;

TRO=1;

num=O;

I

說明:此程序利用到了定時器TO的計數(shù)功能,注意在計數(shù)功能中一定不能開定時器中斷,

定時器中斷僅適用于定時器。存在的問題:此處三位數(shù)碼管只能實(shí)現(xiàn)0—255的按鍵記數(shù),

而且計數(shù)值有時不太穩(wěn)定,即有時下一次P3.4口的按鍵可能會出現(xiàn)兩個甚至兩個以上的數(shù)

字累加,造成計數(shù)不準(zhǔn)確,原因是按鍵沒有加入去抖程序和松手檢測但是數(shù)碼管的動態(tài)顯示

就不能加入這兩個因?yàn)榧雍蟊爻霈F(xiàn)停頓而停頓即意味著有兩個數(shù)碼管不能被點(diǎn)亮。下面的程

序是采用數(shù)碼管的靜態(tài)顯示,同時使用T0的計數(shù)功能,此時可以在程序中加入松手檢測和

去抖過程。具體實(shí)現(xiàn)如下:

#include<reg52.h>

#include<intrins.h>

#defineuintunsignedint

#defineucharunsignedchar

voiddelay(uint);

voidinit();

sbitp37=P3A7;

sbitp34=P3A4;

//ucharbai,shi,ge;

uintnum;

ucharcodeshuma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

voidmain()

(

init();

while(l)

(

if(p34==0)

(

if(TL0==10)

TL0=0;

num=TL0;

delay(lOOO);

if(p34==0)

(

while(!p34);

num=TL0;

p37=l;

P0=shumafnum];

p37=0;

I

)

voiddelay(uinti)

(

while(i—);

)

voidinit()

(

TMOD=0X05;//jishuqi0工作方式1;(16位定時計數(shù)器)

//EA=1;

//ET0=l;

TH0=255;

TL0=255;

TF0=0;

TR0=l;

num=0;

P2=0x00;

說明:這個程序的效果還可以就是有一條計數(shù)值只能是從0—9因而限制了其應(yīng)用!

當(dāng)然了這個程序還可以利用外部中斷來完成。每按一次發(fā)生一次中斷則計數(shù)一次。

以下程序可以實(shí)現(xiàn)六位按鍵計數(shù)功能:利用定時器。工作于計數(shù)方式1,利用定時器1工作

于定時方式1并能產(chǎn)生1.2—1.3MS的定時中斷,以對六位選通的數(shù)碼管進(jìn)行輪翻掃描實(shí)現(xiàn)

動態(tài)顯示。程序中的參數(shù)是經(jīng)我一再調(diào)試最終產(chǎn)生的無閃爍參數(shù):具體程序如下

#include<reg52.h>

#include<intrins.h>

#defineuintunsignedint

#defineucharunsignedchar

voiddelay(uint);

voidinit();

sbitp37=P3A7;

sbitp34=P3八4;

uintnum;

ucharwei,du,bit_wei[6];

ucharwela[]={0x00,0x01,0x02,0x03,0x04,0x05};

ucharcodeshuma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

voidmain()

(

init();

while(l)

(

num=TH0*256+TL0;

bit_wei[5]=0;

bit_wei[4]=num/10000;

bit_wei[3]=num/1000%10;

bit_wei[2]=num/100%10;

bit_wei[l]=num/10%10;

bit_wei[0]=num%10;

p37=l;

P2=wela[wei];

P0=shuma[bit_wei[du]];

p37=0;

delay⑸;

if(wei==5)

wei=0;

if(du==0)

du=5;

voidinit()

TMOD=OX15;〃定時器1工作于定時方式1,定時器0工作于記數(shù)方式1;

EA=1;

ET1=1;

THO=O;

TLO=O;

TH1=(65536-1200)/256;

TL1=(65536-1200)%256;〃定時3毫秒;

TF0=0;

TR0=l;

TR1=1;

num=0;

wei=0;

du=5;

)

voidtimerl()interrupt3

(

TH1=(65536-1200)/256;

TLl=(65536-1200)%256;

wei++;

du-;

voiddelay(uinti)

(

while(i—);

}

說明:其中NUM的值通過按鍵次數(shù)來由定時器0獲得。

(10)普通時鐘程序(存在問題:調(diào)節(jié)一個鍵的時候其他數(shù)碼管跟著變化!)

#include<reg52.h>

#defineucharunsignedchar

#defineuintunsignedint

sbitp37=P3A7;

sbitpl6=PlA6;

sbitp32=P3八2:

sbitp33=P3A3;

bitdingshi;//是否啟動定時功能標(biāo)識位;在中斷服務(wù)程序中設(shè)置:

ucharcode

huayang[]={0x7f.0xbf.0xdf.0xef,0xf7.0xfb,0xfd.0xfe,0xff.0xff,0x00.0,0x55,0x55.0xaa,0xaa);

ucharcodeshuma[]={0x3f.0x06,0x5b.0x4f,0x66,0x6cL0x7d.0x07,0x7f,0x6f}:

ucharcodewela[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07);

ucharhour,min,sec;//時,分,秒的計數(shù)器及用于設(shè)置定時時間的中間計數(shù)器

ucharflag;〃數(shù)碼管位選標(biāo)志

uchara;〃實(shí)現(xiàn)1秒定時功能控制寄存器;

ucharj;〃花樣流水燈控制;

voidinit()

TMOD=OX11;〃定時器1工作方式1定時功能;定時器0工作方式1定時功能;

TH0=(65536-50000)/256;〃設(shè)置各個定時計數(shù)器的處置

TL0=(65536-50000)%256;

TH1=(65536-2000)/256;

TLl=(65536-2000)%256;

〃m=o;//電平觸發(fā)

EA=I;〃開總中斷

ET0=l;〃開定時計數(shù)器0中斷

ET1=1;//開定時計數(shù)器1中斷

TR0=l;//啟動定時器0

TR1=1;//啟動定時器1

hour=00;

min=00;

sec=00;

flag=O;

a=0;

i=0;

)

voidmsdelay(uinti)

(

while(i—);

)

voiddisplayO

(

p37=1;P2=wela[0];P0=shuma[hour/l0];p37=0;

p37=l;P2=wela[1];P0=shuma[hour%10];p37=0;

p37=1;P2=wela[2];P0=0x40;p37=0;

p37=1;P2=wela[3];P0=shuma[min/l0];p37=0;

p37=1;P2=wela[4];P0=shuma[min%10];p37=0;

p37=l;P2=wela[5];P0=0x40;p37=0;

p37=1;P2=wela[6];P0=shuma[sec/l0];p37=0;

p37=l;P2=wela[7];P0=shuma[sec%10];p37=0;

)

ucharkeyscan。//行列交叉掃描法檢測鍵盤;

(

uchartemp,tmp;

P3=OxfO;

temp=P3;

temp=temp&0xf0;

if(temp!=OxfO)

msdelay(10000);

temp=P3;

temp=temp&OxfO;

if(temp!=OxfO)

(

temp=P3;

temp=temp&OxfO;

)

)

P3=OxOf;

tmp=P3;

tmp=tmp&OxOf;

if(tmp!=OxOf)

(

msdelay(1OOOO);

tmp=P3;

tmp=tmp&OxOf;

if(tmp!=OxOf)

(

tmp=P3;

tmp=tmp&OxOf;

)

)

temp=temp+tmp;

returntemp;

)

〃定時計數(shù)器1中斷服務(wù)子程序;

voidtimerl()interrupt3

(

TH1=(65536-2000)/256;

TLl=(65536-2000)%256;

switch(flag)//實(shí)現(xiàn)對數(shù)碼管的位選及顯示;

{

case0:p37=1;P2=wela[0];PO=shuma[hour/10];p37=0;msdelay(lOO);break;

casel:p37=l;P2=wela[l];PO=shuma[hour%10];p37=0;msdelay(lOO);break;

case2:p37=1;P2=wela[2];P0=0x40;p37=0;msdelay(1OO);break;

case3:p37=l;P2=wela[3];P0=shuma[min/10];p37=0;msdelay(100);break;

case4:p37=1;P2=wela[4];P0=shuma[min%10];p37=0;msdelay(lOO);break;

case5:p37=l;P2=wela[5];P0=0x40;p37=0;msdelay(100);break;

case6:p37=1;P2=wela[6];PO=shuma[sec/l0];p37=0;msdelay(l00);break;

case7:p37=1;P2=wela[7];PO=shuma[sec%10];p37=0;msdelay(lOO);break;

defaulcbreak;

}

flag++;

if(flag==8)

flag=O;

//定時器。中斷服務(wù)子程序:包括了時間更新,花樣流水燈顯示,定時器開啟控制,揚(yáng)聲器

開啟控制;

voidtimer()()interrupt1

(

TH0=(65536-50000)/256;〃設(shè)置各個定時計數(shù)器的處置

TL0=(65536-50000)%256;

a++;

if(a==20)

(

a=0;

sec++;

if(sec==60)

(

sec=0;

min++;

if(min==60)

(

min=0;

hour++;

if(hour==24)

hour=0;

i++;

if(i==16)

i=0;

Pl=huayang[i];

)

voidmain()

(

ucharnum;

uchartemp;

init();

while(l)

{

num=keyscan();

switch(num)//鍵值確定及其對應(yīng)鍵功能服務(wù)程序;

{

case0x7e:hour++;if(hour==24)hour=0;display();break;

case0x7d:{hour—;if(hour==255)hour=23;break;}

case0x7b:{min++;if(min==60)min=0;display();break;)

case0x77:{min—;if(min==255)min=59;display();break:}

caseOxbe:{sec++;if(sec==60)sec=0;display();break;}

caseOxbd:{sec—:if(sec==255)sec=59:display():break:}

caseOxbb:;

caseOxb7:;

caseOxde:;

caseOxdd:;

//caseOxdb:p32=O;break;

//caseOxd7:p33=O;break;

default:break;

)

對以上程序的改進(jìn):實(shí)現(xiàn)的功能:1.時鐘顯示。2.定時動作。其中定時到可以無限地做定時

到得動作而不是原來的一分鐘!而且定時動作的取消可以通過手動按鍵來實(shí)現(xiàn)!

#include<reg52.h>

#defineucharunsignedchar

#defineuintunsignedint

sbitp37=P3A7;

sbitpl6=PlA6;

sbitp30=P3八0;

sbitp31=P3Al;

sbitp32=P3A2;

sbitp33=P3A3;

//bitdingshi;〃是否啟動定時功能標(biāo)識位;在中斷服務(wù)程序中設(shè)置;

ucharcode

huayang[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0xff,0xff,0x00,0,0x55,0x55,0xaa,0xaa,0xaa,

Oxaa,0x55,0x55,0,0x00,Oxff,Oxff,Oxfe,Oxfd,Oxfb,Oxf7,Oxef,Oxdf,Oxbf,Ox7f};

ucharcodeshuma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

ucharcodewela[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07);

ucharhour,min,sec,sethour,setmin;〃時,分,秒的計數(shù)器及用于設(shè)置定時時間的中間計數(shù)器

ucharHag;//數(shù)碼管位選標(biāo)志

uchara,b,c,d,e;〃實(shí)現(xiàn)I秒定時功能控制寄存器;

uchari;//花樣流水燈控制;

voidinit()

(

TMOD=OXU;〃定時器1工作方式1定時功能;定時器0工作方式1定時功能;

TH0=(65536-50000)/256;〃設(shè)置各個定時計數(shù)器的處置

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論