<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

單片機編程實例大全

工控論壇 ? 來源:工控論壇 ? 2023-09-06 11:09 ? 次閱讀

*實例1:

使用P3口流水點亮8位LED

#include //包含單片機寄存器的頭文件 / 函數功能:延時一段時間

void delay(void)

{

unsigned char i,j;

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

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

;

}

/ 函數功能:主函數

void main(void)

{

while(1)

{

P3=0xfe; //第一個燈亮

delay(); //調用延時函數

P3=0xfd; //第二個燈亮

delay(); //調用延時函數

P3=0xfb; //第三個燈亮

delay(); //調用延時函數

P3=0xf7; //第四個燈亮

delay(); //調用延時函數

P3=0xef; //第五個燈亮

delay(); //調用延時函數

P3=0xdf; //第六個燈亮

delay(); //調用延時函數

P3=0xbf; //第七個燈亮

delay(); //調用延時函數

P3=0x7f; //第八個燈亮

delay(); //調用延時函數

} / /

}

*實例2:

通過對P3口地址的操作流水點亮8位LED

#include //包含單片機寄存器的頭文件

sfr x=0xb0; //P3口在存儲器中的地址是b0H, 通過sfr可定義8051內核單片機

//的所有內部8位特殊功能寄存器,對地址x的操作也就是對P1口的操作

/

函數功能:延時一段時間

/

void delay(void)

{

unsigned char i,j;

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

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

; //利用循環等待若干機器周期,從而延時一段時間

}

/

函數功能:主函數

/

void main(void)

{

while(1)

{

x=0xfe; //第一個燈亮

delay(); //調用延時函數

x=0xfd; //第二個燈亮

delay(); //調用延時函數

x=0xfb; //第三個燈亮

delay(); //調用延時函數

x=0xf7; //第四個燈亮

delay(); //調用延時函數

x=0xef; //第五個燈亮

delay(); //調用延時函數

x=0xdf; //第六個燈亮

delay(); //調用延時函數

x=0xbf; //第七個燈亮

delay(); //調用延時函數

x=0x7f; //第八個燈亮

delay(); //調用延時函數

}

}

*實例3:用不同數據類型控制燈閃爍時間

#include //包含單片機寄存器的頭文件

/

函數功能:用整形數據延時一段時間

/

void int_delay(void) //延時一段較長的時間

{

unsigned int m; //定義無符號整形變量,雙字節數據,值域為0~65535 for(m=0;m<36000;m++)

; //空操作

}

/

函數功能:用字符型數據延時一段時間

/

void char_delay(void) //延時一段較短的時間

{

unsigned char i,j; //定義無符號字符型變量,單字節數據,值域0~255 for(i=0;i<200;i++)

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

; //空操作

}

/

函數功能:主函數

/

void main(void)

{

unsigned char i;

while(1)

{

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

{

P1=0xfe; //P1.0口的燈點亮

int_delay(); //延時一段較長的時間

P1=0xff; //熄滅

int_delay(); //延時一段較長的時間

}

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

{

P1=0xef; //P1.4口的燈點亮

char_delay(); //延時一段較長的時間

} P1=0xff; //熄滅 char_delay(); //延時一段較長的時間 } }

*實例4:用單片機控制第一個燈亮

#include //包含51單片機寄存器定義的頭文件

void main(void)

{

P1=0xfe; //P1=1111 1110B,即P1.0輸出低電平

}

*實例5:用單片機控制一個燈閃爍:認識單片機的工作頻率 #include //包含單片機寄存器的頭文件

/

函數功能:延時一段時間

/

void delay(void) //兩個void意思分別為無需返回值,沒有參數傳遞 {

unsigned int i; //定義無符號整數,最大取值范圍65535 for(i=0;i<20000;i++) //做20000次空循環

; //什么也不做,等待一個機器周期

}

/ 函數功能:主函數 (C語言規定必須有也只能有1個主函數) / void main(void)

{

while(1) //無限循環

{

P1=0xfe; //P1=1111 1110B, P1.0輸出低電平

delay(); //延時一段時間

P1=0xff; //P1=1111 1111B, P1.0輸出高電平

delay(); //延時一段時間

}

}

*實例6:將 P1口狀態分別送入P0、P2、P3口:認識I/O口

的引腳功能

#include //包含單片機寄存器的頭文件

/ 函數功能:主函數 (C語言規定必須有也只能有1個主函數) /

void main(void)

{

while(1) //無限循環

{

P1=0xff; // P1=1111 1111B,熄滅LED

P0=P1; // 將 P1口狀態送入P0口

P2=P1; // 將 P1口狀態送入P2口

P3=P1; // 將 P1口狀態送入P3口

}

}

*實例7:用P0口、P1 口分別顯示加法和減法運算結果 #include

void main(void)

{

unsigned char m,n;

m=43; //即十進制數2x16+11=43

n=60; //即十進制數3x16+12=60

P1=m+n; //P1=103=0110 0111B,結果P1.3、P1.4、P1.7 口的燈被點亮 P0=n-m; //P0=17=0001 0001B,結果P0.0、P0.4的燈被熄滅 }

*實例8:用P0、P1口顯示乘法運算結果

#include //包含單片機寄存器的頭文件

void main(void)

{

unsigned char m,n;

unsigned int s;

m=64;

n=71;

s=m n; //s=64 71=4544,需要16位二進制數表示,高8位送P1口,低8位送P0口

//由于4544=17 256+192=H3 16 16 16+H2 16 16+H1 16+H0

//兩邊同除以256,可得17+192/256=H3 16+H2+(H1 16+H0)/256

//因此,高8位16進制數H3 16+H2必然等于17,即4544除以256的商

//低8位16進制數H1 16+H0必然等于192,即4544除以256的余數

P1=s/256; //高8位送P1口 ,P1=17=11H=0001 0001B, P1.0和P1.4口滅,其余亮

P0=s%256; //低8位送P0口 , P3=192=c0H=1100 0000B,P3.1,P3.6,P3.7口滅,其余亮

}

*實例9:用P1、P0口顯示除法運算結果

#include //包含單片機寄存器的頭文件

void main(void)

{

P1=36/5; //求整數

P0=((36%5) 10)/5; //求小數

while(1)

; //無限循環防止程序“跑飛”

}

*實例10:用自增運算控制P0口8位LED流水花樣

#include //包含單片機寄存器的頭文件

/

函數功能:延時一段時間

/

void delay(void)

{

unsigned int i;

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

;

}

/ 函數功能?:主函數

/ void main(void)

{

unsigned char i;

for(i=0;i<255;i++) //注意i的值不能超過255

{

P0=i; //將i的值送P0口

delay(); //調用延時函數

}

}

*實例11:用P0口顯示邏輯"與"運算結果 #include //包含單片機寄存器的頭文件 void main(void)

{

P0=(4>0)&&(9>0xab);//將邏輯運算結果送P0口

while(1)

; //設置無限循環,防止程序“跑飛”

}

*實例12:用P0口顯示條件運算結果

#include //包含單片機寄存器的頭文件 void main(void)

{

P0=(8>4)?8:4;//將條件運算結果送P0口,P0=8=0000 1000B while(1)

; //設置無限循環,防止程序“跑飛”

}

*實例13:用P0口顯示按位"異或"運算結果 #include //包含單片機寄存器的頭文件 void main(void)

{

P0=0xa2^0x3c;//將條件運算結果送P0口,P0=8=0000 1000B while(1)

; //設置無限循環,防止程序“跑飛”

}

*實例16:用P0顯示左移運算結果

#include //包含單片機寄存器的頭文件 void main(void)

{

P0=0x3b<<2;//將左移運算結果送P0口,P0=1110 1100B=0xec while(1)

; //無限循環,防止程序“跑飛”

}

*實例17:"萬能邏輯電路"實驗

#include //包含單片機寄存器的頭文件

sbit F=P1^4; //將F位定義為 P1.4

sbit X=P1^5; //將X位定義為 P1.5

sbit Y=P1^6; //將Y位定義為 P1.6

sbit Z=P1^7; //將Z位定義為 P1.7

void main(void)

{

while(1)

{

F=((~X)&Y)|Z; //將邏輯運算結果賦給F

;

}

}

*實例18:用右移運算流水點亮P1口8位LED #include //包含單片機寄存器的頭文件

/

函數功能:延時一段時間

/

void delay(void)

{

unsigned int n;

for(n=0;n<30000;n++)

;

}

/

函數功能:主函數

/

void main(void)

{

unsigned char i;

while(1)

{

P1=0xff;

delay();

for(i=0;i<8;i++)//設置循環次數為8

{

P1=P1>>1; //每次循環P1的各二進位右移1位,高位補0 delay(); //調用延時函數

}

}

}

*實例19:用if語句控制P0口8位LED的流水方向 #include //包含單片機寄存器的頭文件

sbit S1=P1^4; //將S1位定義為P1.4

sbit S2=P1^5; //將S2位定義為P1.5

/

函數功能:主函數

/

void main(void)

{

while(1)

}

{ if(S1==0) //如果按鍵S1按下 P0=0x0f; //P0口高四位LED點亮 if(S2==0) //如果按鍵S2按下 P0=0xf0; //P0口低四位LED點亮 }

*實例20:用swtich語句的控制P0口8位LED的點亮狀態 #include //包含單片機寄存器的頭文件

sbit S1=P1^4; //將S1位定義為P1.4

/

函數功能:延時一段時間

/

void delay(void)

{

unsigned int n;

for(n=0;n<10000;n++)

;

}

/

函數功能:主函數

/

void main(void)

{

unsigned char i;

i=0; //將i初始化為0

while(1)

{

if(S1==0) //如果S1鍵按下

{

delay(); //延時一段時間

if(S1==0) //如果再次檢測到S1鍵按下

i++; //i自增1

if(i==9) //如果i=9,重新將其置為1

i=1;

}

switch(i) //使用多分支選擇語句

{

}

} case 1: P0=0xfe; //第一個LED亮 break; case 2: P0=0xfd; //第二個LED亮 break; case 3:P0=0xfb; //第三個LED亮 break; case 4:P0=0xf7; //第四個LED亮 break; case 5:P0=0xef; //第五個LED亮 break; case 6:P0=0xdf; //第六個LED亮 break; case 7:P0=0xbf; //第七個LED亮 break; case 8:P0=0x7f; //第八個LED亮 break; default: //缺省值,關閉所有LED P0=0xff; }

*實例21:用for語句控制蜂鳴器鳴笛次數

#include //包含單片機寄存器的頭文件 sbit sound=P3^7; //將sound位定義為P3.7 / 函數功能:延時形成1600Hz音頻

/ void delay1600(void)

{

unsigned char n;

for(n=0;n<100;n++)

;

}

/ 函數功能:延時形成800Hz音頻

/ void delay800(void)

{

unsigned char n;

for(n=0;n<200;n++)

;

}

/ 函數功能:主函數

/ void main(void)

{

unsigned int i;

while(1)

{

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

{

sound=0; //P3.7輸出低電平 delay1600();

sound=1; //P3.7輸出高電平 delay1600();

}

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

{

sound=0; //P3.7輸出低電平 delay800();

sound=1; //P3.7輸出高電平 delay800();

}

}

}

*實例22:用while語句控制LED

#include //包含單片機寄存器的頭文件 / 函數功能:延時約60ms (3 100 200=60000μs) / void delay60ms(void)

{

unsigned char m,n;

for(m=0;m<100;m++)

for(n=0;n<200;n++)

;

}

/

函數功能:主函數

/

void main(void)

{

unsigned char i;

while(1) //無限循環

{

i=0; //將i初始化為0

while(i<0xff) //當i小于0xff(255)時執行循環體 {

P0=i; //將i送P0口顯示

delay60ms(); //延時

i++; //i自增1

}

}

}

*實例23:用do-while語句控制P0口8位LED流水點亮 #include //包含單片機寄存器的頭文件

/

函數功能:延時約60ms (3 100 200=60000μs)

/

void delay60ms(void)

{

unsigned char m,n;

for(m=0;m<100;m++)

for(n=0;n<200;n++)

;

}

/

函數功能:主函數

/

void main(void)

{

do

{

P0=0xfe; //第一個LED亮

delay60ms();

}

P0=0xfd; //第二個LED亮 delay60ms(); P0=0xfb; //第三個LED亮 delay60ms(); P0=0xf7; //第四個LED亮 delay60ms(); P0=0xef; //第五個LED亮 delay60ms(); P0=0xdf; //第六個LED亮 delay60ms(); delay60ms(); P0=0xbf; //第七個LED亮 delay60ms(); P0=0x7f; //第八個LED亮 delay60ms(); }while(1); //無限循環,使8位LED循環流水點亮

*實例24:用字符型數組控制P0口8位LED流水點亮 #include //包含單片機寄存器的頭文件

/

函數功能:延時約60ms (3 100 200=60000μs)

/

void delay60ms(void)

{

unsigned char m,n;

for(m=0;m<100;m++)

for(n=0;n<200;n++)

;

}

/

函數功能:主函數

/

void main(void)

{

unsigned char i;

unsigned char code Tab[ ]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //定義無符號字符型數組

while(1)

{

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

{

P0=Tab[i];//依次引用數組元素,并將其送P0口顯示

delay60ms();//調用延時函數

}

}

}

*實例25:用P0口顯示字符串常量

#include //包含單片機寄存器的頭文件

/

函數功能:延時約150ms (3 200 250=150 000μs=150ms

/

void delay150ms(void)

{

unsigned char m,n;

for(m=0;m<200;m++)

for(n=0;n<250;n++)

;

}

/

函數功能:主函數

/

void main(void)

{

unsigned char str[]={"Now,Temperature is :"}; //將字符串賦給字符型全部元素賦值

unsigned char i;

while(1)

{

i=0; //將i初始化為0,從第一個元素開始顯示

while(str[i]!='?') //只要沒有顯示到結束標志'?'

{

P0=str[i]; //將第i個字符送到P0口顯示

delay150ms(); //調用150ms延時函數

i++; //指向下一個待顯字符

}

}

}

*實例26:用P0 口顯示指針運算結果

#include

void main(void)

{

unsigned char p1, p2; //定義無符號字符型指針變量p1,p2 unsigned char i,j; //定義無符號字符型數據

i=25; //給i賦初值25

j=15;

p1=&i; //使指針變量指向i ,對指針初始化

p2=&j; //使指針變量指向j ,對指針初始化

P0= p1+ p2; // p1+ p2相當于i+j,所以P0=25+15=40=0x28

//則P0=0010 1000B,結果P0.3、P0.5引腳LED熄滅,其余點亮 while(1)

; //無限循環,防止程序“跑飛”

}

*實例27:用指針數組控制P0口8位LED流水點亮 #include

/

函數功能:延時約150ms (3 200 250=150 000μs=150ms

/

void delay150ms(void)

{

unsigned char m,n;

for(m=0;m<200;m++)

for(n=0;n<250;n++)

;

}

/

函數功能:主函數

/

void main(void)

{

unsigned char code Tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

unsigned char p[ ]={&Tab[0],&Tab[1],&Tab[2],&Tab[3],&Tab[4],&Tab[5], &Tab[6],&Tab[7]};

unsigned char i; //定義無符號字符型數據

while(1)

{

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

{

P0= p[i];

delay150ms();

}

}

}

*實例28:用數組的指針控制P0 口8 位LED流水點亮 #include

/

函數功能:延時約150ms (3 200 250=150 000μs=150ms

/

void delay150ms(void)

{

unsigned char m,n;

for(m=0;m<200;m++)

for(n=0;n<250;n++)

;

}

/

函數功能:主函數

/

void main(void)

{

unsigned char i;

unsigned char Tab[ ]={0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF, 0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE, 0xFE,0xFC,0xFB,0xF0,0xE0,0xC0,0x80,0x00, 0xE7,0xDB,0xBD,0x7E,0x3C,0x18,0x00,0x81, 0xC3,0xE7,0x7E,0xBD,0xDB,0xE7,0xBD,0xDB}; //流水燈控制碼

unsigned char p; //定義無符號字符型指針

p=Tab; //將數組首地址存入指針p

while(1)

{

for(i=0;i<32;i++) //共32個流水燈控制碼

{

P0= (p+i); // (p+i)的值等于a[i]

}

delay150ms(); //調用150ms延時函數 } }

*實例29:用P0 、P1口顯示整型函數返回值 #include

/ 函數功能:計算兩個無符號整數的和

/ unsigned int sum(int a,int b)

{

unsigned int s;

s=a+b;

return (s);

}

/ 函數功能:主函數

/ void main(void)

{

unsigned z;

z=sum(2008,2009);

P1=z/256; //取得z的高8位

P0=z%256; //取得z的低8位

while(1)

;

}

*實例30:用有參函數控制P0口8位LED流水速度 #include

/ 函數功能:延時一段時間

/ void delay(unsigned char x)

{

unsigned char m,n;

for(m=0;m

for(n=0;n<200;n++)

;

}

/

函數功能:主函數

/

void main(void)

{

unsigned char i;

unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; //流水燈控制碼

while(1)

{

//快速流水點亮LED

for(i=0;i<8;i++) //共8個流水燈控制碼

{

P0=Tab[i];

delay(100); //延時約60ms, (3 100 200=60 000μs) }

//慢速流水點亮LED

for(i=0;i<8;i++) //共8個流水燈控制碼

{

P0=Tab[i];

delay(250); //延時約150ms, (3 250 200=150 000μs) }

}

}

*實例31:用數組作函數參數控制流水花樣

#include

/

函數功能:延時約150ms

/

void delay(void)

{

unsigned char m,n;

for(m=0;m<200;m++)

for(n=0;n<250;n++)

;

}

/

函數功能:流水點亮P0口8位LED

/

void led_flow(unsigned char a[8])

{

unsigned char i;

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

{

P0=a[i];

delay();

}

}

/

函數功能:主函數

/

void main(void)

{

unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; //流水燈控制碼

led_flow(Tab);

}

*實例32:用指針作函數參數控制P0口8位LED流水點亮 #include

/

函數功能:延時約150ms

/

void delay(void)

{

unsigned char m,n;

for(m=0;m<200;m++)

for(n=0;n<250;n++)

;

}

/

函數功能:流水點亮P0口8位LED

/

void led_flow(unsigned char p) //形參為無符號字符型指針

{

unsigned char i;

while(1)

{

i=0; //將i置為0,指向數組第一個元素

while( (p+i)!='?') //只要沒有指向數組的結束標志

{

P0= (p+i);// 取的指針所指變量(數組元素)的值,送P0口 delay(); //調用延時函數

i++; //指向下一個數組元素

}

}

}

/

函數功能:主函數

/

void main(void)

{

unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F, 0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE,

0xFF,0xFE,0xFC,0xFB,0xF0,0xE0,0xC0,0x80,

0x00,0xE7,0xDB,0xBD,0x7E,0xFF,0xFF,0x3C,

0x18,0x0,0x81,0xC3,0xE7,0xFF, 0xFF,0x7E};

//流水燈控制碼

unsigned char pointer;

pointer=Tab;

led_flow(pointer);

}

*實例33:用函數型指針控制P1口燈花樣

#include //包含51單片機寄存器定義的頭文件

unsigned char code Tab[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; //流水燈控制碼,該數組被定義為全局變量

/

函數功能:延時約150ms

/ void delay(void)

{

unsigned char m,n;

for(m=0;m<200;m++)

for(n=0;n<250;n++)

;

}

/ 函數功能:流水燈左移

/ void led_flow(void)

{

unsigned char i;

for(i=0;i<8;i++) //8位控制碼

{

P0=Tab[i];

delay();

}

}

/ 函數功能:主函數

/ void main(void)

{

void ( p)(void); //定義函數型指針,所指函數無參數,無返回值 p=led_flow; //將函數的入口地址賦給函數型指針p

while(1)

( p)(); //通過函數的指針p調用函數led_flow()

}

*實例34:用指針數組作為函數的參數顯示多個字符串 #include //包含51單片機寄存器定義的頭文件

unsigned char code str1[ ]="Temperature is tested by DS18B20";//C語言中,字符串是作為字符數組來處理的

unsigned char code str2[ ]="Now temperature is:"; //所以,字符串的名字就是字符串的首地址

unsigned char code str3[ ]="The Systerm is designed by Zhang San";

unsigned char code str4[ ]="The date is 2008-9-30";

unsigned char p[ ]={str1,str2,str3,str4}; //定義p[4]為指向4個字符串的字符型指針數組

/ 函數功能:延時約150ms

/ void delay(void)

{

unsigned char m,n;

for(m=0;m<200;m++)

for(n=0;n<250;n++)

;

}

/ 函數功能:流水點亮P0口8位LED

/ void led_display(unsigned char x[ ]) //形參必須為指針數組

{

unsigned char i,j;

for(i=0;i<4;i++) //有4個字符串要顯示

{

j=0; //指向待顯字符串的第0號元素

while( (x[i]+j)!='?') //只要第i個字符串的第j號元素不是結束標志 {

P0= (x[i]+j); //取得該元素值送到P0口顯示

delay(); //調用延時函數

j++; //指向下一個元素

}

}

}

/ 函數功能:主函數

/ void main(void)

{

unsigned char i;

while(1)

{

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

led_display(p); //將指針數組名作實際參數傳遞

}

}

*實例35:字符函數ctype.h應用舉例

#include //包含51單片機寄存器定義的頭文件 #include

void main(void)

{

while(1)

{

P3=isalpha('_')?0xf0:0x0f;//條件運算,若'_'是英文字母,P3=0xf0 }

}

*實例36:內部函數intrins.h應用舉例

#include //包含51單片機寄存器定義的頭文件 #include //包含函數isalpha()聲明的頭文件 / 函數功能:延時約150ms

/ void delay(void)

{

unsigned char m,n;

for(m=0;m<200;m++)

for(n=0;n<250;n++)

;

}

/ 函數功能:主函數

/ void main(void)

{

P3=0xfe; //P3=1111 1110B

while(1)

{

P3=_crol_(P3,1);// 將P3的二進制位循環左移1位后再賦給P3 delay(); //調用延時函數

}

}

*實例37:標準函數stdlib.h應用舉例

#include //包含51單片機寄存器定義的頭文件 #include //包含函數isalpha()聲明的頭文件 / 函數功能:延時約150ms

/ void delay(void)

{

unsigned char m,n;

for(m=0;m<200;m++)

for(n=0;n<250;n++)

;

}

/ 函數功能:主函數

/ void main(void)

{

unsigned char i;

while(1)

{

for(i=0;i<10;i++) //產生10個隨機數

{

P3=rand()/160; //將產生的隨機數縮小160倍后送P3顯示 delay();

}

}

}

*實例38:字符串函數string.h應用舉例

#include //包含51單片機寄存器定義的頭文件 #include //包含函數isalpha()聲明的頭文件 void main(void)

{

unsigned char str1[ ]="Now, The temperature is :";

unsigned char str2[ ]="Now, The temperature is 36 Centgrade:"; unsigned char i;

i=strcmp(str1,str2); //比較兩個字符串,并將結果存入i

if(i==0) //str1=str2

P3=0x00;

else

if(i<0) //str1

P3=0xf0;

else //str1>str2

P3=0x0f;

while(1)

; //防止程序“跑飛”

}

*實例39:宏定義應用舉例2

#include //包含51單片機寄存器定義的頭文件

# define F(a,b) (a)+(a) (b)/256+(b) //帶參數的宏定義,a和b為形參 void main(void)

{

unsigned char i,j,k;

i=40;

j=30;

k=20;

P3=F(i,j+k); //i和j+k分別為實參,宏展開時,實參將替代宏定義中的形參

while(1)

;

}

*實例40:宏定義應用舉例2

#include

#include

void main(void)

{

P3_0=0; //將P3.0引腳置低電平,LED點亮

P3_1=0; //將P3.0引腳置低電平,LED點亮

P3_2=0; //將P3.0引腳置低電平,LED點亮

P3_3=0; //將P3.0引腳置低電平,LED點亮

P3_4=1; //將P3.4引腳置高電平,LED熄滅

}

P3_5=1; //將P3.5引腳置高電平,LED熄滅 P3_6=1; //將P3.7引腳置高電平,LED熄滅 P3_7=1; //將P3.7引腳置高電平,LED熄滅 while(1) ;

*實例41:宏定義應用舉例3

#include //包含51單片機寄存器定義的頭文件

#define MAX 100 //將MAX宏定義為字符串100

void main(void)

{

#if MAX>80 //如果字符串100大于80

P3=0xf0; //P3口低四位LED點亮

#else

P3=0x0f; //否則,P3口高四位LED點亮

#endif //結束本次編譯

}

/ 中斷、定時器 中斷、定時器

中斷、定時器中斷、定時器/

*實例42:用定時器T0查詢方式P2口8位控制LED閃爍

#include // 包含51單片機寄存器定義的頭文件

/

函數功能:主函數

/ void main(void)

{

// EA=1; //開總中斷

// ET0=1; //定時器T0中斷允許 TMOD=0x01; //使用定時器T0的模式1

TH0=(65536-46083)/256; //定時器T0的高8位賦初值

TL0=(65536-46083)%256; //定時器T0的高8位賦初值

TR0=1; //啟動定時器T0

TF0=0;

P2=0xff;

while(1)//無限循環等待查詢

{

while(TF0==0)

;

TF0=0;

P2=~P2;

TH0=(65536-46083)/256; //定時器T0的高8位賦初值 TL0=(65536-46083)%256; //定時器T0的高8位賦初值 }

}

*實例43:用定時器T1查詢方式控制單片機發出1KHz音頻 #include // 包含51單片機寄存器定義的頭文件 sbit sound=P3^7; //將sound位定義為P3.7引腳

/ 函數功能:主函數

/ void main(void)

{

// EA=1; //開總中斷

// ET0=1; //定時器T0中斷允許 TMOD=0x10; //使用定時器T1的模式1

TH1=(65536-921)/256; //定時器T1的高8位賦初值

TL1=(65536-921)%256; //定時器T1的高8位賦初值

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

TF1=0;

while(1)//無限循環等待查詢

{

while(TF1==0)

;

TF1=0;

sound=~sound; //將P3.7引腳輸出電平取反

TH1=(65536-921)/256; //定時器T0的高8位賦初值 TL1=(65536-921)%256; //定時器T0的高8位賦初值 }

}

*實例44:將計數器T0計數的結果送P1口8位LED顯示 #include // 包含51單片機寄存器定義的頭文件 sbit S=P3^4; //將S位定義為P3.4引腳

/ 函數功能:主函數

/ void main(void)

{

// EA=1; //開總中斷

// ET0=1; //定時器T0中斷允許 TMOD=0x02; //使用定時器T0的模式2

TH0=256-156; //定時器T0的高8位賦初值

TL0=256-156; //定時器T0的高8位賦初值

TR0=1; //啟動定時器T0

while(1)//無限循環等待查詢

{

while(TF0==0) //如果未計滿就等待

{

if(S==0) //按鍵S按下接地,電平為0

P1=TL0; //計數器TL0加1后送P1口顯示

}

TF0=0; //計數器溢出后,將TF0清0

}

}

*實例45:用定時器T0的中斷控制1位LED閃爍 #include // 包含51單片機寄存器定義的頭文件

sbit D1=P2^0; //將D1位定義為P2.0引腳

/ 函數功能:主函數

/ void main(void)

{

EA=1; //開總中斷

ET0=1; //定時器T0中斷允許

TMOD=0x01; //使用定時器T0的模式2

TH0=(65536-46083)/256; //定時器T0的高8位賦初值

TL0=(65536-46083)%256; //定時器T0的高8位賦初值

TR0=1; //啟動定時器T0

while(1)//無限循環等待中斷

;

}

/ 函數功能:定時器T0的中斷服務程序

/ void Time0(void) interrupt 1 using 0 //“interrupt”聲明函數為中斷服務函數 //其后的1為定時器T0的中斷編號;0表示使用第0組工作寄存器

{

D1=~D1; //按位取反操作,將P2.0引腳輸出電平取反

TH0=(65536-46083)/256; //定時器T0的高8位重新賦初值

TL0=(65536-46083)%256; //定時器T0的高8位重新賦初值

}

*實例46:用定時器T0的中斷實現長時間定時

#include // 包含51單片機寄存器定義的頭文件

sbit D1=P2^0; //將D1位定義為P2.0引腳

unsigned char Countor; //設置全局變量,儲存定時器T0中斷次數

/ 函數功能:主函數

/ void main(void)

{

EA=1; //開總中斷

ET0=1; //定時器T0中斷允許

TMOD=0x01; //使用定時器T0的模式2

TH0=(65536-46083)/256; //定時器T0的高8位賦初值

TL0=(65536-46083)%256; //定時器T0的高8位賦初值

TR0=1; //啟動定時器T0

Countor=0; //從0開始累計中斷次數

while(1)//無限循環等待中斷

;

}

/ 函數功能:定時器T0的中斷服務程序

/ void Time0(void) interrupt 1 using 0 //“interrupt”聲明函數為中斷服務函數

//其后的1為定時器T0的中斷編號;0表示使用第0組工作寄存器

{

Countor++; //中斷次數自加1

if(Countor==20) //若累計滿20次,即計時滿1s

{

D1=~D1; //按位取反操作,將P2.0引腳輸出電平取反

Countor=0; //將Countor清0,重新從0開始計數

}

TH0=(65536-46083)/256; //定時器T0的高8位重新賦初值

TL0=(65536-46083)%256; //定時器T0的高8位重新賦初值

}

*實例47:用定時器T1中斷控制兩個LED以不同周期閃爍 #include // 包含51單片機寄存器定義的頭文件

sbit D1=P2^0; //將D1位定義為P2.0引腳

sbit D2=P2^1; //將D2位定義為P2.1引腳

unsigned char Countor1; //設置全局變量,儲存定時器T1中斷次數

unsigned char Countor2; //設置全局變量,儲存定時器T1中斷次數

/ 函數功能:主函數

/ void main(void)

{

EA=1; //開總中斷

ET1=1; //定時器T1中斷允許

TMOD=0x10; //使用定時器T1的模式1

TH1=(65536-46083)/256; //定時器T1的高8位賦初值

TL1=(65536-46083)%256; //定時器T1的高8位賦初值

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

Countor1=0; //從0開始累計中斷次數

Countor2=0; //從0開始累計中斷次數

while(1)//無限循環等待中斷

;

}

/ 函數功能:定時器T1的中斷服務程序

/ void Time1(void) interrupt 3 using 0 //“interrupt”聲明函數為中斷服務函數 //其后的3為定時器T1的中斷編號;0表示使用第0組工作寄存器

{

Countor1++; //Countor1自加1

Countor2++; //Countor2自加1

if(Countor1==2) //若累計滿2次,即計時滿100ms

{

D1=~D1; //按位取反操作,將P2.0引腳輸出電平取反 Countor1=0; //將Countor1清0,重新從0開始計數

}

if(Countor2==8) //若累計滿8次,即計時滿400ms

{

D2=~D2; //按位取反操作,將P2.1引腳輸出電平取反 Countor2=0; //將Countor1清0,重新從0開始計數

}

TH1=(65536-46083)/256; //定時器T1的高8位重新賦初值

TL1=(65536-46083)%256; //定時器T1的高8位重新賦初值

}

*實例48:用計數器T1的中斷控制蜂鳴器發出1KHz音頻 #include // 包含51單片機寄存器定義的頭文件

sbit sound=P3^7; //將sound位定義為P3.7引腳

/ 函數功能:主函數

/ void main(void)

{

EA=1; //開總中斷

ET1=1; //定時器T1中斷允許

TMOD=0x10; //TMOD=0001 000B,使用定時器T1的模式1 TH1=(65536-921)/256; //定時器T1的高8位賦初值

TL1=(65536-921)%256; //定時器T1的高8位賦初值

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

while(1)//無限循環等待中斷

;

}

/ 函數功能:定時器T1的中斷服務程序

/ void Time1(void) interrupt 3 using 0 //“interrupt”聲明函數為中斷服務函數 {

sound=~sound;

TH1=(65536-921)/256; //定時器T1的高8位重新賦初值

TL1=(65536-921)%256; //定時器T1的高8位重新賦初值

}

*實例49:用定時器T0的中斷實現"渴望"主題曲的播放 #include //包含51單片機寄存器定義的頭文件

sbit sound=P3^7; //將sound位定義為P3.7

unsigned int C; //儲存定時器的定時常數

//以下是C調低音的音頻宏定義

#define l_dao 262 //將“l_dao”宏定義為低音“1”的頻率262Hz #define l_re 286 //將“l_re”宏定義為低音“2”的頻率286Hz #define l_mi 311 //將“l_mi”宏定義為低音“3”的頻率311Hz #define l_fa 349 //將“l_fa”宏定義為低音“4”的頻率349Hz #define l_sao 392 //將“l_sao”宏定義為低音“5”的頻率392Hz #define l_la 440 //將“l_a”宏定義為低音“6”的頻率440Hz #define l_xi 494 //將“l_xi”宏定義為低音“7”的頻率494Hz //以下是C調中音的音頻宏定義

#define dao 523 //將“dao”宏定義為中音“1”的頻率523Hz #define re 587 //將“re”宏定義為中音“2”的頻率587Hz #define mi 659 //將“mi”宏定義為中音“3”的頻率659Hz #define fa 698 //將“fa”宏定義為中音“4”的頻率698Hz #define sao 784 //將“sao”宏定義為中音“5”的頻率784Hz #define la 880 //將“la”宏定義為中音“6”的頻率880Hz

#define xi 987 //將“xi”宏定義為中音“7”的頻率523H //以下是C調高音的音頻宏定義

#define h_dao 1046 //將“h_dao”宏定義為高音“1”的頻率1046Hz #define h_re 1174 //將“h_re”宏定義為高音“2”的頻率1174Hz #define h_mi 1318 //將“h_mi”宏定義為高音“3”的頻率1318Hz #define h_fa 1396 //將“h_fa”宏定義為高音“4”的頻率1396Hz

#define h_sao 1567 //將“h_sao”宏定義為高音“5”的頻率1567Hz #define h_la 1760 //將“h_la”宏定義為高音“6”的頻率1760Hz #define h_xi 1975 //將“h_xi”宏定義為高音“7”的頻率1975Hz /

函數功能:1個延時單位,延時200ms

/

void delay()

{

unsigned char i,j;

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

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

;

}

/

函數功能:主函數

/

void main(void)

{

unsigned char i,j;

//以下是《渴望》片頭曲的一段簡譜

unsigned int code f[]={re,mi,re,dao,l_la,dao,l_la, //每行對應一小節音符 l_sao,l_mi,l_sao,l_la,dao,

l_la,dao,sao,la,mi,sao,

re,

mi,re,mi,sao,mi,

l_sao,l_mi,l_sao,l_la,dao,

l_la,l_la,dao,l_la,l_sao,l_re,l_mi,

l_sao,

re,re,sao,la,sao,

fa,mi,sao,mi,

la,sao,mi,re,mi,l_la,dao,

re,

mi,re,mi,sao,mi,

l_sao,l_mi,l_sao,l_la,dao,

l_la,dao,re,l_la,dao,re,mi,

re,

l_la,dao,re,l_la,dao,re,mi,

re,

0xff}; //以0xff作為音符的結束標志

//以下是簡譜中每個音符的節拍

//"4"對應4個延時單位,"2"對應2個延時單位,"1"對應1個延時單位 unsigned char code JP[ ]={4,1,1,4,1,1,2,

2,2,2,2,8,

4,2,3,1,2,2,

10,

4,2,2,4,4,

2,2,2,2,4,

2,2,2,2,2,2,2,

10,

4,4,4,2,2,

4,2,4,4,

4,2,2,2,2,2,2,

10,

4,2,2,4,4,

2,2,2,2,6,

4,2,2,4,1,1,4,

10,

4,2,2,4,1,1,4,

10

};

EA=1; //開總中斷

ET0=1; //定時器T0中斷允許

TMOD=0x00; // 使用定時器T0的模式1(13位計數器)

while(1) //無限循環

{

i=0; //從第1個音符f[0]開始播放

while(f[i]!=0xff) //只要沒有讀到結束標志就繼續播放 {

C=460830/f[i];

TH0=(8192-C)/32; //可證明這是13位計數器TH0高8位的賦初值方法

TL0=(8192-C)%32; //可證明這是13位計數器TL0低5位的賦初值方法

TR0=1; //啟動定時器T0

for(j=0;j

delay(); //延時1個節拍單位

TR0=0; //關閉定時器T0

i++; //播放下一個音符

}

}

}

/ 函數功能:定時器T0的中斷服務子程序,使P3.7引腳輸出音頻的方波 / void Time0(void ) interrupt 1 using 1

{

sound=!sound; //將P3.7引腳輸出電平取反,形成方波

TH0=(8192-C)/32; //可證明這是13位計數器TH0高8位的賦初值方法 TL0=(8192-C)%32; //可證明這是13位計數器TL0低5位的賦初值方法 }

*實例50-1:輸出50個矩形脈沖

#include //包含51單片機寄存器定義的頭文件

sbit u=P1^4; //將u位定義為P1.4

/

函數功能:延時約30ms (3 100 100=30 000μs =30m

/

void delay30ms(void)

{

unsigned char m,n;

for(m=0;m<100;m++)

for(n=0;n<100;n++)

;

}

/

函數功能:主函數

/

void main(void)

{

unsigned char i;

u=1; //初始化輸出高電平

for(i=0;i<50;i++) //輸出50個矩形脈沖

{

u=1;

delay30ms();

u=0;

delay30ms();

}

while(1)

; //無限循環,防止程序“跑飛”

}

*實例50-2:計數器T0統計外部脈沖數

#include //包含51單片機寄存器定義的頭文件

/

函數功能:主函數

/

void main(void)

{

TMOD=0x06; // TMOD=0000 0110B,使用計數器T0的模式2 EA=1; //開總中斷

ET0=0; //不使用定時器T0的中斷

TR0=1; //啟動T0

TH0=0; //計數器T0高8位賦初值

TL0=0; //計數器T0低8位賦初值

while(1) //無限循環,不停地將TL0計數結果送P1口

P1=TL0;

}

*實例51-2:定時器T0的模式2測量正脈沖寬度

#include //包含51單片機寄存器定義的頭文件

sbit ui=P3^2; //將ui位定義為P3.0(INT0)引腳,表示輸入電壓

/

函數功能:主函數

/

void main(void)

{

TMOD=0x0a; // TMOD=0000 1010B,使用定時器T0的模式2,GATE置1 EA=1; //開總中斷

ET0=0; //不使用定時器T0的中斷

TR0=1; //啟動T0

TH0=0; //計數器T0高8位賦初值

TL0=0; //計數器T0低8位賦初值

while(1) //無限循環,不停地將TL0計數結果送P1口 {

while(ui==0) //INT0為低電平,T0不能啟動

;

TL0=0; //INT0為高電平,啟動T0計時,所以將TL0清0 while(ui==1) //在INT0高電平期間,等待,計時

;

P1=TL0; //將計時結果送P1口顯示

}

}

*實例52:用定時器T0控制輸出高低寬度不同的矩形波 #include //包含51單片機寄存器定義的頭文件

sbit u=P3^0; //將u位定義為P3.0,從該引腳輸出矩形脈沖 unsigned char Countor; //設置全局變量,儲存負跳變累計數 / 函數功能:延時約30ms (3 100 100=30 000μs =30ms) / void delay30ms(void)

{

unsigned char m,n;

for(m=0;m<100;m++)

for(n=0;n<100;n++)

;

}

/

函數功能:主函數

/ void main(void)

{

unsigned char i;

EA=1; //開放總中斷

EX0=1; //允許使用外中斷

IT0=1; //選擇負跳變來觸發外中斷

Countor=0;

for(i=0;i<100;i++) //輸出100個負跳變

{

u=1;

delay30ms();

u=0;

delay30ms();

}

while(1)

; //無限循環, 防止程序跑飛

}

/ 函數功能:外中斷T0的中斷服務程序

void int0(void) interrupt 0 using 0 //外中斷0的中斷編號為0 /

{

Countor++;

P1=Countor;

}

*實例53:用外中斷0的中斷方式進行數據采集 #include //包含51單片機寄存器定義的頭文件

sbit S=P3^2; //將S位定義為P3.2,

/

函數功能:主函數

/

void main(void)

{

EA=1; //開放總中斷

EX0=1; //允許使用外中斷

IT0=1; //選擇負跳變來觸發外中斷

P1=0xff;

while(1)

; //無限循環, 防止程序跑飛

}

/ 函數功能:外中斷T0的中斷服務程序

/ void int0(void) interrupt 0 using 0 //外中斷0的中斷編號為0

{

P1=~P1; //每產生一次中斷請求,P1取反一次。

}

*實例54-1:輸出負脈寬為200微秒的方波

#include //包含51單片機寄存器定義的頭文件

sbit u=P1^4; //將u位定義為P1.4

/

函數功能:主函數

/

void main(void)

{

TMOD=0x02; //TMOD=0000 0010B,使用定時器T0的模式2 EA=1; //開總中斷

ET0=1; //定時器T0中斷允許

TH0=256-200; //定時器T0的高8位賦初值

TL0=256-200; //定時器T0的高8位賦初值

TR0=1; //啟動定時器T0

while(1) //無限循環,等待中斷

;

}

/ 函數功能:定時器T0的中斷服務程序

/ void Time0(void) interrupt 1 using 0 //"interrupt"聲明函數為中斷服務函數 {

u=~u; //將P1.4引腳輸出電平取反,產生方波

}

*實例54-2:測量負脈沖寬度

#include //包含51單片機寄存器定義的頭文件

sbit u=P3^2; //將u位定義為P3.2

/

函數功能:主函數

/

void main(void)

{

TMOD=0x02; //TMOD=0000 0010B,使用定時器T0的模式2

EA=1; //開放總中斷

EX0=1; //允許使用外中斷

IT0=1; //選擇負跳變來觸發外中斷

ET0=1; //允許定時器T0中斷

TH0=0; //定時器T0賦初值0

TL0=0; //定時器T0賦初值0

TR0=0; //先關閉T0

while(1)

; //無限循環, 不停檢測輸入負脈沖寬度

}

/ 函數功能:外中斷0的中斷服務程序

/ void int0(void) interrupt 0 using 0 //外中斷0的中斷編號為0

{

TR0=1; //外中斷一到來,即啟動T0計時

TL0=0; //從0開始計時

while(u==0) //低電平時,等待T0計時

;

P1=TL0; //將結果送P1口顯示

TR0=0; //關閉T0

}

*實例55:方式0控制流水燈循環點亮

#include //包含51單片機寄存器定義的頭文件

#include //包含函數_nop_()定義的頭文件

unsigned char code Tab[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};//流水燈控制碼,該數組被定義為全局變量

sbit P17=P1^7;

/ 函數功能:延時約150ms

/ void delay(void)

{

unsigned char m,n;

for(m=0;m<200;m++)

for(n=0;n<250;n++)

;

}

/ 函數功能:發送一個字節的數據

/ void Send(unsigned char dat)

{

P17=0; //P1.7引腳輸出清0信號,對74LS164清0

_nop_(); //延時一個機器周期

_nop_(); //延時一個機器周期,保證清0完成

P17=1; //結束對74LS164的清0

SBUF=dat; //將數據寫入發送緩沖器,啟動發送

while(TI==0) //若沒有發送完畢,等待

;

TI=0; //發送完畢,TI被置“1”,需將其清0

}

/

函數功能:主函數

/

void main(void)

{

unsigned char i;

SCON=0x00; //SCON=0000 0000B,使串行口工作于方式0 while(1)

{

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

{

Send(Tab[i]); //發送數據

delay(); //延時

}

}

}

*實例56-1:數據發送程序

#include //包含單片機寄存器的頭文件

unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; //流水燈控制碼,該數組被定義為全局變量

/ 函數功能:向PC發送一個字節數據

/ void Send(unsigned char dat)

{

SBUF=dat;

while(TI==0)

;

TI=0;

}

/ 函數功能:延時約150ms

void delay(void)

{ /

unsigned char m,n;

for(m=0;m<200;m++)

for(n=0;n<250;n++)

;

}

/ 函數功能:主函數

/ void main(void)

{

unsigned char i;

TMOD=0x20; //TMOD=0010 0000B,定時器T1工作于方式2 SCON=0x40; //SCON=0100 0000B,串口工作方式1 PCON=0x00; //PCON=0000 0000B,波特率9600

TH1=0xfd; //根據規定給定時器T1賦初值

TL1=0xfd; //根據規定給定時器T1賦初值

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

while(1)

{

for(i=0;i<8;i++) //模擬檢測數據

{

Send(Tab[i]); //發送數據i

delay(); //50ms發送一次檢測數據 }

}

}

*實例56-2:數據接收程序

#include //包含單片機寄存器的頭文件

/ 函數功能:接收一個字節數據

/ unsigned char Receive(void)

{

unsigned char dat;

while(RI==0) //只要接收中斷標志位RI沒有被置“1” ; //等待,直至接收完畢(RI=1)

RI=0; //為了接收下一幀數據,需將RI清0 dat=SBUF; //將接收緩沖器中的數據存于dat

return dat;

}

/

函數功能:主函數

/

void main(void)

{

TMOD=0x20; //定時器T1工作于方式2

SCON=0x50; //SCON=0101 0000B,串口工作方式1,允許接收(REN=1) PCON=0x00; //PCON=0000 0000B,波特率9600

TH1=0xfd; //根據規定給定時器T1賦初值

TL1=0xfd; //根據規定給定時器T1賦初值

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

REN=1; //允許接收

while(1)

{

P1=Receive(); //將接收到的數據送P1口顯示

}

}

*實例57-1:數據發送程序

#include //包含單片機寄存器的頭文件

sbit p=PSW^0;

unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; //流水燈控制碼,該數組被定義為全局變量

/

函數功能:向PC發送一個字節數據

/

void Send(unsigned char dat)

{

ACC=dat;

TB8=p;

SBUF=dat;

while(TI==0)

;

TI=0;

}

/ 函數功能:延時約150ms

/

void delay(void)

{

unsigned char m,n;

for(m=0;m<200;m++)

for(n=0;n<250;n++)

;

}

/ 函數功能:主函數

/ void main(void)

{

unsigned char i;

TMOD=0x20; //TMOD=0010 0000B,定時器T1工作于方式2 SCON=0xc0; //SCON=1100 0000B,串口工作方式3, //SM2置0,不使用多機通信,TB8置0 PCON=0x00; //PCON=0000 0000B,波特率9600

TH1=0xfd; //根據規定給定時器T1賦初值

TL1=0xfd; //根據規定給定時器T1賦初值

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

while(1)

{

for(i=0;i<8;i++) //模擬檢測數據

{

Send(Tab[i]); //發送數據i

delay(); //50ms發送一次檢測數據 }

}

}

*實例57-2:數據接收程序

#include //包含單片機寄存器的頭文件 sbit p=PSW^0;

/ 函數功能:接收一個字節數據

/ unsigned char Receive(void)

{

unsigned char dat;

while(RI==0) //只要接收中斷標志位RI沒有被置"1"

; //等待,直至接收完畢(RI=1)

RI=0; //為了接收下一幀數據,需將RI清0

ACC=SBUF; //將接收緩沖器中的數據存于dat

if(RB8==p)

{

dat=ACC;

return dat;

}

}

/

函數功能:主函數

/

void main(void)

{

TMOD=0x20; //定時器T1工作于方式2

SCON=0xd0; //SCON=1101 0000B,串口工作方式1,允許接收(REN=1) PCON=0x00; //PCON=0000 0000B,波特率9600

TH1=0xfd; //根據規定給定時器T1賦初值

TL1=0xfd; //根據規定給定時器T1賦初值

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

REN=1; //允許接收

while(1)

{

P1=Receive(); //將接收到的數據送P1口顯示

}

}

*實例58:單片機向PC發送數據

#include //包含單片機寄存器的頭文件

unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; //流水燈控制碼,該數組被定義為全局變量

/

函數功能:向PC發送一個字節數據

/

void Send(unsigned char dat)

{

SBUF=dat;

while(TI==0)

;

TI=0;

}

/ 函數功能:延時約150ms

/ void delay(void)

{

unsigned char m,n;

for(m=0;m<200;m++)

for(n=0;n<250;n++)

;

}

/ 函數功能:主函數

/

void main(void)

{

unsigned char i;

TMOD=0x20; //TMOD=0010 0000B,定時器T1工作于方式2 SCON=0x40; //SCON=0100 0000B,串口工作方式1

PCON=0x00; //PCON=0000 0000B,波特率9600

TH1=0xfd; //根據規定給定時器T1賦初值

TL1=0xfd; //根據規定給定時器T1賦初值

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

while(1)

{

for(i=0;i<8;i++) //模擬檢測數據

{

Send(Tab[i]); //發送數據i

delay(); //150ms發送一次數據

}

}

}

*實例59:單片機接收PC發出的數據

#include //包含單片機寄存器的頭文件

/ 函數功能:接收一個字節數據

/

unsigned char Receive(void)

{

unsigned char dat;

while(RI==0) //只要接收中斷標志位RI沒有被置“1”

; //等待,直至接收完畢(RI=1)

RI=0; //為了接收下一幀數據,需將RI清0

dat=SBUF; //將接收緩沖器中的數據存于dat

return dat;

}

/

函數功能:主函數

/

void main(void)

{

TMOD=0x20; //定時器T1工作于方式2

SCON=0x50; //SCON=0101 0000B,串口工作方式1,允許接收(REN=1)

PCON=0x00; //PCON=0000 0000B,波特率9600

TH1=0xfd; //根據規定給定時器T1賦初值

TL1=0xfd; //根據規定給定時器T1賦初值

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

REN=1; //允許接收

while(1)

{

P1=Receive(); //將接收到的數據送P1口顯示

}

}

/ 數碼管顯示 數碼管顯示 數

碼管顯示數碼管顯示/

*實例60:用LED數碼顯示數字5

#include // 包含51單片機寄存器定義的頭文件

void main(void)

{

P2=0xfe; //P2.0引腳輸出低電平,數碼顯示器接通電源準備點亮

P0=0x92; //讓P0口輸出數字"5"的段碼92H

}

*實例61:用LED數碼顯示器循環顯示數字0~9

#include // 包含51單片機寄存器定義的頭文件

/

函數功能:延時函數,延時一段時間

/

void delay(void)

{

unsigned char i,j;

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

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

;

}

/

函數功能:主函數

/

void main(void)

{

unsigned char i;

unsigned char code

Tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

//數碼管顯示0~9的段碼表,程序運行中當數組值不發生變化

時,

//前面加關鍵字code ,可以大大節約單片機的存儲空間 P2=0xfe; //P2.0引腳輸出低電平,數碼顯示器DS0接通電源工作

while(1) //無限循環

{

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

{

P0=Tab[i]; //讓P0口輸出數字的段碼92H

delay(); //調用延時函數

}

}

}

*實例62:用數碼管慢速動態掃描顯示數字"1234" #include // 包含51單片機寄存器定義的頭文件 void delay(void) //延時函數,延時一段時間

{

unsigned char i,j;

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

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

;

}

void main(void)

{

while(1) //無限循環

{

P2=0xfe; //P2.0引腳輸出低電平,DS0點亮

P0=0xf9; //數字1的段碼

delay();

P2=0xfd ; //P2.1引腳輸出低電平,DS1點亮

P0=0xa4; //數字2的段碼

delay();

P2=0xfb; //P2.2引腳輸出低電平,DS2點亮

P0=0xb0; //數字3的段碼

delay();

P2=0xf7; //P2.3引腳輸出低電平,DS3點亮

P0=0x99; //數字4的段碼

delay();

P2=0xff;

}

}

*實例63:用LED數碼顯示器偽靜態顯示數字1234 #include // 包含51單片機寄存器定義的頭文件 void delay(void) //延時函數,延時約0.6毫秒

{

unsigned char i;

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

;

}

void main(void)

{

while(1) //無限循環

{

P2=0xfe; //P2.0引腳輸出低電平,DS0點亮

P0=0xf9; //數字1的段碼

delay();

P2=0xfd ; //P2.1引腳輸出低電平,DS1點亮

P0=0xa4; //數字2的段碼

delay();

P2=0xfb; //P2.2引腳輸出低電平,DS2點亮

P0=0xb0; //數字3的段碼

delay();

P2=0xf7; //P2.3引腳輸出低電平,DS3點亮

P0=0x99; //數字4的段碼

delay();

P2=0xff;

}

}

*實例64:用數碼管顯示動態檢測結果

#include // 包含51單片機寄存器定義的頭文件

#include //包含隨機函數rand()的定義文件

unsigned char i; //記錄中斷次數

unsigned int x; //隨機檢測的數據

unsigned char code Tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //數碼管顯示0~9的段碼表

/ 函數功能:快速動態掃描延時,延時約0.9毫秒

/

void delay(void)

{

unsigned int i;

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

;

}

/

函數功能:4位數的數碼顯示器顯示

入口參數:k

出口參數:無

/

void display(unsigned int k)

{

P2=0xfe; //即P2=1111 1110B,P2.0引腳輸出低電平,數碼顯示器DS0接通電源

P0=Tab[k/1000]; //顯示千位

delay();

P2=0xfd ; //即P2=1111 1101B,P2.1引腳輸出低電平,數碼顯示器DS1接通電源

P0=Tab[(k%1000)/100]; //顯示百位

delay();

P2=0xfb; //即P2=1111 1011B,P2.2引腳輸出低電平,數碼顯示器DS2接通電源

P0=Tab[(k%100)/10]; //顯示十位

delay();

P2=0xf7; //即P2=1111 0111B ,P2.3引腳輸出低電平,數碼顯示器DS3接通電源

P0=Tab[k%10];//顯示個位

delay();

P2=0xff; //關閉所有顯示器

}

void main(void) //主函數

{

TMOD=0x01; //使用定時器T0

TH0=(65536-46083)/256; //將定時器計時時間設定為46083×1.085微秒=50000微秒=50毫秒

TL0=(65536-46083)%256;

EA=1; //開啟總中斷

ET0=1; //定時器T0中斷允許

TR0=1; //啟動定時器T0開始運行

while(1)

{

display(x); //調用檢測結果的顯示程序

}

}

/

函數功能:定時器T0的中斷服務程序

/

void Time0(void) interrupt 1 using 1

{

TR0=0; //關閉定時器T0

i++; //每來一次中斷,i自加1

if(i==20) //夠20次中斷,即1秒鐘進行一次檢測結果采樣

{

x=rand()/10; //隨機產生一個從0到32767的整數,再將其除以10,獲得一個隨機4位數,模擬檢測結果

i=0; //將i清0,重新統計中斷次數

}

TH0=(65536-46083)/256; //重新給計數器T0賦初值

TL0=(65536-46083)%256;

TR0=1; //啟動定時器T0

}

*實例65:數碼秒表設計

#include // 包含51單片機寄存器定義的頭文件

unsigned char code Tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //數碼管顯示0~9的段碼表

unsigned char int_time; //記錄中斷次數

unsigned char second; //儲存秒

/ 函數功能:快速動態掃描延時,延時約0.6毫秒

/

void delay(void)

{

unsigned char i;

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

;

}

/ 函數功能:顯示秒

入口參數:k

出口參數:無

/

void DisplaySecond(unsigned char k)

{

P2=0xfb; //P2.6引腳輸出低電平, DS6點亮

P0=Tab[k/10]; //顯示十位

delay();

P2=0xf7; //P2.7引腳輸出低電平, DS7點亮

P0=Tab[k%10]; //顯示個位

delay();

P2=0xff; //關閉所有數碼管

}

void main(void) //主函數

{

TMOD=0x01; //使用定時器T0

TH0=(65536-46083)/256; //將定時器計時時間設定為46083×1.085微秒

//=50000微秒=50毫秒

TL0=(65536-46083)%256;

EA=1; //開啟總中斷

ET0=1; //定時器T0中斷允許

TR0=1; //啟動定時器T0開始運行

int_time=0; //中斷次數初始化

second=0; //秒初始化

while(1)

{

DisplaySecond(second); //調用秒的顯示子程序

}

}

//

//函數功能:定時器T0的中斷服務程序

//

void interserve(void ) interrupt 1 using 1

{

TR0=0; //關閉定時器T0

int_time ++; //每來一次中斷,中斷次數int_time自加1

if(int_time==20) //夠20次中斷,即1秒鐘進行一次檢測結果采樣 {

int_time=0; //中斷次數清0

second++; //秒加1

if(second==60)

second =0; //秒等于60就返回0

}

TH0=(65536-46083)/256; //重新給計數器T0賦初值

TL0=(65536-46083)%256;

TR0=1; //啟動定時器T0

}

*實例66:數碼時鐘設計

#include // 包含51單片機寄存器定義的頭文件

unsigned char Tab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //control shape

unsigned char port[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; unsigned char int_time ; //中斷次數計數變量

unsigned char second; //秒計數變量

unsigned char minute; //分鐘計數變量

unsigned char hour; //小時計數變量

/////////////////////////////////////////////////////

void delay(void) //延時函數,延時約0.6ms

{

unsigned char j;

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

;

}

/ 函數功能:顯示秒的子程序

入口參數:s

void DisplaySecond(unsigned char s)

{

P2=0xbf; //P2.6引腳輸出低電平, DS6點亮

P0=Tab[s/10]; //顯示十位

delay();

P2=0x7f; //P2.7引腳輸出低電平, DS7點亮

P0=Tab[s%10]; //顯示個位 /

delay();

P2=0xff; //關閉所有數碼管

}

/ 函數功能:顯示分鐘的子程序

入口參數:m

/ void DisplayMinute(unsigned char m)

{

P2=0xf7; // P2.3引腳輸出低電平, DS3點亮

P0=Tab[m/10];//顯示個位

delay();

P2=0xef; // P2.4引腳輸出低電平, DS4點亮

P0=Tab[m%10];

delay();

P2=0xdf; //P2.5引腳輸出低電平, DS5點亮

P0=0xbf; //分隔符“-”的段碼

delay();

P2=0xff; //關閉所有數碼管

}

/ 函數功能:顯示小時的子程序

入口參數:h

void DisplayHour(unsigned char h)

{

P2=0xfe; //P2.0引腳輸出低電平, DS0點亮

P0=Tab[h/10]; //顯示十位

delay();

P2=0xfd; //P2.1引腳輸出低電平, DS1點亮

P0=Tab[h%10]; //顯示個位

delay();

P2=0xfb; //P2.2引腳輸出低電平, DS2點亮

P0=0xbf; //分隔符“-”的段碼

delay();

P2=0xff; //關閉所有數碼管

/

}

/ 函數功能:主函數

/

void main(void)

{

TMOD=0x01; //使用定時器T0

EA=1; //開中斷總允許

ET0=1; //允許T0中斷

TH0=(65536-46083)/256; //定時器高八位賦初值

TL0=(65536-46083)%256; //定時器低八位賦初值

TR0=1;

int_time=0; //中斷計數變量初始化

second=0; //秒計數變量初始化

minute=0; //分鐘計數變量初始化

hour=0; //小時計數變量初始化

while(1)

{

DisplaySecond(second); //調用秒顯示子程序 delay();

DisplayMinute(minute); //調用分鐘顯示子程序 delay();

DisplayHour(hour);

delay();

}

}

/ 函數功能:定時器T0的中斷服務子程序

void interserve(void ) interrupt 1 using 1 //using Time0

{

int_time++;

if(int_time==20)

{

int_time=0; //中斷計數變量清0

second++; //秒計數變量加1

}

if(second==60)

{

second=0; //如果秒計滿60,將秒計數變量清0 /

清0

清0

}

} minute++; //分鐘計數變量加1 if(minute==60) { minute=0; //如果分鐘計滿60,將分鐘計數變量 hour++; //小時計數變量加1 } if(hour==24) { hour=0; //如果小時計滿24,將小時計數變量 } TH0=(65536-46083)/256; //定時器重新賦初值 TL0=(65536-46083)%256;

*實例67:LED數碼管顯示計數器T0的計數值

#include //包含51單片機寄存器定義的頭文件

sbit S=P3^2 ; //將S位定義為P3.2引腳

unsigned char Tab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //段碼表

unsigned char x;

/ 函數功能:延時約0.6ms

/ void delay(void)

{

unsigned char j;

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

;

}

/ 函數功能:顯示計數次數的子程序

入口參數:x

/ void Display(unsigned char x)

{

P2=0xf7; //P2.6引腳輸出低電平,DS6點亮

P0=Tab[x/10]; //顯示十位

delay();

P2=0xfb; //P2.7引腳輸出低電平,DS7點亮

P0=Tab[x%10]; //顯示個位

delay();

}

/

函數功能:主函數

/

void main(void)

{

EA=1; //開放總中斷

EX0=1; //允許使用外中斷

IT0=1; //選擇負跳變來觸發外中斷

x=0;

while(1)

Display(x);

}

/ 函數功能:外中斷T0的中斷服務程序

void int0(void) interrupt 0 using 0 //外中斷0的中斷編號為0

{

x++;

if(x==100)

x=0;

}

*實例68:靜態顯示數字“59”

#include //包含51單片機寄存器定義的頭文件

/ /

函數功能:主函數

/

void main(void)

{

P0=0x92; //將數字5的段碼送P0口

P1=0x90; //將數字9的段碼送P1口

while(1) //無限循環,防止程序跑飛

;

}

*實例69:無軟件消抖的獨立式鍵盤輸入實驗 #include // 包含51單片機寄存器定義的頭文件 sbit S1=P1^4; //將S1位定義為P1.4引腳

sbit LED0=P3^0; //將LED0位定義為P3.0引腳 void main(void) //主函數

{

LED0=0; //P3.0引腳輸出低電平

while(1)

{

if(S1==0) //P1.4引腳輸出低電平,按鍵S1被按下 LED0=!LED0; //P3.0引腳取反

}

}

*實例70:軟件消抖的獨立式鍵盤輸入實驗

#include // 包含51單片機寄存器定義的頭文件 sbit S1=P1^4; //將S1位定義為P1.4引腳

sbit LED0=P3^0; //將LED0位定義為P3.0引腳

/ 函數功能:延時約30ms

/ void delay(void)

{

unsigned char i,j;

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

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

;

}

/ 函數功能:主函數

/ void main(void) //主函數

{

LED0=0; //P3.0引腳輸出低電平

while(1)

{

if(S1==0) //P1.4引腳輸出低電平,按鍵S1被按下 {

delay(); //延時一段時間再次檢測

if(S1==0) // 按鍵S1的確被按下

LED0=!LED0; //P3.0引腳取反

}

}

}

*實例71:CPU控制的獨立式鍵盤掃描實驗

#include //包含51單片機寄存器定義的頭文件 sbit S1=P1^4; //將S1位定義為P1.4引腳 sbit S2=P1^5; //將S2位定義為P1.5引腳 sbit S3=P1^6; //將S3位定義為P1.6引腳 sbit S4=P1^7; //將S4位定義為P1.7引腳 unsigned char keyval; //儲存按鍵值

/ 函數功能:流水燈延時

/ void led_delay(void)

{

unsigned char i,j;

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

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

;

}

/ 函數功能:軟件消抖延時

/

void delay30ms(void)

{

unsigned char i,j;

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

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

;

}

/ 函數功能:正向流水點亮LED

void forward(void)

{

P3=0xfe; //第一個燈亮

led_delay();

P3=0xfd; //第二個燈亮

led_delay();

P3=0xfb; //第三個燈亮 led_delay();

P3=0xf7; //第四個燈亮 led_delay();

P3=0xef; //第五個燈亮

led_delay();

P3=0xdf; //第六個燈亮

led_delay();

P3=0xbf; //第七個燈亮

led_delay();

P3=0x7f; //第八個燈亮

led_delay();

P3=0xff;

P3=0xfe; //第一個燈亮

led_delay();

}

/ 函數功能:反向流水點亮LED

void backward(void)

{

P3=0x7f; //第八個燈亮

led_delay();

P3=0xbf; //第七個燈亮

led_delay();

P3=0xdf; //第六個燈亮

led_delay();

P3=0xef; //第五個燈亮 / /

led_delay();

P3=0xf7; //第四個燈亮

led_delay();

P3=0xfb; //第三個燈亮

led_delay();

P3=0xfd; //第二個燈亮

led_delay();

P3=0xfe; //第一個燈亮

led_delay();

}

/ 函數功能:關閉所有LED

/ void stop(void)

{

P3=0xff;

}

/ 函數功能:閃爍點亮LED

/ void flash(void)

{

P3=0xff;

led_delay();

P3=0x00;

led_delay();

}

/ 函數功能:鍵盤掃描子程序

/ void key_scan(void)

{

if((P1&0xf0)!=0xf0) //第一次檢測到有鍵按下 {

delay30ms(); //延時20ms再去檢測 if(S1==0) //按鍵S1被按下 keyval=1;

if(S2==0) //按鍵S2被按下 keyval=2;

if(S3==0) //按鍵S3被按下 keyval=3;

if(S4==0) //按鍵S4被按下 keyval=4;

}

}

/ 函數功能:主函數

/ void main(void) //主函數

{

keyval=0; //按鍵值初始化為0,什么也不做 while(1)

{

key_scan();

switch(keyval)

{

case 1:forward();

break;

case 2:backward();

break;

case 3:stop();

break;

case 4: flash();

break;

}

}

}

*實例72:定時器中斷控制的獨立式鍵盤掃描實驗 #include //包含51單片機寄存器定義的頭文件 sbit S1=P1^4; //將S1位定義為P1.4引腳

sbit S2=P1^5; //將S2位定義為P1.5引腳

sbit S3=P1^6; //將S3位定義為P1.6引腳

sbit S4=P1^7; //將S4位定義為P1.7引腳

unsigned char keyval; //儲存按鍵值

/ 函數功能:流水燈延時

/ void led_delay(void)

{

unsigned char i,j;

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

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

;

}

/ 函數功能:軟件消抖延時

/ void delay20ms(void)

{

unsigned char i,j;

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

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

;

}

/ 函數功能:正向流水點亮LED

void forward(void)

{

P3=0xfe; //第一個燈亮

led_delay();

P3=0xfd; //第二個燈亮

led_delay();

P3=0xfb; //第三個燈亮

led_delay();

P3=0xf7; //第四個燈亮

led_delay();

P3=0xef; //第五個燈亮

led_delay();

P3=0xdf; //第六個燈亮

led_delay();

P3=0xbf; //第七個燈亮

led_delay();

P3=0x7f; //第八個燈亮

led_delay();

P3=0xff;

P3=0xfe; //第一個燈亮

led_delay();

}

/ 函數功能:反向流水點亮LED

void backward(void) / /

{

P3=0x7f; //第八個燈亮 led_delay();

P3=0xbf; //第七個燈亮 led_delay();

P3=0xdf; //第六個燈亮 led_delay();

P3=0xef; //第五個燈亮 led_delay();

P3=0xf7; //第四個燈亮 led_delay();

P3=0xfb; //第三個燈亮 led_delay();

P3=0xfd; //第二個燈亮 led_delay();

P3=0xfe; //第一個燈亮 led_delay();

}

/ 函數功能:關閉所有LED

void stop(void)

{

P3=0xff; //關閉8個LED }

/ 函數功能:閃爍點亮LED

void flash(void)

{

P3=0xff; //關閉8個LED

led_delay();

P3=0x00; //點亮8個LED

led_delay();

}

/ 函數功能:主函數

void main(void) //主函數

{

TMOD=0x01; //使用定時器T0的模式1 / / /

EA=1; //開總中斷

ET0=1; //定時器T0中斷允許

TR0=1; //啟動定時器T0

TH0=(65536-1000)/256; //定時器T0賦初值,每計數200次(217微秒)發送一次中斷請求

TL0=(65536-1000)%256; //定時器T0賦初值

keyval=0; //按鍵值初始化為0,什么也不做

while(1)

{

switch(keyval)

{

case 1:forward();

break;

case 2:backward();

break;

case 3:stop();

break;

case 4: flash();

break;

}

}

}

/

函數功能:定時器T0的中斷服務子程序

/

void Time0_serve(void) interrupt 1 using 1

{

if((P1&0xf0)!=0xf0) //第一次檢測到有鍵按下

{

delay20ms(); //延時20ms再去檢測

if(S1==0) //按鍵S1被按下

keyval=1;

if(S2==0) //按鍵S2被按下

keyval=2;

if(S3==0) //按鍵S3被按下

keyval=3;

if(S4==0) //按鍵S4被按下

keyval=4;

}

TH0=(65536-1000)/256;

TL0=(65536-1000)%256;

}

*實例73:獨立式鍵盤控制的4級變速流水燈 #include // 包含51單片機寄存器定義的頭文件 unsigned char speed; //儲存流水燈的流動速度

sbit S1=P1^4; //位定義S1為P1.4

sbit S2=P1^5; //位定義S2為P1.5

sbit S3=P1^6; //位定義S3為P1.6

sbit S4=P1^7; //位定義S4為P1.7

/ 函數功能:延時20ms的子程序

void delay20ms(void) //3 i j+2 i=3 100 60+2 100=20000μs=20ms; {

unsigned char i,j;

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

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

;

}

/ 函數功能:延時可調子程序

入口參數:x

void delay(unsigned char x)

{

unsigned char k;

for(k=0;k

delay20ms();

}

/ 函數功能:主函數

void main(void)

{

TMOD=0x02; //使用定時器T0的模式2

EA=1; //開總中斷

ET0=1; //定時器T0中斷允許

TR0=1; //定時器T0開始運行

TH0=256-200; //定時器T0賦初值,每200微妙來1次中斷請求 TL0=256-200;

speed=3; //默認流水燈流水點亮延時20ms×3=60ms / / /

while(1)

{

P3=0xfe; //第一個燈亮

delay(speed); //調用延時可調子程序

P3=0xfd; //第二個燈亮

delay(speed);

P3=0xfb; //第三個燈亮

delay(speed);

P3=0xf7; //第四個燈亮

delay(speed);

P3=0xef; //第五個燈亮

delay(speed);

P3=0xdf; //第六個燈亮

delay(speed);

P3=0xbf; //第七個燈亮

delay(speed);

P3=0x7f; //第八個燈亮

delay(speed);

P3=0xff;

}

}

/ 函數功能:定時器T0的中斷服務子程序,進行鍵盤掃描

/ void intersev(void) interrupt 1 using 1

{

TR0=0; //關閉定時器T0/

P1=0xff; //將P1口的均置高電平"1"

if((P1&0xf0)!=0xf0) //如果有鍵按下

{

delay20ms(); //延時20ms,軟件消抖

if((P1&0xf0)!=0xf0) //確實有鍵按下

{

if(S1==0) //如果是按鍵S1按下

speed=5; //流水燈流水點亮延時20ms×5=100ms if(S2==0) //如果是按鍵S2按下

speed=10; //流水燈流水點亮延時20ms×10=200ms if(S3==0) //如果是按鍵S3按下

speed=25; //流水燈流水點亮延時20ms×25=500ms if(S4==0) //如果是按鍵S4按下

speed=50; //流水燈流水點亮延時20ms×50=1000ms }

}

TR0=1; //啟動定時器T0

}

*實例74:獨立式鍵盤的按鍵功能擴展:"以一當四" #include // 包含51單片機寄存器定義的頭文件 unsigned char ID; //儲存流水燈的流動速度

sbit S1=P1^4; //位定義S1為P1.4

/ 函數功能:延時子程序

/ void delay(void) //因為僅對一個按鍵掃描,所以延時時間較長約200ms {

unsigned char i,j;

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

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

;

}

/ 函數功能:主函數

/ void main(void)

{

TMOD=0x02; //使用定時器T0的模式2

EA=1; //開總中斷

ET0=1; //定時器T0中斷允許

TR0=1; //定時器T0開始運行

TH0=256-200; //定時器T0賦初值,每200微妙來1次中斷請求 TL0=256-200;

ID=0;

while(1)

{

switch(ID)

{

case 0: P3=0xfe;

break;

case 1: P3=0xfd;

break;

case 2: P3=0xfb;

break;

case 3: P3=0xf7;

break;

}

}

}

/ 函數功能:定時器T0的中斷服務子程序,進行鍵盤掃描

/ void intersev(void) interrupt 1 using 1

{

TR0=0; //關閉定時器T0

P1=0xff;

if(S1==0) //如果是按鍵S1按下

{

delay(); //延時20ms,軟件消抖

if(S1==0) //如果是按鍵S1按下

ID=ID+1;

}

if(ID==4)

ID=0;

TR0=1; //啟動定時器T0

}

*實例75:獨立式鍵盤調時的數碼時鐘實驗

#include // 包含51單片機寄存器定義的頭文件

unsigned char code Tab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //數字0~9的段碼

unsigned char int_time ; //中斷次數計數變量

unsigned char second; //秒計數變量

unsigned char minute; //分鐘計數變量

unsigned char hour; //小時計數變量

sbit S1=P1^4; //將S1位定義為P1.4

sbit S2=P1^5; //將S2位定義為P1.5

sbit S3=P1^6; //將S3位定義為P1.6

sbit S4=P1^7; //將S4位定義為P1.7

/ 函數功能:數碼管掃描延時

/ void delay(void)

{

unsigned char j;

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

;

}

/ 函數功能:鍵盤掃描延時

void delay60ms(void)

{

unsigned char i,j;

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

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

;

}

/ 函數功能:顯示秒

入口參數:s

void DisplaySecond(unsigned char s)

{

P2=0xbf; //P2.6引腳輸出低電平, DS6點亮

P0=Tab[s/10]; //顯示十位

delay();

P2=0x7f; //P2.7引腳輸出低電平, DS7點亮

P0=Tab[s%10]; //顯示個位

delay();

P2=0xff; //關閉所有數碼管

}

/ 函數功能:顯示分鐘

入口參數:m

void DisplayMinute(unsigned char m)

{ / / /

P2=0xf7; // P2.3引腳輸出低電平, DS3點亮 P0=Tab[m/10];//顯示個位

delay();

P2=0xef; // P2.4引腳輸出低電平, DS4點亮 P0=Tab[m%10];

delay();

P2=0xdf; //P2.5引腳輸出低電平, DS5點亮 P0=0xbf; //分隔符“-”的段碼

delay();

P2=0xff; //關閉所有數碼管

}

/ 函數功能:顯示小時的子程序

入口參數:h

void DisplayHour(unsigned char h)

{

P2=0xfe; //P2.0引腳輸出低電平, DS0點亮 P0=Tab[h/10]; //顯示十位

delay();

P2=0xfd; //P2.1引腳輸出低電平, DS1點亮 P0=Tab[h%10]; //顯示個位

delay();

P2=0xfb; //P2.2引腳輸出低電平, DS2點亮 P0=0xbf; //分隔符“-”的段碼

delay();

P2=0xff; //關閉所有數碼管

}

/ 函數功能:鍵盤掃描

void key_scan(void)

{

P1=0xf0; //將P1口高4位置高電平“1”

if((P1&0xf0)!=0xf0) //有鍵按下

{

delay60ms(); //延時60ms再檢測

if((P1&0xf0)!=0xf0) //確實有鍵按下 {

if(S1==0) //如果是S1鍵按下 second++; //秒加1 / /

if(S2==0) //如果是S2鍵按下 minute++; //分鐘加1

if(S3==0) //如果是S3鍵按下 hour++; //小時加1

if(S4==0) //如果是S4鍵按下 {

second=0; //秒清0

minute=0; //分鐘清0

hour=0; //小時清0

}

}

}

}

/ 函數功能:主函數

void main(void)

{

TMOD=0x01; //使用定時器T0 EA=1; //開中斷總允許

ET0=1; //允許T0中斷

TH0=(65536-46083)/256; //定時器高八位賦初值 TL0=(65536-46083)%256; //定時器低八位賦初值 TR0=1; //啟動定時器T0

int_time=0; //中斷計數變量初始化

second=0; //秒計數變量初始化

minute=0; //分鐘計數變量初始化

hour=0; //小時計數變量初始化

while(1)

{

DisplaySecond(second); //調用秒顯示子程序 DisplayMinute(minute); //調用分鐘顯示子程序 DisplayHour(hour); //調用小時顯示子程序

}

}

/ 函數功能:定時器T0的中斷服務子程序

/ /

void interserve(void ) interrupt 1 using 1 //using Time0

{

TR0=0; //關閉定時器T0

int_time++; //中斷次數加1

if(int_time==20) //如果中斷次數滿20

{

int_time=0; //中斷計數變量清0

second++; //秒計數變量加1

}

if(second==60) //如果秒計滿60

{

second=0; //如果秒計滿60,將秒計數變量清0 minute++; //分鐘計數變量加1

}

if(minute==60) //如果分鐘計滿60

{

minute=0; //如果分鐘計滿60,將分鐘計數變量清0 hour++; //小時計數變量加1

}

if(hour==24) //如果小時計滿24

{

hour=0; //如果小時計滿24,將小時計數變量清0 }

key_scan(); //執行鍵盤掃描

TH0=(65536-46083)/256; //定時器T0高四位賦值

TL0=(65536-46083)%256; //定時器T0低四位賦值

TR0=1; //啟動定時器T0

}

*實例76:獨立式鍵盤控制步進電機實驗

#include //包含51單片機寄存器定義的頭文件

sbit S1=P1^4; //將S1位定義為P1.4引腳

sbit S2=P1^5; //將S2位定義為P1.5引腳

sbit S3=P1^6; //將S3位定義為P1.6引腳

unsigned char keyval; //儲存按鍵值

unsigned char ID; //儲存功能標號

/

函數功能:軟件消抖延時(約50ms)

/

void delay(void)

{

unsigned char i,j;

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

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

;

}

/ 函數功能:步進電機轉動延時,延時越長,轉速越慢

void motor_delay(void)

{

unsigned int i;

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

;

}

/

函數功能:步進電機正轉

void forward( )

{

P0=0xfc;

motor_delay();

P0=0xf6;

motor_delay();

P0=0xf3;

motor_delay();

P0=0xf9;

motor_delay();

}

/

函數功能:步進電機反轉

void backward()

{

P0=0xfc;

motor_delay();

P0=0xf9;

motor_delay();

P0=0xf3;

motor_delay();

P0=0xf6;

motor_delay();

} //P0口低四位脈沖1100 //P0口低四位脈沖0110 //P0口低四位脈沖0011 //P0口低四位脈沖1001 //P0口低四位脈沖1100 //P0口低四位脈沖1001 //P0口低四位脈沖0011 //P0口低四位脈沖0110 / / /

/

函數功能:步進電機停轉

/

void stop(void)

{

P0=0xff ; //停止輸出脈沖

}

/

函數功能:主函數

/

void main(void)

{

TMOD=0x01; //使用定時器T0的模式1

EA=1; //開總中斷

ET0=1; //定時器T0中斷允許

TR0=1; //啟動定時器T0

TH0=(65536-500)/256; //定時器T0賦初值,每計數200次(217微秒)發送一次中斷請求

TL0=(65536-500)%256; //定時器T0賦初值

keyval=0; //按鍵值初始化為0,什么也不做

ID=0;

while(1)

{

switch(keyval) //根據按鍵值keyval選擇待執行的功能 {

case 1:forward(); //按鍵S1按下,正轉

break;

case 2:backward(); //按鍵S2按下 ,反轉

break;

case 3:stop(); //按鍵S3按下,停轉

break;

}

}

}

/

函數功能:定時器T0的中斷服務子程序

/

void Time0_serve(void) interrupt 1 using 1

{

TR0=0; //關閉定時器T0

if((P1&0xf0)!=0xf0) //第一次檢測到有鍵按下

{

delay(); //延時一段時間再去檢測

if((P1&0xf0)!=0xf0) //確實有鍵按下

{

if(S1==0) //按鍵S1被按下

keyval=1;

if(S2==0) //按鍵S2被按下

keyval=2;

if(S3==0) //按鍵S3被按下

keyval=3;

}

}

TH0=(65536-200)/256; //定時器T0的高8位賦初值

TL0=(65536-200)%256; //定時器T0的低8位賦初值

TR0=1; //啟動定時器T0

}

*實例77:矩陣式鍵盤按鍵值的數碼管顯示實驗

#include //包含51單片機寄存器定義的頭文件

sbit P14=P1^4; //將P14位定義為P1.4引腳

sbit P15=P1^5; //將P15位定義為P1.5引腳

sbit P16=P1^6; //將P16位定義為P1.6引腳

sbit P17=P1^7; //將P17位定義為P1.7引腳

unsigned char code Tab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //數字0~9的段碼

unsigned char keyval; //定義變量儲存按鍵值

/ 函數功能:數碼管動態掃描延時

/ void led_delay(void)

{

unsigned char j;

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

;

}

/ 函數功能:按鍵值的數碼管顯示子程序

/ void display(unsigned char k)

{

P2=0xbf; //點亮數碼管DS6

P0=Tab[k/10]; //顯示十位

led_delay(); //動態掃描延時

P2=0x7f; //點亮數碼管DS7

P0=Tab[k%10]; //顯示個位

led_delay(); //動態掃描延時

}

/ 函數功能:軟件延時子程序

/ void delay20ms(void)

{

unsigned char i,j;

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

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

;

}

/ 函數功能:主函數

/ void main(void)

{

EA=1; //開總中斷

ET0=1; //定時器T0中斷允許

TMOD=0x01; //使用定時器T0的模式1

TH0=(65536-500)/256; //定時器T0的高8位賦初值

TL0=(65536-500)%256; //定時器T0的高8位賦初值

TR0=1; //啟動定時器T0

keyval=0x00; //按鍵值初始化為0

while(1) //無限循環

{

display(keyval); //調用按鍵值的數碼管顯示子程序

}

}

/ 函數功能:定時器0的中斷服務子程序,進行鍵盤掃描,判斷鍵位

/

void time0_interserve(void) interrupt 1 using 1 //定時器T0的中斷編號為1,使用第一組寄存器

{

TR0=0; //關閉定時器T0

P1=0xf0; //所有行線置為低電平“0”,所有列線置為高電平“1”

if((P1&0xf0)!=0xf0) //列線中有一位為低電平“0”,說明有鍵按下 delay20ms(); //延時一段時間、軟件消抖

if((P1&0xf0)!=0xf0) //確實有鍵按下

{

P1=0xfe; //第一行置為低電平“0”(P1.0輸出低電平“0”)

if(P14==0) //如果檢測到接P1.4引腳的列線為低電平“0” keyval=1; //可判斷是S1鍵被按下

if(P15==0) //如果檢測到接P1.5引腳的列線為低電平“0”

keyval=2; //可判斷是S2鍵被按下

if(P16==0)

“0”

keyval=3;

if(P17==0)

“0”

keyval=4;

P1=0xfd;

“0”)

if(P14==0)

keyval=5;

if(P15==0)

“0”

keyval=6;

if(P16==0)

“0”

keyval=7;

if(P17==0)

“0”

keyval=8;

P1=0xfb;

“0”)

if(P14==0)

keyval=9;

if(P15==0)

keyval=10;

if(P16==0)

keyval=11;

if(P17==0)

keyval=12;

P1=0xf7;

“0”)

if(P14==0) //如果檢測到接P1.6引腳的列線為低電平 //可判斷是S3鍵被按下 //如果檢測到接P1.7引腳的列線為低電平 //可判斷是S4鍵被按下 //第二行置為低電平“0”(P1.1輸出低電平 //如果檢測到接P1.4引腳的列線為低電平“0” //可判斷是S5鍵被按下 //如果檢測到接P1.5引腳的列線為低電平 //可判斷是S6鍵被按下 //如果檢測到接P1.6引腳的列線為低電平 //可判斷是S7鍵被按下 //如果檢測到接P1.7引腳的列線為低電平 //可判斷是S8鍵被按下 //第三行置為低電平“0”(P1.2輸出低電平//如果檢測到接P1.4引腳的列線為低電平“0” //可判斷是S9鍵被按下 //如果檢測到接P1.5引腳的列線為低電平“0” //可判斷是S10鍵被按下 //如果檢測到接P1.6引腳的列線為低電平“0” //可判斷是S11鍵被按下 //如果檢測到接P1.7引腳的列線為低電平“0” //可判斷是S12鍵被按下 //第四行置為低電平“0”(P1.3輸出低電平//如果檢測到接P1.4引腳的列線為低電平“0”

keyval=13; //可判斷是S13鍵被按下

if(P15==0) //如果檢測到接P1.5引腳的列線為低電平“0” keyval=14; //可判斷是S14鍵被按下

if(P16==0) //如果檢測到接P1.6引腳的列線為低電平“0” keyval=15; //可判斷是S15鍵被按下

if(P17==0) //如果檢測到接P1.7引腳的列線為低電平“0” keyval=16; //可判斷是S16鍵被按下 }

TR0=1; //開啟定時器T0

TH0=(65536-500)/256; //定時器T0的高8位賦初值 TL0=(65536-500)%256; //定時器T0的高8位賦初值 }

*實例78:矩陣式鍵盤按鍵音

#include //包含51單片機寄存器定義的頭文件 sbit sound=P3^7; //將sound位定義為P3.7

/ 函數功能:蜂鳴器發聲延時約120ms

void delay_sound(void) {

unsigned char i; for(i=0;i<250;i++) ; }

/ 函數功能:軟件延時子程序約20ms

void delay20ms(void) {

unsigned char i,j; for(i=0;i<100;i++) for(j=0;j<60;j++) ; }

/ 函數功能:主函數

void main(void)

/ / /

{

EA=1; //開總中斷

ET0=1; //定時器T0中斷允許

TMOD=0x01; //使用定時器T0的模式1

TH0=(65536-500)/256; //定時器T0的高8位賦初值

TL0=(65536-500)%256; //定時器T0的高8位賦初值

TR0=1; //啟動定時器T0

while(1) //無限循環,等待鍵盤按下

;

}

/ 函數功能:定時器0的中斷服務子程序,進行鍵盤掃描,判斷鍵位

/

void time0_interserve(void) interrupt 1 using 1 //定時器T0的中斷編號為1,使用第一組寄存器

{

unsigned char i;

TR0=0; //關閉定時器T0

P1=0xf0; //所有行線置為低電平“0”,所有列線置為高電平“1”

if((P1&0xf0)!=0xf0) //列線中有一位為低電平“0”,說明有鍵按下 delay20ms(); //延時一段時間、軟件消抖

if((P1&0xf0)!=0xf0) //確實有鍵按下

{

for(i=0;i<200;i++) //讓P3.7引腳電平不斷取反輸出音頻

{

sound=0;

delay_sound();

sound=1;

delay_sound();

}

}

TR0=1; //開啟定時器T0

TH0=(65536-500)/256; //定時器T0的高8位賦初值

TL0=(65536-500)%256; //定時器T0的高8位賦初值 }

*實例79:簡易電子

#include //包含51單片機寄存器定義的頭文件

sbit P14=P1^4; //將P14位定義為P1.4引腳

sbit P15=P1^5; //將P15位定義為P1.5引腳

sbit P16=P1^6; //將P16位定義為P1.6引腳

sbit P17=P1^7; //將P17位定義為P1.7引腳

unsigned char keyval; //定義變量儲存按鍵值

sbit sound=P3^7; //將sound位定義為P3.7

unsigned int C; //全局變量,儲存定時器的定時常數

unsigned int f; //全局變量,儲存音階的頻率

//以下是C調低音的音頻宏定義

#define l_dao 262 //將“l_dao”宏定義為低音“1”的頻率262Hz #define l_re 286 //將“l_re”宏定義為低音“2”的頻率286Hz #define l_mi 311 //將“l_mi”宏定義為低音“3”的頻率311Hz #define l_fa 349 //將“l_fa”宏定義為低音“4”的頻率349Hz #define l_sao 392 //將“l_sao”宏定義為低音“5”的頻率392Hz #define l_la 440 //將“l_a”宏定義為低音“6”的頻率440Hz #define l_xi 494 //將“l_xi”宏定義為低音“7”的頻率494Hz

//以下是C調中音的音頻宏定義

#define dao 523 //將“dao”宏定義為中音“1”的頻率523Hz #define re 587 //將“re”宏定義為中音“2”的頻率587Hz #define mi 659 //將“mi”宏定義為中音“3”的頻率659Hz #define fa 698 //將“fa”宏定義為中音“4”的頻率698Hz #define sao 784 //將“sao”宏定義為中音“5”的頻率784Hz #define la 880 //將“la”宏定義為中音“6”的頻率880Hz #define xi 987 //將“xi”宏定義為中音“7”的頻率53

//以下是C調高音的音頻宏定義

#define h_dao 1046 //將“h_dao”宏定義為高音“1”的頻率1046Hz #define h_re 1174 //將“h_re”宏定義為高音“2”的頻率1174Hz #define h_mi 1318 //將“h_mi”宏定義為高音“3”的頻率1318Hz #define h_fa 1396 //將“h_fa”宏定義為高音“4”的頻率1396Hz #define h_sao 1567 //將“h_sao”宏定義為高音“5”的頻率1567Hz #define h_la 1760 //將“h_la”宏定義為高音“6”的頻率1760Hz #define h_xi 1975 //將“h_xi”宏定義為高音“7”的頻率1975Hz / 函數功能:軟件延時子程序

/ void delay20ms(void)

{

unsigned char i,j;

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

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

;

}

/

函數功能:節拍的延時的基本單位,延時200ms

/

void delay()

{

unsigned char i,j;

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

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

;

}

/

函數功能:輸出音頻

入口參數:F

/

void Output_Sound(void)

{

C=(46083/f) 10; //計算定時常數

TH0=(8192-C)/32; //可證明這是13位計數器TH0高8位的賦初值方法 TL0=(8192-C)%32; //可證明這是13位計數器TL0低5位的賦初值方法 TR0=1; //開定時T0

delay(); //延時200ms,播放音頻

TR0=0; //關閉定時器

sound=1; //關閉蜂鳴器

keyval=0xff; //播放按鍵音頻后,將按鍵值更改,停止播放 }

/

函數功能:主函數

/

void main(void)

{

EA=1; //開總中斷

ET0=1; //定時器T0中斷允許

ET1=1; //定時器T1中斷允許

TR1=1; //定時器T1啟動,開始鍵盤掃描

TMOD=0x10; //分別使用定時器T1的模式1,T0的模式0 TH1=(65536-500)/256; //定時器T1的高8位賦初值

TL1=(65536-500)%256; //定時器T1的高8位賦初值

while(1) //無限循環

{

switch(keyval)

{

case 1:f=dao; //如果第1個鍵按下,將中音1的頻率賦給f

Output_Sound(); //轉去計算定時常數 break;

case 2:f=l_xi; //如果第2個鍵按下,將低音7的頻率賦給f

Output_Sound(); //轉去計算定時常數 break;

case 3:f=l_la; //如果第3個鍵按下,將低音6的頻率賦給f

Output_Sound(); //轉去計算定時常數 break;

case 4:f=l_sao; //如果第4個鍵按下,將低音5的頻率賦給f

Output_Sound(); //轉去計算定時常數 break;

case 5:f=sao; //如果第5個鍵按下,將中音5的頻率賦給f

Output_Sound(); //轉去計算定時常數 break;

case 6:f=fa; //如果第6個鍵按下,將中音4的頻率賦給f

Output_Sound(); //轉去計算定時常數 break;

case 7:f=mi; //如果第7個鍵按下,將中音3的頻率賦給f

Output_Sound(); //轉去計算定時常數 break;

case 8:f=re; //如果第8個鍵按下,將中音2的頻率賦給f

Output_Sound(); //轉去計算定時常數 break;

case 9:f=h_re; //如果第9個鍵按下,將高音2的頻率賦給f

Output_Sound(); //轉去計算定時常數 break;

case 10:f=h_dao; //如果第10個鍵按下,將高音1的頻率賦給f

Output_Sound(); //轉去計算定時常數 break;

case 11:f=xi; //如果第11個鍵按下,將中音7的頻率賦給f

Output_Sound(); //轉去計算定時常數 break;

case 12:f=la; //如果第12個鍵按下,將中音6的頻率賦給f

Output_Sound(); //轉去計算定時常數 break;

case 13:f=h_la; //如果第13個鍵按下,將高音6的頻率賦給f

Output_Sound(); //轉去計算定時常數 break;

case 14:f=h_sao; //如果第14個鍵按下,將高音5的頻率賦給f

Output_Sound(); //轉去計算定時常數 break;

case 15:f=h_fa; //如果第15個鍵按下,將高音4的頻率賦給f

Output_Sound(); //轉去計算定時常數 break;

case 16:f=h_mi; //如果第16個鍵按下,將高音3的頻率賦給f

Output_Sound(); //轉去計算定時常數 break;

}

}

}

/ 函數功能:定時器T0的中斷服務子程序,使P3.7引腳輸出音頻方波

/

void Time0_serve(void ) interrupt 1 using 1

{

TH0=(8192-C)/32; //可證明這是13位計數器TH0高8位的賦初值方法

TL0=(8192-C)%32; //可證明這是13位計數器TL0低5位的賦初值方法

sound=!sound; //將P3.7引腳取反,輸出音頻方波

}

/ 函數功能:定時器T1的中斷服務子程序,進行鍵盤掃描,判斷鍵位

/

void time1_serve(void) interrupt 3 using 2 //定時器T1的中斷編號為3,使用第2組寄存器 {

TR1=0; //關閉定時器T0

P1=0xf0; //所有行線置為低電平“0”,所有列線置為高電平“1” if((P1&0xf0)!=0xf0) //列線中有一位為低電平“0”,說明有鍵按下 { delay20ms(); //延時一段時間、軟件消抖 if((P1&0xf0)!=0xf0) { P1=0xfe; 輸出低電平“0”) if(P14==0) 為低電平“0” keyval=1; if(P15==0) 線為低電平“0” keyval=2; if(P16==0) 線為低電平“0” keyval=3; if(P17==0) 線為低電平“0” keyval=4; P1=0xfd; 輸出低電平“0”) if(P14==0) 低電平“0” keyval=5; if(P15==0) 線為低電平“0” keyval=6; if(P16==0) 線為低電平“0” keyval=7; if(P17==0) 線為低電平“0” keyval=8; P1=0xfb; 輸出低電平“0”)

//確實有鍵按下 //第一行置為低電平“0”(P1.0 //如果檢測到接P1.4引腳的列線 //可判斷是S1鍵被按下 //如果檢測到接P1.5引腳的列 //可判斷是S2鍵被按下 //如果檢測到接P1.6引腳的列 //可判斷是S3鍵被按下 //如果檢測到接P1.7引腳的列 //可判斷是S4鍵被按下 //第二行置為低電平“0”(P1.1 //如果檢測到接P1.4引腳的列線為 //可判斷是S5鍵被按下 //如果檢測到接P1.5引腳的列 //可判斷是S6鍵被按下 //如果檢測到接P1.6引腳的列 //可判斷是S7鍵被按下 //如果檢測到接P1.7引腳的列 //可判斷是S8鍵被按下 //第三行置為低電平“0”(P1.2

if(P14==0) //如果檢測到接P1.4引腳的列線為低電平“0”

keyval=9; //可判斷是S9鍵被按下

if(P15==0) //如果檢測到接P1.5引腳的列線為低電平“0”

keyval=10; //可判斷是S10鍵被按下

if(P16==0) //如果檢測到接P1.6引腳的列線為低電平“0”

keyval=11; //可判斷是S11鍵被按下

if(P17==0) //如果檢測到接P1.7引腳的列線為低電平“0”

keyval=12; //可判斷是S12鍵被按下

P1=0xf7; //第四行置為低電平“0”(P1.3輸出低電平“0”)

if(P14==0) //如果檢測到接P1.4引腳的列線為低電平“0”

keyval=13; //可判斷是S13鍵被按下

if(P15==0) //如果檢測到接P1.5引腳的列線為低電平“0”

keyval=14; //可判斷是S14鍵被按下

if(P16==0) //如果檢測到接P1.6引腳的列線為低電平“0”

keyval=15; //可判斷是S15鍵被按下

if(P17==0) //如果檢測到接P1.7引腳的列線為低電平“0”

keyval=16; //可判斷是S16鍵被按下 }

}

TR1=1; //開啟定時器T1

TH1=(65536-500)/256; //定時器T1的高8位賦初值

TL1=(65536-500)%256; //定時器T1的高8位賦初值

}

*實例80:矩陣式鍵盤實現的電子密碼鎖

#include //包含51單片機寄存器定義的頭文件

sbit P14=P1^4; //將P14位定義為P1.4引腳

sbit P15=P1^5; //將P15位定義為P1.5引腳

sbit P16=P1^6; //將P16位定義為P1.6引腳

sbit P17=P1^7; //將P17位定義為P1.7引腳

sbit sound=P3^7; //將sound位定義為P3.7

unsigned char keyval; //儲存按鍵值

/ 函數功能:延時輸出音頻

/ void delay(void)

{

unsigned char i;

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

;

}

/ 函數功能:軟件延時子程序

void delay20ms(void)

{

unsigned char i,j;

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

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

;

}

/ 函數功能:主函數

void main(void)

{

unsigned char D[ ]={0,8,0,8,7,4,11}; //設定密碼

EA=1; //開總中斷

ET0=1; //定時器T0中斷允許 TMOD=0x01; //使用定時器T0的模式1

TH0=(65536-500)/256; //定時器T0的高8位賦初值

TL0=(65536-500)%256; //定時器T0的高8位賦初值

TR0=1; //啟動定時器T0

keyval=0xff; //按鍵值初始化

while(keyval!=D[0]) //第一位密碼輸入不正確,等待

;

while(keyval!=D[1]) //第二位密碼輸入不正確,等待

;

while(keyval!=D[2]) //第三位密碼輸入不正確,等待

;

while(keyval!=D[3]) //第四位密碼輸入不正確,等待 / /

;

while(keyval!=D[4]) //第五位密碼輸入不正確,等待

;

while(keyval!=D[5]) //第六位密碼輸入不正確,等待

;

while(keyval!=D[6]) //沒有輸入“OK”,等待

;

P3=0xfe; //P3.0引腳輸出低電平,點亮LED

}

/ 函數功能:定時器0的中斷服務子程序,進行鍵盤掃描,判斷鍵位

/

void time0_interserve(void) interrupt 1 using 1 //定時器T0的中斷編號為1,使用第一組寄存器

{

unsigned char i;

TR0=0; //關閉定時器T0

P1=0xf0; //所有行線置為低電平“0”,所有列線置為高電平“1”

if((P1&0xf0)!=0xf0) //列線中有一位為低電平“0”,說明有鍵按下 delay20ms(); //延時一段時間、軟件消抖

if((P1&0xf0)!=0xf0) //確實有鍵按下

{

P1=0xfe; //第一行置為低電平“0”(P1.0輸出低電平“0”)

if(P14==0) //如果檢測到接P1.4引腳的列線為低電平“0” keyval=1; //可判斷是S1鍵被按下

if(P15==0) //如果檢測到接P1.5引腳的列線為低電平“0”

keyval=2; //可判斷是S2鍵被按下

if(P16==0) //如果檢測到接P1.6引腳的列線為低電平“0”

keyval=3; //可判斷是S3鍵被按下

if(P17==0) //如果檢測到接P1.7引腳的列線為低電平“0”

keyval=4; //可判斷是S4鍵被按下

P1=0xfd; //第二行置為低電平“0”(P1.1輸出低電平“0”)

if(P14==0) //如果檢測到接P1.4引腳的列線為低電平“0” keyval=5; //可判斷是S5鍵被按下

if(P15==0) //如果檢測到接P1.5引腳的列線為低電平“0”

keyval=6; //可判斷是S6鍵被按下

if(P16==0) //如果檢測到接P1.6引腳的列線為低電平“0”

keyval=7; //可判斷是S7鍵被按下

if(P17==0) //如果檢測到接P1.7引腳的列線為低電平“0”

keyval=8; //可判斷是S8鍵被按下

P1=0xfb; //第三行置為低電平“0”(P1.2輸出低電平“0”)

if(P14==0) //如果檢測到接P1.4引腳的列線為低電平“0” keyval=9; //可判斷是S9鍵被按下

if(P15==0) //如果檢測到接P1.5引腳的列線為低電平“0” keyval=0; //可判斷是S10鍵被按下

if(P16==0) //如果檢測到接P1.6引腳的列線為低電平“0” keyval=11; //可判斷是S11鍵被按下

if(P17==0) //如果檢測到接P1.7引腳的列線為低電平“0” keyval=12; //可判斷是S12鍵被按下

P1=0xf7; //第四行置為低電平“0”(P1.3輸出低電平“0”)

if(P14==0) //如果檢測到接P1.4引腳的列線為低電平“0”

keyval=13; //可判斷是S13鍵被按下

if(P15==0) //如果檢測到接P1.5引腳的列線為低電平“0”

keyval=14; //可判斷是S14鍵被按下

if(P16==0) //如果檢測到接P1.6引腳的列線為低電平“0”

keyval=15; //可判斷是S15鍵被按下

if(P17==0) //如果檢測到接P1.7引腳的列線為低電平“0”

keyval=16; //可判斷是S16鍵被按下 for(i=0;i<200;i++) //讓P3.7引腳電平不斷取反輸出音頻

{

sound=0;

delay();

sound=1;

delay();

}

}

TR0=1; //開啟定時器T0

TH0=(65536-500)/256; //定時器T0的高8位賦初值

TL0=(65536-500)%256; //定時器T0的高8位賦初值

審核編輯:湯梓紅


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • led
    led
    +關注

    關注

    237

    文章

    22550

    瀏覽量

    646856
  • 單片機
    +關注

    關注

    6008

    文章

    44087

    瀏覽量

    623080
  • 寄存器
    +關注

    關注

    30

    文章

    5164

    瀏覽量

    118135
  • 編程
    +關注

    關注

    88

    文章

    3450

    瀏覽量

    92706

原文標題:【建議收藏】單片機編程實例80例大全

文章出處:【微信號:gkongbbs,微信公眾號:工控論壇】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    單片機編程實例大全

    單片機編程實例大全
    發表于 08-17 17:09

    單片機開發實例大全》--單片機系統開發典型實例系列

    `《單片機開發實例大全》--單片機系統開發典型實例系列`
    發表于 08-17 22:02

    單片機技術資料匯總】

    單片機編程實例大全 188頁5 十天學會單片機100實例 192頁6
    發表于 08-18 15:54

    4 單片機編程實例大全 188頁

    4 單片機編程實例大全
    發表于 12-05 20:38

    單片機C語言編程寶典大全,初學必備

    單片機C語言編程寶典大全,初學必備:1. 51單片機入門教程 2. 初學者適用:單片機C語言實例
    發表于 04-18 10:04

    單片機編程實例大全

    發表于 09-10 12:47 ?59次下載

    單片機編程實例大全

    發表于 09-23 11:57 ?15次下載

    單片機編程實例大全WELL

    發表于 04-13 14:56 ?31次下載

    單片機編程實例大全

    發表于 01-02 20:38 ?2次下載

    51單片機編程實例大全 188例

    發表于 11-06 14:47 ?77次下載

    單片機編程實例大全

    發表于 04-13 10:22 ?333次下載

    單片機編程實例大全

    受錄了多種實例單片機編程,非常實用,與大家分享。
    發表于 03-23 17:06 ?65次下載

    單片機開發實例大全

    單片機開發實例大全
    發表于 10-13 12:12 ?74次下載
    <b class='flag-5'>單片機</b>開發<b class='flag-5'>實例</b><b class='flag-5'>大全</b>

    單片機編程100實例大全

    本文檔的主要內容詳細介紹的是單片機編程實例100例大全。
    發表于 01-19 17:41 ?144次下載
    <b class='flag-5'>單片機</b>的<b class='flag-5'>編程</b>100<b class='flag-5'>實例</b><b class='flag-5'>大全</b>

    C語言單片機等待詢問_51單片機編程實例大全(下部)

    學習單片機// 實例 1:用單片機控制第一個燈亮#include //包含 51單片機寄存器定義的頭文件void main(void){ P1=0xfe; //P1=1111 1110
    發表于 11-21 09:51 ?10次下載
    C語言<b class='flag-5'>單片機</b>等待詢問_51<b class='flag-5'>單片機</b><b class='flag-5'>編程</b><b class='flag-5'>實例</b><b class='flag-5'>大全</b>(下部)
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>