*實例1:
使用P3口流水點亮8位LED
#include<reg51.h> //包含單片機寄存器的頭文件 / 函數(shù)功能:延時一段時間
void delay(void)
{
unsigned char i,j;
for(i=0;i<250;i++)
for(j=0;j<250;j++)
;
}
/ 函數(shù)功能:主函數(shù)
void main(void)
{
while(1)
{
P3=0xfe; //第一個燈亮
delay(); //調(diào)用延時函數(shù)
P3=0xfd; //第二個燈亮
delay(); //調(diào)用延時函數(shù)
P3=0xfb; //第三個燈亮
delay(); //調(diào)用延時函數(shù)
P3=0xf7; //第四個燈亮
delay(); //調(diào)用延時函數(shù)
P3=0xef; //第五個燈亮
delay(); //調(diào)用延時函數(shù)
P3=0xdf; //第六個燈亮
delay(); //調(diào)用延時函數(shù)
P3=0xbf; //第七個燈亮
delay(); //調(diào)用延時函數(shù)
P3=0x7f; //第八個燈亮
delay(); //調(diào)用延時函數(shù)
} / /
}
*實例2:
通過對P3口地址的操作流水點亮8位LED
#include<reg51.h> //包含單片機寄存器的頭文件
sfr x=0xb0; //P3口在存儲器中的地址是b0H, 通過sfr可定義8051內(nèi)核單片機
//的所有內(nèi)部8位特殊功能寄存器,對地址x的操作也就是對P1口的操作
/
函數(shù)功能:延時一段時間
/
void delay(void)
{
unsigned char i,j;
for(i=0;i<250;i++)
for(j=0;j<250;j++)
; //利用循環(huán)等待若干機器周期,從而延時一段時間
}
/
函數(shù)功能:主函數(shù)
/
void main(void)
{
while(1)
{
x=0xfe; //第一個燈亮
delay(); //調(diào)用延時函數(shù)
x=0xfd; //第二個燈亮
delay(); //調(diào)用延時函數(shù)
x=0xfb; //第三個燈亮
delay(); //調(diào)用延時函數(shù)
x=0xf7; //第四個燈亮
delay(); //調(diào)用延時函數(shù)
x=0xef; //第五個燈亮
delay(); //調(diào)用延時函數(shù)
x=0xdf; //第六個燈亮
delay(); //調(diào)用延時函數(shù)
x=0xbf; //第七個燈亮
delay(); //調(diào)用延時函數(shù)
x=0x7f; //第八個燈亮
delay(); //調(diào)用延時函數(shù)
}
}
*實例3:用不同數(shù)據(jù)類型控制燈閃爍時間
#include<reg51.h> //包含單片機寄存器的頭文件
/
函數(shù)功能:用整形數(shù)據(jù)延時一段時間
/
void int_delay(void) //延時一段較長的時間
{
unsigned int m; //定義無符號整形變量,雙字節(jié)數(shù)據(jù),值域為0~65535 for(m=0;m<36000;m++)
; //空操作
}
/
函數(shù)功能:用字符型數(shù)據(jù)延時一段時間
/
void char_delay(void) //延時一段較短的時間
{
unsigned char i,j; //定義無符號字符型變量,單字節(jié)數(shù)據(jù),值域0~255 for(i=0;i<200;i++)
for(j=0;j<180;j++)
; //空操作
}
/
函數(shù)功能:主函數(shù)
/
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<reg51.h> //包含51單片機寄存器定義的頭文件
void main(void)
{
P1=0xfe; //P1=1111 1110B,即P1.0輸出低電平
}
*實例5:用單片機控制一個燈閃爍:認(rèn)識單片機的工作頻率 #include<reg51.h> //包含單片機寄存器的頭文件
/
函數(shù)功能:延時一段時間
/
void delay(void) //兩個void意思分別為無需返回值,沒有參數(shù)傳遞 {
unsigned int i; //定義無符號整數(shù),最大取值范圍65535 for(i=0;i<20000;i++) //做20000次空循環(huán)
; //什么也不做,等待一個機器周期
}
/ 函數(shù)功能:主函數(shù) (C語言規(guī)定必須有也只能有1個主函數(shù)) / void main(void)
{
while(1) //無限循環(huán)
{
P1=0xfe; //P1=1111 1110B, P1.0輸出低電平
delay(); //延時一段時間
P1=0xff; //P1=1111 1111B, P1.0輸出高電平
delay(); //延時一段時間
}
}
*實例6:將 P1口狀態(tài)分別送入P0、P2、P3口:認(rèn)識I/O口
的引腳功能
#include<reg51.h> //包含單片機寄存器的頭文件
/ 函數(shù)功能:主函數(shù) (C語言規(guī)定必須有也只能有1個主函數(shù)) /
void main(void)
{
while(1) //無限循環(huán)
{
P1=0xff; // P1=1111 1111B,熄滅LED
P0=P1; // 將 P1口狀態(tài)送入P0口
P2=P1; // 將 P1口狀態(tài)送入P2口
P3=P1; // 將 P1口狀態(tài)送入P3口
}
}
*實例7:用P0口、P1 口分別顯示加法和減法運算結(jié)果 #include<reg51.h>
void main(void)
{
unsigned char m,n;
m=43; //即十進制數(shù)2x16+11=43
n=60; //即十進制數(shù)3x16+12=60
P1=m+n; //P1=103=0110 0111B,結(jié)果P1.3、P1.4、P1.7 口的燈被點亮 P0=n-m; //P0=17=0001 0001B,結(jié)果P0.0、P0.4的燈被熄滅 }
*實例8:用P0、P1口顯示乘法運算結(jié)果
#include<reg51.h> //包含單片機寄存器的頭文件
void main(void)
{
unsigned char m,n;
unsigned int s;
m=64;
n=71;
s=m n; //s=64 71=4544,需要16位二進制數(shù)表示,高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進制數(shù)H3 16+H2必然等于17,即4544除以256的商
//低8位16進制數(shù)H1 16+H0必然等于192,即4544除以256的余數(shù)
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口顯示除法運算結(jié)果
#include<reg51.h> //包含單片機寄存器的頭文件
void main(void)
{
P1=36/5; //求整數(shù)
P0=((36%5) 10)/5; //求小數(shù)
while(1)
; //無限循環(huán)防止程序“跑飛”
}
*實例10:用自增運算控制P0口8位LED流水花樣
#include<reg51.h> //包含單片機寄存器的頭文件
/
函數(shù)功能:延時一段時間
/
void delay(void)
{
unsigned int i;
for(i=0;i<20000;i++)
;
}
/ 函數(shù)功能?:主函數(shù)
/ void main(void)
{
unsigned char i;
for(i=0;i<255;i++) //注意i的值不能超過255
{
P0=i; //將i的值送P0口
delay(); //調(diào)用延時函數(shù)
}
}
*實例11:用P0口顯示邏輯'與'運算結(jié)果 #include<reg51.h> //包含單片機寄存器的頭文件 void main(void)
{
P0=(4>0)&&(9>0xab);//將邏輯運算結(jié)果送P0口
while(1)
; //設(shè)置無限循環(huán),防止程序“跑飛”
}
*實例12:用P0口顯示條件運算結(jié)果
#include<reg51.h> //包含單片機寄存器的頭文件 void main(void)
{
P0=(8>4)?8:4;//將條件運算結(jié)果送P0口,P0=8=0000 1000B while(1)
; //設(shè)置無限循環(huán),防止程序“跑飛”
}
*實例13:用P0口顯示按位'異或'運算結(jié)果 #include<reg51.h> //包含單片機寄存器的頭文件 void main(void)
{
P0=0xa2^0x3c;//將條件運算結(jié)果送P0口,P0=8=0000 1000B while(1)
; //設(shè)置無限循環(huán),防止程序“跑飛”
}
*實例16:用P0顯示左移運算結(jié)果
#include<reg51.h> //包含單片機寄存器的頭文件 void main(void)
{
P0=0x3b<<2;//將左移運算結(jié)果送P0口,P0=1110 1100B=0xec while(1)
; //無限循環(huán),防止程序“跑飛”
}
*實例17:'萬能邏輯電路'實驗
#include<reg51.h> //包含單片機寄存器的頭文件
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; //將邏輯運算結(jié)果賦給F
;
}
}
*實例18:用右移運算流水點亮P1口8位LED #include<reg51.h> //包含單片機寄存器的頭文件
/
函數(shù)功能:延時一段時間
/
void delay(void)
{
unsigned int n;
for(n=0;n<30000;n++)
;
}
/
函數(shù)功能:主函數(shù)
/
void main(void)
{
unsigned char i;
while(1)
{
P1=0xff;
delay();
for(i=0;i<8;i++)//設(shè)置循環(huán)次數(shù)為8
{
P1=P1>>1; //每次循環(huán)P1的各二進位右移1位,高位補0 delay(); //調(diào)用延時函數(shù)
}
}
}
*實例19:用if語句控制P0口8位LED的流水方向 #include<reg51.h> //包含單片機寄存器的頭文件
sbit S1=P1^4; //將S1位定義為P1.4
sbit S2=P1^5; //將S2位定義為P1.5
/
函數(shù)功能:主函數(shù)
/
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的點亮狀態(tài) #include<reg51.h> //包含單片機寄存器的頭文件
sbit S1=P1^4; //將S1位定義為P1.4
/
函數(shù)功能:延時一段時間
/
void delay(void)
{
unsigned int n;
for(n=0;n<10000;n++)
;
}
/
函數(shù)功能:主函數(shù)
/
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: //缺省值,關(guān)閉所有LED P0=0xff; }
*實例21:用for語句控制蜂鳴器鳴笛次數(shù)
#include<reg51.h> //包含單片機寄存器的頭文件 sbit sound=P3^7; //將sound位定義為P3.7 / 函數(shù)功能:延時形成1600Hz音頻
/ void delay1600(void)
{
unsigned char n;
for(n=0;n<100;n++)
;
}
/ 函數(shù)功能:延時形成800Hz音頻
/ void delay800(void)
{
unsigned char n;
for(n=0;n<200;n++)
;
}
/ 函數(shù)功能:主函數(shù)
/ 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<reg51.h> //包含單片機寄存器的頭文件 / 函數(shù)功能:延時約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++)
;
}
/
函數(shù)功能:主函數(shù)
/
void main(void)
{
unsigned char i;
while(1) //無限循環(huán)
{
i=0; //將i初始化為0
while(i<0xff) //當(dāng)i小于0xff(255)時執(zhí)行循環(huán)體 {
P0=i; //將i送P0口顯示
delay60ms(); //延時
i++; //i自增1
}
}
}
*實例23:用do-while語句控制P0口8位LED流水點亮 #include<reg51.h> //包含單片機寄存器的頭文件
/
函數(shù)功能:延時約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++)
;
}
/
函數(shù)功能:主函數(shù)
/
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); //無限循環(huán),使8位LED循環(huán)流水點亮
*實例24:用字符型數(shù)組控制P0口8位LED流水點亮 #include<reg51.h> //包含單片機寄存器的頭文件
/
函數(shù)功能:延時約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++)
;
}
/
函數(shù)功能:主函數(shù)
/
void main(void)
{
unsigned char i;
unsigned char code Tab[ ]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //定義無符號字符型數(shù)組
while(1)
{
for(i=0;i<8;i++)
{
P0=Tab[i];//依次引用數(shù)組元素,并將其送P0口顯示
delay60ms();//調(diào)用延時函數(shù)
}
}
}
*實例25:用P0口顯示字符串常量
#include<reg51.h> //包含單片機寄存器的頭文件
/
函數(shù)功能:延時約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++)
;
}
/
函數(shù)功能:主函數(shù)
/
void main(void)
{
unsigned char str[]={'Now,Temperature is :'}; //將字符串賦給字符型全部元素賦值
unsigned char i;
while(1)
{
i=0; //將i初始化為0,從第一個元素開始顯示
while(str[i]!='\0') //只要沒有顯示到結(jié)束標(biāo)志'\0'
{
P0=str[i]; //將第i個字符送到P0口顯示
delay150ms(); //調(diào)用150ms延時函數(shù)
i++; //指向下一個待顯字符
}
}
}
*實例26:用P0 口顯示指針運算結(jié)果
#include<reg51.h>
void main(void)
{
unsigned char p1, p2; //定義無符號字符型指針變量p1,p2 unsigned char i,j; //定義無符號字符型數(shù)據(jù)
i=25; //給i賦初值25
j=15;
p1=&i; //使指針變量指向i ,對指針初始化
p2=&j; //使指針變量指向j ,對指針初始化
P0= p1+ p2; // p1+ p2相當(dāng)于i+j,所以P0=25+15=40=0x28
//則P0=0010 1000B,結(jié)果P0.3、P0.5引腳LED熄滅,其余點亮 while(1)
; //無限循環(huán),防止程序“跑飛”
}
*實例27:用指針數(shù)組控制P0口8位LED流水點亮 #include<reg51.h>
/
函數(shù)功能:延時約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++)
;
}
/
函數(shù)功能:主函數(shù)
/
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; //定義無符號字符型數(shù)據(jù)
while(1)
{
for(i=0;i<8;i++)
{
P0= p[i];
delay150ms();
}
}
}
*實例28:用數(shù)組的指針控制P0 口8 位LED流水點亮 #include<reg51.h>
/
函數(shù)功能:延時約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++)
;
}
/
函數(shù)功能:主函數(shù)
/
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; //將數(shù)組首地址存入指針p
while(1)
{
for(i=0;i<32;i++) //共32個流水燈控制碼
{
P0= (p+i); // (p+i)的值等于a[i]
}
delay150ms(); //調(diào)用150ms延時函數(shù) } }
*實例29:用P0 、P1口顯示整型函數(shù)返回值 #include<reg51.h>
/ 函數(shù)功能:計算兩個無符號整數(shù)的和
/ unsigned int sum(int a,int b)
{
unsigned int s;
s=a+b;
return (s);
}
/ 函數(shù)功能:主函數(shù)
/ void main(void)
{
unsigned z;
z=sum(2008,2009);
P1=z/256; //取得z的高8位
P0=z%256; //取得z的低8位
while(1)
;
}
*實例30:用有參函數(shù)控制P0口8位LED流水速度 #include<reg51.h>
/ 函數(shù)功能:延時一段時間
/ void delay(unsigned char x)
{
unsigned char m,n;
for(m=0;m<x;m++)
for(n=0;n<200;n++)
;
}
/
函數(shù)功能:主函數(shù)
/
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:用數(shù)組作函數(shù)參數(shù)控制流水花樣
#include<reg51.h>
/
函數(shù)功能:延時約150ms
/
void delay(void)
{
unsigned char m,n;
for(m=0;m<200;m++)
for(n=0;n<250;n++)
;
}
/
函數(shù)功能:流水點亮P0口8位LED
/
void led_flow(unsigned char a[8])
{
unsigned char i;
for(i=0;i<8;i++)
{
P0=a[i];
delay();
}
}
/
函數(shù)功能:主函數(shù)
/
void main(void)
{
unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; //流水燈控制碼
led_flow(Tab);
}
*實例32:用指針作函數(shù)參數(shù)控制P0口8位LED流水點亮 #include<reg51.h>
/
函數(shù)功能:延時約150ms
/
void delay(void)
{
unsigned char m,n;
for(m=0;m<200;m++)
for(n=0;n<250;n++)
;
}
/
函數(shù)功能:流水點亮P0口8位LED
/
void led_flow(unsigned char p) //形參為無符號字符型指針
{
unsigned char i;
while(1)
{
i=0; //將i置為0,指向數(shù)組第一個元素
while( (p+i)!='\0') //只要沒有指向數(shù)組的結(jié)束標(biāo)志
{
P0= (p+i);// 取的指針?biāo)缸兞浚〝?shù)組元素)的值,送P0口 delay(); //調(diào)用延時函數(shù)
i++; //指向下一個數(shù)組元素
}
}
}
/
函數(shù)功能:主函數(shù)
/
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:用函數(shù)型指針控制P1口燈花樣
#include<reg51.h> //包含51單片機寄存器定義的頭文件
unsigned char code Tab[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; //流水燈控制碼,該數(shù)組被定義為全局變量
/
函數(shù)功能:延時約150ms
/ void delay(void)
{
unsigned char m,n;
for(m=0;m<200;m++)
for(n=0;n<250;n++)
;
}
/ 函數(shù)功能:流水燈左移
/ void led_flow(void)
{
unsigned char i;
for(i=0;i<8;i++) //8位控制碼
{
P0=Tab[i];
delay();
}
}
/ 函數(shù)功能:主函數(shù)
/ void main(void)
{
void ( p)(void); //定義函數(shù)型指針,所指函數(shù)無參數(shù),無返回值 p=led_flow; //將函數(shù)的入口地址賦給函數(shù)型指針p
while(1)
( p)(); //通過函數(shù)的指針p調(diào)用函數(shù)led_flow()
}
*實例34:用指針數(shù)組作為函數(shù)的參數(shù)顯示多個字符串 #include<reg51.h> //包含51單片機寄存器定義的頭文件
unsigned char code str1[ ]='Temperature is tested by DS18B20';//C語言中,字符串是作為字符數(shù)組來處理的
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個字符串的字符型指針數(shù)組
/ 函數(shù)功能:延時約150ms
/ void delay(void)
{
unsigned char m,n;
for(m=0;m<200;m++)
for(n=0;n<250;n++)
;
}
/ 函數(shù)功能:流水點亮P0口8位LED
/ void led_display(unsigned char x[ ]) //形參必須為指針數(shù)組
{
unsigned char i,j;
for(i=0;i<4;i++) //有4個字符串要顯示
{
j=0; //指向待顯字符串的第0號元素
while( (x[i]+j)!='\0') //只要第i個字符串的第j號元素不是結(jié)束標(biāo)志 {
P0= (x[i]+j); //取得該元素值送到P0口顯示
delay(); //調(diào)用延時函數(shù)
j++; //指向下一個元素
}
}
}
/ 函數(shù)功能:主函數(shù)
/ void main(void)
{
unsigned char i;
while(1)
{
for(i=0;i<4;i++)
led_display(p); //將指針數(shù)組名作實際參數(shù)傳遞
}
}
*實例35:字符函數(shù)ctype.h應(yīng)用舉例
#include<reg51.h> //包含51單片機寄存器定義的頭文件 #include<ctype.h>
void main(void)
{
while(1)
{
P3=isalpha('_')?0xf0:0x0f;//條件運算,若'_'是英文字母,P3=0xf0 }
}
*實例36:內(nèi)部函數(shù)intrins.h應(yīng)用舉例
#include<reg51.h> //包含51單片機寄存器定義的頭文件 #include<intrins.h> //包含函數(shù)isalpha()聲明的頭文件 / 函數(shù)功能:延時約150ms
/ void delay(void)
{
unsigned char m,n;
for(m=0;m<200;m++)
for(n=0;n<250;n++)
;
}
/ 函數(shù)功能:主函數(shù)
/ void main(void)
{
P3=0xfe; //P3=1111 1110B
while(1)
{
P3=_crol_(P3,1);// 將P3的二進制位循環(huán)左移1位后再賦給P3 delay(); //調(diào)用延時函數(shù)
}
}
*實例37:標(biāo)準(zhǔn)函數(shù)stdlib.h應(yīng)用舉例
#include<reg51.h> //包含51單片機寄存器定義的頭文件 #include<stdlib.h> //包含函數(shù)isalpha()聲明的頭文件 / 函數(shù)功能:延時約150ms
/ void delay(void)
{
unsigned char m,n;
for(m=0;m<200;m++)
for(n=0;n<250;n++)
;
}
/ 函數(shù)功能:主函數(shù)
/ void main(void)
{
unsigned char i;
while(1)
{
for(i=0;i<10;i++) //產(chǎn)生10個隨機數(shù)
{
P3=rand()/160; //將產(chǎn)生的隨機數(shù)縮小160倍后送P3顯示 delay();
}
}
}
*實例38:字符串函數(shù)string.h應(yīng)用舉例
#include<reg51.h> //包含51單片機寄存器定義的頭文件 #include<string.h> //包含函數(shù)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); //比較兩個字符串,并將結(jié)果存入i
if(i==0) //str1=str2
P3=0x00;
else
if(i<0) //str1<str2
P3=0xf0;
else //str1>str2
P3=0x0f;
while(1)
; //防止程序“跑飛”
}
*實例39:宏定義應(yīng)用舉例2
#include<reg51.h> //包含51單片機寄存器定義的頭文件
# define F(a,b) (a)+(a) (b)/256+(b) //帶參數(shù)的宏定義,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:宏定義應(yīng)用舉例2
#include<AT89X51.h>
#include<ctype.h>
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:宏定義應(yīng)用舉例3
#include<reg51.h> //包含51單片機寄存器定義的頭文件
#define MAX 100 //將MAX宏定義為字符串100
void main(void)
{
#if MAX>80 //如果字符串100大于80
P3=0xf0; //P3口低四位LED點亮
#else
P3=0x0f; //否則,P3口高四位LED點亮
#endif //結(jié)束本次編譯
}
/ 中斷、定時器 中斷、定時器
中斷、定時器 中斷、定時器 /
*實例42:用定時器T0查詢方式P2口8位控制LED閃爍
#include<reg51.h> // 包含51單片機寄存器定義的頭文件
/
函數(shù)功能:主函數(shù)
/ 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)//無限循環(huán)等待查詢
{
while(TF0==0)
;
TF0=0;
P2=~P2;
TH0=(65536-46083)/256; //定時器T0的高8位賦初值 TL0=(65536-46083)%256; //定時器T0的高8位賦初值 }
}
*實例43:用定時器T1查詢方式控制單片機發(fā)出1KHz音頻 #include<reg51.h> // 包含51單片機寄存器定義的頭文件 sbit sound=P3^7; //將sound位定義為P3.7引腳
/ 函數(shù)功能:主函數(shù)
/ 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)//無限循環(huán)等待查詢
{
while(TF1==0)
;
TF1=0;
sound=~sound; //將P3.7引腳輸出電平取反
TH1=(65536-921)/256; //定時器T0的高8位賦初值 TL1=(65536-921)%256; //定時器T0的高8位賦初值 }
}
*實例44:將計數(shù)器T0計數(shù)的結(jié)果送P1口8位LED顯示 #include<reg51.h> // 包含51單片機寄存器定義的頭文件 sbit S=P3^4; //將S位定義為P3.4引腳
/ 函數(shù)功能:主函數(shù)
/ 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)//無限循環(huán)等待查詢
{
while(TF0==0) //如果未計滿就等待
{
if(S==0) //按鍵S按下接地,電平為0
P1=TL0; //計數(shù)器TL0加1后送P1口顯示
}
TF0=0; //計數(shù)器溢出后,將TF0清0
}
}
*實例45:用定時器T0的中斷控制1位LED閃爍 #include<reg51.h> // 包含51單片機寄存器定義的頭文件
sbit D1=P2^0; //將D1位定義為P2.0引腳
/ 函數(shù)功能:主函數(shù)
/ 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)//無限循環(huán)等待中斷
;
}
/ 函數(shù)功能:定時器T0的中斷服務(wù)程序
/ void Time0(void) interrupt 1 using 0 //“interrupt”聲明函數(shù)為中斷服務(wù)函數(shù) //其后的1為定時器T0的中斷編號;0表示使用第0組工作寄存器
{
D1=~D1; //按位取反操作,將P2.0引腳輸出電平取反
TH0=(65536-46083)/256; //定時器T0的高8位重新賦初值
TL0=(65536-46083)%256; //定時器T0的高8位重新賦初值
}
*實例46:用定時器T0的中斷實現(xiàn)長時間定時
#include<reg51.h> // 包含51單片機寄存器定義的頭文件
sbit D1=P2^0; //將D1位定義為P2.0引腳
unsigned char Countor; //設(shè)置全局變量,儲存定時器T0中斷次數(shù)
/ 函數(shù)功能:主函數(shù)
/ 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開始累計中斷次數(shù)
while(1)//無限循環(huán)等待中斷
;
}
/ 函數(shù)功能:定時器T0的中斷服務(wù)程序
/ void Time0(void) interrupt 1 using 0 //“interrupt”聲明函數(shù)為中斷服務(wù)函數(shù)
//其后的1為定時器T0的中斷編號;0表示使用第0組工作寄存器
{
Countor++; //中斷次數(shù)自加1
if(Countor==20) //若累計滿20次,即計時滿1s
{
D1=~D1; //按位取反操作,將P2.0引腳輸出電平取反
Countor=0; //將Countor清0,重新從0開始計數(shù)
}
TH0=(65536-46083)/256; //定時器T0的高8位重新賦初值
TL0=(65536-46083)%256; //定時器T0的高8位重新賦初值
}
*實例47:用定時器T1中斷控制兩個LED以不同周期閃爍 #include<reg51.h> // 包含51單片機寄存器定義的頭文件
sbit D1=P2^0; //將D1位定義為P2.0引腳
sbit D2=P2^1; //將D2位定義為P2.1引腳
unsigned char Countor1; //設(shè)置全局變量,儲存定時器T1中斷次數(shù)
unsigned char Countor2; //設(shè)置全局變量,儲存定時器T1中斷次數(shù)
/ 函數(shù)功能:主函數(shù)
/ 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開始累計中斷次數(shù)
Countor2=0; //從0開始累計中斷次數(shù)
while(1)//無限循環(huán)等待中斷
;
}
/ 函數(shù)功能:定時器T1的中斷服務(wù)程序
/ void Time1(void) interrupt 3 using 0 //“interrupt”聲明函數(shù)為中斷服務(wù)函數(shù) //其后的3為定時器T1的中斷編號;0表示使用第0組工作寄存器
{
Countor1++; //Countor1自加1
Countor2++; //Countor2自加1
if(Countor1==2) //若累計滿2次,即計時滿100ms
{
D1=~D1; //按位取反操作,將P2.0引腳輸出電平取反 Countor1=0; //將Countor1清0,重新從0開始計數(shù)
}
if(Countor2==8) //若累計滿8次,即計時滿400ms
{
D2=~D2; //按位取反操作,將P2.1引腳輸出電平取反 Countor2=0; //將Countor1清0,重新從0開始計數(shù)
}
TH1=(65536-46083)/256; //定時器T1的高8位重新賦初值
TL1=(65536-46083)%256; //定時器T1的高8位重新賦初值
}
*實例48:用計數(shù)器T1的中斷控制蜂鳴器發(fā)出1KHz音頻 #include<reg51.h> // 包含51單片機寄存器定義的頭文件
sbit sound=P3^7; //將sound位定義為P3.7引腳
/ 函數(shù)功能:主函數(shù)
/ 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)//無限循環(huán)等待中斷
;
}
/ 函數(shù)功能:定時器T1的中斷服務(wù)程序
/ void Time1(void) interrupt 3 using 0 //“interrupt”聲明函數(shù)為中斷服務(wù)函數(shù) {
sound=~sound;
TH1=(65536-921)/256; //定時器T1的高8位重新賦初值
TL1=(65536-921)%256; //定時器T1的高8位重新賦初值
}
*實例49:用定時器T0的中斷實現(xiàn)'渴望'主題曲的播放 #include<reg51.h> //包含51單片機寄存器定義的頭文件
sbit sound=P3^7; //將sound位定義為P3.7
unsigned int C; //儲存定時器的定時常數(shù)
//以下是C調(diào)低音的音頻宏定義
#define l_dao 262 //將“l(fā)_dao”宏定義為低音“1”的頻率262Hz #define l_re 286 //將“l(fā)_re”宏定義為低音“2”的頻率286Hz #define l_mi 311 //將“l(fā)_mi”宏定義為低音“3”的頻率311Hz #define l_fa 349 //將“l(fā)_fa”宏定義為低音“4”的頻率349Hz #define l_sao 392 //將“l(fā)_sao”宏定義為低音“5”的頻率392Hz #define l_la 440 //將“l(fā)_a”宏定義為低音“6”的頻率440Hz #define l_xi 494 //將“l(fā)_xi”宏定義為低音“7”的頻率494Hz //以下是C調(diào)中音的音頻宏定義
#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 //將“l(fā)a”宏定義為中音“6”的頻率880Hz
#define xi 987 //將“xi”宏定義為中音“7”的頻率523H //以下是C調(diào)高音的音頻宏定義
#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 /
函數(shù)功能:1個延時單位,延時200ms
/
void delay()
{
unsigned char i,j;
for(i=0;i<250;i++)
for(j=0;j<250;j++)
;
}
/
函數(shù)功能:主函數(shù)
/
void main(void)
{
unsigned char i,j;
//以下是《渴望》片頭曲的一段簡譜
unsigned int code f[]={re,mi,re,dao,l_la,dao,l_la, //每行對應(yīng)一小節(jié)音符 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作為音符的結(jié)束標(biāo)志
//以下是簡譜中每個音符的節(jié)拍
//'4'對應(yīng)4個延時單位,'2'對應(yīng)2個延時單位,'1'對應(yīng)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位計數(shù)器)
while(1) //無限循環(huán)
{
i=0; //從第1個音符f[0]開始播放
while(f[i]!=0xff) //只要沒有讀到結(jié)束標(biāo)志就繼續(xù)播放 {
C=460830/f[i];
TH0=(8192-C)/32; //可證明這是13位計數(shù)器TH0高8位的賦初值方法
TL0=(8192-C)%32; //可證明這是13位計數(shù)器TL0低5位的賦初值方法
TR0=1; //啟動定時器T0
for(j=0;j<JP[i];j++) //控制節(jié)拍數(shù)
delay(); //延時1個節(jié)拍單位
TR0=0; //關(guān)閉定時器T0
i++; //播放下一個音符
}
}
}
/ 函數(shù)功能:定時器T0的中斷服務(wù)子程序,使P3.7引腳輸出音頻的方波 / void Time0(void ) interrupt 1 using 1
{
sound=!sound; //將P3.7引腳輸出電平取反,形成方波
TH0=(8192-C)/32; //可證明這是13位計數(shù)器TH0高8位的賦初值方法 TL0=(8192-C)%32; //可證明這是13位計數(shù)器TL0低5位的賦初值方法 }
*實例50-1:輸出50個矩形脈沖
#include<reg51.h> //包含51單片機寄存器定義的頭文件
sbit u=P1^4; //將u位定義為P1.4
/
函數(shù)功能:延時約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++)
;
}
/
函數(shù)功能:主函數(shù)
/
void main(void)
{
unsigned char i;
u=1; //初始化輸出高電平
for(i=0;i<50;i++) //輸出50個矩形脈沖
{
u=1;
delay30ms();
u=0;
delay30ms();
}
while(1)
; //無限循環(huán),防止程序“跑飛”
}
*實例50-2:計數(shù)器T0統(tǒng)計外部脈沖數(shù)
#include<reg51.h> //包含51單片機寄存器定義的頭文件
/
函數(shù)功能:主函數(shù)
/
void main(void)
{
TMOD=0x06; // TMOD=0000 0110B,使用計數(shù)器T0的模式2 EA=1; //開總中斷
ET0=0; //不使用定時器T0的中斷
TR0=1; //啟動T0
TH0=0; //計數(shù)器T0高8位賦初值
TL0=0; //計數(shù)器T0低8位賦初值
while(1) //無限循環(huán),不停地將TL0計數(shù)結(jié)果送P1口
P1=TL0;
}
*實例51-2:定時器T0的模式2測量正脈沖寬度
#include<reg51.h> //包含51單片機寄存器定義的頭文件
sbit ui=P3^2; //將ui位定義為P3.0(INT0)引腳,表示輸入電壓
/
函數(shù)功能:主函數(shù)
/
void main(void)
{
TMOD=0x0a; // TMOD=0000 1010B,使用定時器T0的模式2,GATE置1 EA=1; //開總中斷
ET0=0; //不使用定時器T0的中斷
TR0=1; //啟動T0
TH0=0; //計數(shù)器T0高8位賦初值
TL0=0; //計數(shù)器T0低8位賦初值
while(1) //無限循環(huán),不停地將TL0計數(shù)結(jié)果送P1口 {
while(ui==0) //INT0為低電平,T0不能啟動
;
TL0=0; //INT0為高電平,啟動T0計時,所以將TL0清0 while(ui==1) //在INT0高電平期間,等待,計時
;
P1=TL0; //將計時結(jié)果送P1口顯示
}
}
*實例52:用定時器T0控制輸出高低寬度不同的矩形波 #include<reg51.h> //包含51單片機寄存器定義的頭文件
sbit u=P3^0; //將u位定義為P3.0,從該引腳輸出矩形脈沖 unsigned char Countor; //設(shè)置全局變量,儲存負(fù)跳變累計數(shù) / 函數(shù)功能:延時約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++)
;
}
/
函數(shù)功能:主函數(shù)
/ void main(void)
{
unsigned char i;
EA=1; //開放總中斷
EX0=1; //允許使用外中斷
IT0=1; //選擇負(fù)跳變來觸發(fā)外中斷
Countor=0;
for(i=0;i<100;i++) //輸出100個負(fù)跳變
{
u=1;
delay30ms();
u=0;
delay30ms();
}
while(1)
; //無限循環(huán), 防止程序跑飛
}
/ 函數(shù)功能:外中斷T0的中斷服務(wù)程序
void int0(void) interrupt 0 using 0 //外中斷0的中斷編號為0 /
{
Countor++;
P1=Countor;
}
*實例53:用外中斷0的中斷方式進行數(shù)據(jù)采集 #include<reg51.h> //包含51單片機寄存器定義的頭文件
sbit S=P3^2; //將S位定義為P3.2,
/
函數(shù)功能:主函數(shù)
/
void main(void)
{
EA=1; //開放總中斷
EX0=1; //允許使用外中斷
IT0=1; //選擇負(fù)跳變來觸發(fā)外中斷
P1=0xff;
while(1)
; //無限循環(huán), 防止程序跑飛
}
/ 函數(shù)功能:外中斷T0的中斷服務(wù)程序
/ void int0(void) interrupt 0 using 0 //外中斷0的中斷編號為0
{
P1=~P1; //每產(chǎn)生一次中斷請求,P1取反一次。
}
*實例54-1:輸出負(fù)脈寬為200微秒的方波
#include<reg51.h> //包含51單片機寄存器定義的頭文件
sbit u=P1^4; //將u位定義為P1.4
/
函數(shù)功能:主函數(shù)
/
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) //無限循環(huán),等待中斷
;
}
/ 函數(shù)功能:定時器T0的中斷服務(wù)程序
/ void Time0(void) interrupt 1 using 0 //'interrupt'聲明函數(shù)為中斷服務(wù)函數(shù) {
u=~u; //將P1.4引腳輸出電平取反,產(chǎn)生方波
}
*實例54-2:測量負(fù)脈沖寬度
#include<reg51.h> //包含51單片機寄存器定義的頭文件
sbit u=P3^2; //將u位定義為P3.2
/
函數(shù)功能:主函數(shù)
/
void main(void)
{
TMOD=0x02; //TMOD=0000 0010B,使用定時器T0的模式2
EA=1; //開放總中斷
EX0=1; //允許使用外中斷
IT0=1; //選擇負(fù)跳變來觸發(fā)外中斷
ET0=1; //允許定時器T0中斷
TH0=0; //定時器T0賦初值0
TL0=0; //定時器T0賦初值0
TR0=0; //先關(guān)閉T0
while(1)
; //無限循環(huán), 不停檢測輸入負(fù)脈沖寬度
}
/ 函數(shù)功能:外中斷0的中斷服務(wù)程序
/ void int0(void) interrupt 0 using 0 //外中斷0的中斷編號為0
{
TR0=1; //外中斷一到來,即啟動T0計時
TL0=0; //從0開始計時
while(u==0) //低電平時,等待T0計時
;
P1=TL0; //將結(jié)果送P1口顯示
TR0=0; //關(guān)閉T0
}
*實例55:方式0控制流水燈循環(huán)點亮
#include<reg51.h> //包含51單片機寄存器定義的頭文件
#include<intrins.h> //包含函數(shù)_nop_()定義的頭文件
unsigned char code Tab[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};//流水燈控制碼,該數(shù)組被定義為全局變量
sbit P17=P1^7;
/ 函數(shù)功能:延時約150ms
/ void delay(void)
{
unsigned char m,n;
for(m=0;m<200;m++)
for(n=0;n<250;n++)
;
}
/ 函數(shù)功能:發(fā)送一個字節(jié)的數(shù)據(jù)
/ void Send(unsigned char dat)
{
P17=0; //P1.7引腳輸出清0信號,對74LS164清0
_nop_(); //延時一個機器周期
_nop_(); //延時一個機器周期,保證清0完成
P17=1; //結(jié)束對74LS164的清0
SBUF=dat; //將數(shù)據(jù)寫入發(fā)送緩沖器,啟動發(fā)送
while(TI==0) //若沒有發(fā)送完畢,等待
;
TI=0; //發(fā)送完畢,TI被置“1”,需將其清0
}
/
函數(shù)功能:主函數(shù)
/
void main(void)
{
unsigned char i;
SCON=0x00; //SCON=0000 0000B,使串行口工作于方式0 while(1)
{
for(i=0;i<8;i++)
{
Send(Tab[i]); //發(fā)送數(shù)據(jù)
delay(); //延時
}
}
}
*實例56-1:數(shù)據(jù)發(fā)送程序
#include<reg51.h> //包含單片機寄存器的頭文件
unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; //流水燈控制碼,該數(shù)組被定義為全局變量
/ 函數(shù)功能:向PC發(fā)送一個字節(jié)數(shù)據(jù)
/ void Send(unsigned char dat)
{
SBUF=dat;
while(TI==0)
;
TI=0;
}
/ 函數(shù)功能:延時約150ms
void delay(void)
{ /
unsigned char m,n;
for(m=0;m<200;m++)
for(n=0;n<250;n++)
;
}
/ 函數(shù)功能:主函數(shù)
/ 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; //根據(jù)規(guī)定給定時器T1賦初值
TL1=0xfd; //根據(jù)規(guī)定給定時器T1賦初值
TR1=1; //啟動定時器T1
while(1)
{
for(i=0;i<8;i++) //模擬檢測數(shù)據(jù)
{
Send(Tab[i]); //發(fā)送數(shù)據(jù)i
delay(); //50ms發(fā)送一次檢測數(shù)據(jù) }
}
}
*實例56-2:數(shù)據(jù)接收程序
#include<reg51.h> //包含單片機寄存器的頭文件
/ 函數(shù)功能:接收一個字節(jié)數(shù)據(jù)
/ unsigned char Receive(void)
{
unsigned char dat;
while(RI==0) //只要接收中斷標(biāo)志位RI沒有被置“1” ; //等待,直至接收完畢(RI=1)
RI=0; //為了接收下一幀數(shù)據(jù),需將RI清0 dat=SBUF; //將接收緩沖器中的數(shù)據(jù)存于dat
return dat;
}
/
函數(shù)功能:主函數(shù)
/
void main(void)
{
TMOD=0x20; //定時器T1工作于方式2
SCON=0x50; //SCON=0101 0000B,串口工作方式1,允許接收(REN=1) PCON=0x00; //PCON=0000 0000B,波特率9600
TH1=0xfd; //根據(jù)規(guī)定給定時器T1賦初值
TL1=0xfd; //根據(jù)規(guī)定給定時器T1賦初值
TR1=1; //啟動定時器T1
REN=1; //允許接收
while(1)
{
P1=Receive(); //將接收到的數(shù)據(jù)送P1口顯示
}
}
*實例57-1:數(shù)據(jù)發(fā)送程序
#include<reg51.h> //包含單片機寄存器的頭文件
sbit p=PSW^0;
unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; //流水燈控制碼,該數(shù)組被定義為全局變量
/
函數(shù)功能:向PC發(fā)送一個字節(jié)數(shù)據(jù)
/
void Send(unsigned char dat)
{
ACC=dat;
TB8=p;
SBUF=dat;
while(TI==0)
;
TI=0;
}
/ 函數(shù)功能:延時約150ms
/
void delay(void)
{
unsigned char m,n;
for(m=0;m<200;m++)
for(n=0;n<250;n++)
;
}
/ 函數(shù)功能:主函數(shù)
/ 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; //根據(jù)規(guī)定給定時器T1賦初值
TL1=0xfd; //根據(jù)規(guī)定給定時器T1賦初值
TR1=1; //啟動定時器T1
while(1)
{
for(i=0;i<8;i++) //模擬檢測數(shù)據(jù)
{
Send(Tab[i]); //發(fā)送數(shù)據(jù)i
delay(); //50ms發(fā)送一次檢測數(shù)據(jù) }
}
}
*實例57-2:數(shù)據(jù)接收程序
#include<reg51.h> //包含單片機寄存器的頭文件 sbit p=PSW^0;
/ 函數(shù)功能:接收一個字節(jié)數(shù)據(jù)
/ unsigned char Receive(void)
{
unsigned char dat;
while(RI==0) //只要接收中斷標(biāo)志位RI沒有被置'1'
; //等待,直至接收完畢(RI=1)
RI=0; //為了接收下一幀數(shù)據(jù),需將RI清0
ACC=SBUF; //將接收緩沖器中的數(shù)據(jù)存于dat
if(RB8==p)
{
dat=ACC;
return dat;
}
}
/
函數(shù)功能:主函數(shù)
/
void main(void)
{
TMOD=0x20; //定時器T1工作于方式2
SCON=0xd0; //SCON=1101 0000B,串口工作方式1,允許接收(REN=1) PCON=0x00; //PCON=0000 0000B,波特率9600
TH1=0xfd; //根據(jù)規(guī)定給定時器T1賦初值
TL1=0xfd; //根據(jù)規(guī)定給定時器T1賦初值
TR1=1; //啟動定時器T1
REN=1; //允許接收
while(1)
{
P1=Receive(); //將接收到的數(shù)據(jù)送P1口顯示
}
}
*實例58:單片機向PC發(fā)送數(shù)據(jù)
#include<reg51.h> //包含單片機寄存器的頭文件
unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; //流水燈控制碼,該數(shù)組被定義為全局變量
/
函數(shù)功能:向PC發(fā)送一個字節(jié)數(shù)據(jù)
/
void Send(unsigned char dat)
{
SBUF=dat;
while(TI==0)
;
TI=0;
}
/ 函數(shù)功能:延時約150ms
/ void delay(void)
{
unsigned char m,n;
for(m=0;m<200;m++)
for(n=0;n<250;n++)
;
}
/ 函數(shù)功能:主函數(shù)
/
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; //根據(jù)規(guī)定給定時器T1賦初值
TL1=0xfd; //根據(jù)規(guī)定給定時器T1賦初值
TR1=1; //啟動定時器T1
while(1)
{
for(i=0;i<8;i++) //模擬檢測數(shù)據(jù)
{
Send(Tab[i]); //發(fā)送數(shù)據(jù)i
delay(); //150ms發(fā)送一次數(shù)據(jù)
}
}
}
*實例59:單片機接收PC發(fā)出的數(shù)據(jù)
#include<reg51.h> //包含單片機寄存器的頭文件
/ 函數(shù)功能:接收一個字節(jié)數(shù)據(jù)
/
unsigned char Receive(void)
{
unsigned char dat;
while(RI==0) //只要接收中斷標(biāo)志位RI沒有被置“1”
; //等待,直至接收完畢(RI=1)
RI=0; //為了接收下一幀數(shù)據(jù),需將RI清0
dat=SBUF; //將接收緩沖器中的數(shù)據(jù)存于dat
return dat;
}
/
函數(shù)功能:主函數(shù)
/
void main(void)
{
TMOD=0x20; //定時器T1工作于方式2
SCON=0x50; //SCON=0101 0000B,串口工作方式1,允許接收(REN=1)
PCON=0x00; //PCON=0000 0000B,波特率9600
TH1=0xfd; //根據(jù)規(guī)定給定時器T1賦初值
TL1=0xfd; //根據(jù)規(guī)定給定時器T1賦初值
TR1=1; //啟動定時器T1
REN=1; //允許接收
while(1)
{
P1=Receive(); //將接收到的數(shù)據(jù)送P1口顯示
}
}
/ 數(shù)碼管顯示 數(shù)碼管顯示 數(shù)
碼管顯示 數(shù)碼管顯示 /
*實例60:用LED數(shù)碼顯示數(shù)字5
#include<reg51.h> // 包含51單片機寄存器定義的頭文件
void main(void)
{
P2=0xfe; //P2.0引腳輸出低電平,數(shù)碼顯示器接通電源準(zhǔn)備點亮
P0=0x92; //讓P0口輸出數(shù)字'5'的段碼92H
}
*實例61:用LED數(shù)碼顯示器循環(huán)顯示數(shù)字0~9
#include<reg51.h> // 包含51單片機寄存器定義的頭文件
/
函數(shù)功能:延時函數(shù),延時一段時間
/
void delay(void)
{
unsigned char i,j;
for(i=0;i<255;i++)
for(j=0;j<255;j++)
;
}
/
函數(shù)功能:主函數(shù)
/
void main(void)
{
unsigned char i;
unsigned char code
Tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//數(shù)碼管顯示0~9的段碼表,程序運行中當(dāng)數(shù)組值不發(fā)生變化
時,
//前面加關(guān)鍵字code ,可以大大節(jié)約單片機的存儲空間 P2=0xfe; //P2.0引腳輸出低電平,數(shù)碼顯示器DS0接通電源工作
while(1) //無限循環(huán)
{
for(i=0;i<10;i++)
{
P0=Tab[i]; //讓P0口輸出數(shù)字的段碼92H
delay(); //調(diào)用延時函數(shù)
}
}
}
*實例62:用數(shù)碼管慢速動態(tài)掃描顯示數(shù)字'1234' #include<reg51.h> // 包含51單片機寄存器定義的頭文件 void delay(void) //延時函數(shù),延時一段時間
{
unsigned char i,j;
for(i=0;i<250;i++)
for(j=0;j<250;j++)
;
}
void main(void)
{
while(1) //無限循環(huán)
{
P2=0xfe; //P2.0引腳輸出低電平,DS0點亮
P0=0xf9; //數(shù)字1的段碼
delay();
P2=0xfd ; //P2.1引腳輸出低電平,DS1點亮
P0=0xa4; //數(shù)字2的段碼
delay();
P2=0xfb; //P2.2引腳輸出低電平,DS2點亮
P0=0xb0; //數(shù)字3的段碼
delay();
P2=0xf7; //P2.3引腳輸出低電平,DS3點亮
P0=0x99; //數(shù)字4的段碼
delay();
P2=0xff;
}
}
*實例63:用LED數(shù)碼顯示器偽靜態(tài)顯示數(shù)字1234 #include<reg51.h> // 包含51單片機寄存器定義的頭文件 void delay(void) //延時函數(shù),延時約0.6毫秒
{
unsigned char i;
for(i=0;i<200;i++)
;
}
void main(void)
{
while(1) //無限循環(huán)
{
P2=0xfe; //P2.0引腳輸出低電平,DS0點亮
P0=0xf9; //數(shù)字1的段碼
delay();
P2=0xfd ; //P2.1引腳輸出低電平,DS1點亮
P0=0xa4; //數(shù)字2的段碼
delay();
P2=0xfb; //P2.2引腳輸出低電平,DS2點亮
P0=0xb0; //數(shù)字3的段碼
delay();
P2=0xf7; //P2.3引腳輸出低電平,DS3點亮
P0=0x99; //數(shù)字4的段碼
delay();
P2=0xff;
}
}
*實例64:用數(shù)碼管顯示動態(tài)檢測結(jié)果
#include<reg51.h> // 包含51單片機寄存器定義的頭文件
#include<stdlib.h> //包含隨機函數(shù)rand()的定義文件
unsigned char i; //記錄中斷次數(shù)
unsigned int x; //隨機檢測的數(shù)據(jù)
unsigned char code Tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //數(shù)碼管顯示0~9的段碼表
/ 函數(shù)功能:快速動態(tài)掃描延時,延時約0.9毫秒
/
void delay(void)
{
unsigned int i;
for(i=0;i<300;i++)
;
}
/
函數(shù)功能:4位數(shù)的數(shù)碼顯示器顯示
入口參數(shù):k
出口參數(shù):無
/
void display(unsigned int k)
{
P2=0xfe; //即P2=1111 1110B,P2.0引腳輸出低電平,數(shù)碼顯示器DS0接通電源
P0=Tab[k/1000]; //顯示千位
delay();
P2=0xfd ; //即P2=1111 1101B,P2.1引腳輸出低電平,數(shù)碼顯示器DS1接通電源
P0=Tab[(k%1000)/100]; //顯示百位
delay();
P2=0xfb; //即P2=1111 1011B,P2.2引腳輸出低電平,數(shù)碼顯示器DS2接通電源
P0=Tab[(k%100)/10]; //顯示十位
delay();
P2=0xf7; //即P2=1111 0111B ,P2.3引腳輸出低電平,數(shù)碼顯示器DS3接通電源
P0=Tab[k%10];//顯示個位
delay();
P2=0xff; //關(guān)閉所有顯示器
}
void main(void) //主函數(shù)
{
TMOD=0x01; //使用定時器T0
TH0=(65536-46083)/256; //將定時器計時時間設(shè)定為46083×1.085微秒=50000微秒=50毫秒
TL0=(65536-46083)%256;
EA=1; //開啟總中斷
ET0=1; //定時器T0中斷允許
TR0=1; //啟動定時器T0開始運行
while(1)
{
display(x); //調(diào)用檢測結(jié)果的顯示程序
}
}
/
函數(shù)功能:定時器T0的中斷服務(wù)程序
/
void Time0(void) interrupt 1 using 1
{
TR0=0; //關(guān)閉定時器T0
i++; //每來一次中斷,i自加1
if(i==20) //夠20次中斷,即1秒鐘進行一次檢測結(jié)果采樣
{
x=rand()/10; //隨機產(chǎn)生一個從0到32767的整數(shù),再將其除以10,獲得一個隨機4位數(shù),模擬檢測結(jié)果
i=0; //將i清0,重新統(tǒng)計中斷次數(shù)
}
TH0=(65536-46083)/256; //重新給計數(shù)器T0賦初值
TL0=(65536-46083)%256;
TR0=1; //啟動定時器T0
}
*實例65:數(shù)碼秒表設(shè)計
#include<reg51.h> // 包含51單片機寄存器定義的頭文件
unsigned char code Tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //數(shù)碼管顯示0~9的段碼表
unsigned char int_time; //記錄中斷次數(shù)
unsigned char second; //儲存秒
/ 函數(shù)功能:快速動態(tài)掃描延時,延時約0.6毫秒
/
void delay(void)
{
unsigned char i;
for(i=0;i<200;i++)
;
}
/ 函數(shù)功能:顯示秒
入口參數(shù):k
出口參數(shù):無
/
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; //關(guān)閉所有數(shù)碼管
}
void main(void) //主函數(shù)
{
TMOD=0x01; //使用定時器T0
TH0=(65536-46083)/256; //將定時器計時時間設(shè)定為46083×1.085微秒
//=50000微秒=50毫秒
TL0=(65536-46083)%256;
EA=1; //開啟總中斷
ET0=1; //定時器T0中斷允許
TR0=1; //啟動定時器T0開始運行
int_time=0; //中斷次數(shù)初始化
second=0; //秒初始化
while(1)
{
DisplaySecond(second); //調(diào)用秒的顯示子程序
}
}
//
//函數(shù)功能:定時器T0的中斷服務(wù)程序
//
void interserve(void ) interrupt 1 using 1
{
TR0=0; //關(guān)閉定時器T0
int_time ++; //每來一次中斷,中斷次數(shù)int_time自加1
if(int_time==20) //夠20次中斷,即1秒鐘進行一次檢測結(jié)果采樣 {
int_time=0; //中斷次數(shù)清0
second++; //秒加1
if(second==60)
second =0; //秒等于60就返回0
}
TH0=(65536-46083)/256; //重新給計數(shù)器T0賦初值
TL0=(65536-46083)%256;
TR0=1; //啟動定時器T0
}
*實例66:數(shù)碼時鐘設(shè)計
#include<reg51.h> // 包含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 ; //中斷次數(shù)計數(shù)變量
unsigned char second; //秒計數(shù)變量
unsigned char minute; //分鐘計數(shù)變量
unsigned char hour; //小時計數(shù)變量
/////////////////////////////////////////////////////
void delay(void) //延時函數(shù),延時約0.6ms
{
unsigned char j;
for(j=0;j<200;j++)
;
}
/ 函數(shù)功能:顯示秒的子程序
入口參數(shù):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; //關(guān)閉所有數(shù)碼管
}
/ 函數(shù)功能:顯示分鐘的子程序
入口參數(shù):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; //關(guān)閉所有數(shù)碼管
}
/ 函數(shù)功能:顯示小時的子程序
入口參數(shù):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; //關(guān)閉所有數(shù)碼管
/
}
/ 函數(shù)功能:主函數(shù)
/
void main(void)
{
TMOD=0x01; //使用定時器T0
EA=1; //開中斷總允許
ET0=1; //允許T0中斷
TH0=(65536-46083)/256; //定時器高八位賦初值
TL0=(65536-46083)%256; //定時器低八位賦初值
TR0=1;
int_time=0; //中斷計數(shù)變量初始化
second=0; //秒計數(shù)變量初始化
minute=0; //分鐘計數(shù)變量初始化
hour=0; //小時計數(shù)變量初始化
while(1)
{
DisplaySecond(second); //調(diào)用秒顯示子程序 delay();
DisplayMinute(minute); //調(diào)用分鐘顯示子程序 delay();
DisplayHour(hour);
delay();
}
}
/ 函數(shù)功能:定時器T0的中斷服務(wù)子程序
void interserve(void ) interrupt 1 using 1 //using Time0
{
int_time++;
if(int_time==20)
{
int_time=0; //中斷計數(shù)變量清0
second++; //秒計數(shù)變量加1
}
if(second==60)
{
second=0; //如果秒計滿60,將秒計數(shù)變量清0 /
清0
清0
}
} minute++; //分鐘計數(shù)變量加1 if(minute==60) { minute=0; //如果分鐘計滿60,將分鐘計數(shù)變量 hour++; //小時計數(shù)變量加1 } if(hour==24) { hour=0; //如果小時計滿24,將小時計數(shù)變量 } TH0=(65536-46083)/256; //定時器重新賦初值 TL0=(65536-46083)%256;
*實例67:用LED數(shù)碼管顯示計數(shù)器T0的計數(shù)值
#include<reg51.h> //包含51單片機寄存器定義的頭文件
sbit S=P3^2 ; //將S位定義為P3.2引腳
unsigned char Tab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //段碼表
unsigned char x;
/ 函數(shù)功能: 延時約0.6ms
/ void delay(void)
{
unsigned char j;
for(j=0;j<200;j++)
;
}
/ 函數(shù)功能:顯示計數(shù)次數(shù)的子程序
入口參數(shù):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();
}
/
函數(shù)功能:主函數(shù)
/
void main(void)
{
EA=1; //開放總中斷
EX0=1; //允許使用外中斷
IT0=1; //選擇負(fù)跳變來觸發(fā)外中斷
x=0;
while(1)
Display(x);
}
/ 函數(shù)功能:外中斷T0的中斷服務(wù)程序
void int0(void) interrupt 0 using 0 //外中斷0的中斷編號為0
{
x++;
if(x==100)
x=0;
}
*實例68:靜態(tài)顯示數(shù)字“59”
#include<reg51.h> //包含51單片機寄存器定義的頭文件
/ /
函數(shù)功能:主函數(shù)
/
void main(void)
{
P0=0x92; //將數(shù)字5的段碼送P0口
P1=0x90; //將數(shù)字9的段碼送P1口
while(1) //無限循環(huán),防止程序跑飛
;
}
*實例69:無軟件消抖的獨立式鍵盤輸入實驗 #include<reg51.h> // 包含51單片機寄存器定義的頭文件 sbit S1=P1^4; //將S1位定義為P1.4引腳
sbit LED0=P3^0; //將LED0位定義為P3.0引腳 void main(void) //主函數(shù)
{
LED0=0; //P3.0引腳輸出低電平
while(1)
{
if(S1==0) //P1.4引腳輸出低電平,按鍵S1被按下 LED0=!LED0; //P3.0引腳取反
}
}
*實例70:軟件消抖的獨立式鍵盤輸入實驗
#include<reg51.h> // 包含51單片機寄存器定義的頭文件 sbit S1=P1^4; //將S1位定義為P1.4引腳
sbit LED0=P3^0; //將LED0位定義為P3.0引腳
/ 函數(shù)功能:延時約30ms
/ void delay(void)
{
unsigned char i,j;
for(i=0;i<100;i++)
for(j=0;j<100;j++)
;
}
/ 函數(shù)功能:主函數(shù)
/ void main(void) //主函數(shù)
{
LED0=0; //P3.0引腳輸出低電平
while(1)
{
if(S1==0) //P1.4引腳輸出低電平,按鍵S1被按下 {
delay(); //延時一段時間再次檢測
if(S1==0) // 按鍵S1的確被按下
LED0=!LED0; //P3.0引腳取反
}
}
}
*實例71:CPU控制的獨立式鍵盤掃描實驗
#include<reg51.h> //包含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; //儲存按鍵值
/ 函數(shù)功能:流水燈延時
/ void led_delay(void)
{
unsigned char i,j;
for(i=0;i<250;i++)
for(j=0;j<250;j++)
;
}
/ 函數(shù)功能:軟件消抖延時
/
void delay30ms(void)
{
unsigned char i,j;
for(i=0;i<100;i++)
for(j=0;j<100;j++)
;
}
/ 函數(shù)功能:正向流水點亮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();
}
/ 函數(shù)功能:反向流水點亮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();
}
/ 函數(shù)功能:關(guān)閉所有LED
/ void stop(void)
{
P3=0xff;
}
/ 函數(shù)功能:閃爍點亮LED
/ void flash(void)
{
P3=0xff;
led_delay();
P3=0x00;
led_delay();
}
/ 函數(shù)功能:鍵盤掃描子程序
/ 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;
}
}
/ 函數(shù)功能:主函數(shù)
/ void main(void) //主函數(shù)
{
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<reg51.h> //包含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; //儲存按鍵值
/ 函數(shù)功能:流水燈延時
/ void led_delay(void)
{
unsigned char i,j;
for(i=0;i<250;i++)
for(j=0;j<250;j++)
;
}
/ 函數(shù)功能:軟件消抖延時
/ void delay20ms(void)
{
unsigned char i,j;
for(i=0;i<100;i++)
for(j=0;j<60;j++)
;
}
/ 函數(shù)功能:正向流水點亮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();
}
/ 函數(shù)功能:反向流水點亮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();
}
/ 函數(shù)功能:關(guān)閉所有LED
void stop(void)
{
P3=0xff; //關(guān)閉8個LED }
/ 函數(shù)功能:閃爍點亮LED
void flash(void)
{
P3=0xff; //關(guān)閉8個LED
led_delay();
P3=0x00; //點亮8個LED
led_delay();
}
/ 函數(shù)功能:主函數(shù)
void main(void) //主函數(shù)
{
TMOD=0x01; //使用定時器T0的模式1 / / /
EA=1; //開總中斷
ET0=1; //定時器T0中斷允許
TR0=1; //啟動定時器T0
TH0=(65536-1000)/256; //定時器T0賦初值,每計數(shù)200次(217微秒)發(fā)送一次中斷請求
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;
}
}
}
/
函數(shù)功能:定時器T0的中斷服務(wù)子程序
/
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<reg51.h> // 包含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
/ 函數(shù)功能:延時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++)
;
}
/ 函數(shù)功能:延時可調(diào)子程序
入口參數(shù):x
void delay(unsigned char x)
{
unsigned char k;
for(k=0;k<x;k++)
delay20ms();
}
/ 函數(shù)功能:主函數(shù)
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; //默認(rèn)流水燈流水點亮延時20ms×3=60ms / / /
while(1)
{
P3=0xfe; //第一個燈亮
delay(speed); //調(diào)用延時可調(diào)子程序
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;
}
}
/ 函數(shù)功能:定時器T0的中斷服務(wù)子程序,進行鍵盤掃描
/ void intersev(void) interrupt 1 using 1
{
TR0=0; //關(guān)閉定時器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:獨立式鍵盤的按鍵功能擴展:'以一當(dāng)四' #include<reg51.h> // 包含51單片機寄存器定義的頭文件 unsigned char ID; //儲存流水燈的流動速度
sbit S1=P1^4; //位定義S1為P1.4
/ 函數(shù)功能:延時子程序
/ void delay(void) //因為僅對一個按鍵掃描,所以延時時間較長約200ms {
unsigned char i,j;
for(i=0;i<200;i++)
for(j=0;j<100;j++)
;
}
/ 函數(shù)功能:主函數(shù)
/ 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;
}
}
}
/ 函數(shù)功能:定時器T0的中斷服務(wù)子程序,進行鍵盤掃描
/ void intersev(void) interrupt 1 using 1
{
TR0=0; //關(guān)閉定時器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:獨立式鍵盤調(diào)時的數(shù)碼時鐘實驗
#include<reg51.h> // 包含51單片機寄存器定義的頭文件
unsigned char code Tab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //數(shù)字0~9的段碼
unsigned char int_time ; //中斷次數(shù)計數(shù)變量
unsigned char second; //秒計數(shù)變量
unsigned char minute; //分鐘計數(shù)變量
unsigned char hour; //小時計數(shù)變量
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
/ 函數(shù)功能:數(shù)碼管掃描延時
/ void delay(void)
{
unsigned char j;
for(j=0;j<200;j++)
;
}
/ 函數(shù)功能:鍵盤掃描延時
void delay60ms(void)
{
unsigned char i,j;
for(i=0;i<200;i++)
for(j=0;j<100;j++)
;
}
/ 函數(shù)功能:顯示秒
入口參數(shù):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; //關(guān)閉所有數(shù)碼管
}
/ 函數(shù)功能:顯示分鐘
入口參數(shù):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; //關(guān)閉所有數(shù)碼管
}
/ 函數(shù)功能:顯示小時的子程序
入口參數(shù):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; //關(guān)閉所有數(shù)碼管
}
/ 函數(shù)功能:鍵盤掃描
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
}
}
}
}
/ 函數(shù)功能:主函數(shù)
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; //中斷計數(shù)變量初始化
second=0; //秒計數(shù)變量初始化
minute=0; //分鐘計數(shù)變量初始化
hour=0; //小時計數(shù)變量初始化
while(1)
{
DisplaySecond(second); //調(diào)用秒顯示子程序 DisplayMinute(minute); //調(diào)用分鐘顯示子程序 DisplayHour(hour); //調(diào)用小時顯示子程序
}
}
/ 函數(shù)功能:定時器T0的中斷服務(wù)子程序
/ /
void interserve(void ) interrupt 1 using 1 //using Time0
{
TR0=0; //關(guān)閉定時器T0
int_time++; //中斷次數(shù)加1
if(int_time==20) //如果中斷次數(shù)滿20
{
int_time=0; //中斷計數(shù)變量清0
second++; //秒計數(shù)變量加1
}
if(second==60) //如果秒計滿60
{
second=0; //如果秒計滿60,將秒計數(shù)變量清0 minute++; //分鐘計數(shù)變量加1
}
if(minute==60) //如果分鐘計滿60
{
minute=0; //如果分鐘計滿60,將分鐘計數(shù)變量清0 hour++; //小時計數(shù)變量加1
}
if(hour==24) //如果小時計滿24
{
hour=0; //如果小時計滿24,將小時計數(shù)變量清0 }
key_scan(); //執(zhí)行鍵盤掃描
TH0=(65536-46083)/256; //定時器T0高四位賦值
TL0=(65536-46083)%256; //定時器T0低四位賦值
TR0=1; //啟動定時器T0
}
*實例76:獨立式鍵盤控制步進電機實驗
#include<reg51.h> //包含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; //儲存功能標(biāo)號
/
函數(shù)功能:軟件消抖延時(約50ms)
/
void delay(void)
{
unsigned char i,j;
for(i=0;i<150;i++)
for(j=0;j<100;j++)
;
}
/ 函數(shù)功能:步進電機轉(zhuǎn)動延時,延時越長,轉(zhuǎn)速越慢
void motor_delay(void)
{
unsigned int i;
for(i=0;i<2000;i++)
;
}
/
函數(shù)功能:步進電機正轉(zhuǎn)
void forward( )
{
P0=0xfc;
motor_delay();
P0=0xf6;
motor_delay();
P0=0xf3;
motor_delay();
P0=0xf9;
motor_delay();
}
/
函數(shù)功能:步進電機反轉(zhuǎn)
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 / / /
/
函數(shù)功能:步進電機停轉(zhuǎn)
/
void stop(void)
{
P0=0xff ; //停止輸出脈沖
}
/
函數(shù)功能:主函數(shù)
/
void main(void)
{
TMOD=0x01; //使用定時器T0的模式1
EA=1; //開總中斷
ET0=1; //定時器T0中斷允許
TR0=1; //啟動定時器T0
TH0=(65536-500)/256; //定時器T0賦初值,每計數(shù)200次(217微秒)發(fā)送一次中斷請求
TL0=(65536-500)%256; //定時器T0賦初值
keyval=0; //按鍵值初始化為0,什么也不做
ID=0;
while(1)
{
switch(keyval) //根據(jù)按鍵值keyval選擇待執(zhí)行的功能 {
case 1:forward(); //按鍵S1按下,正轉(zhuǎn)
break;
case 2:backward(); //按鍵S2按下 ,反轉(zhuǎn)
break;
case 3:stop(); //按鍵S3按下,停轉(zhuǎn)
break;
}
}
}
/
函數(shù)功能:定時器T0的中斷服務(wù)子程序
/
void Time0_serve(void) interrupt 1 using 1
{
TR0=0; //關(guān)閉定時器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:矩陣式鍵盤按鍵值的數(shù)碼管顯示實驗
#include<reg51.h> //包含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}; //數(shù)字0~9的段碼
unsigned char keyval; //定義變量儲存按鍵值
/ 函數(shù)功能:數(shù)碼管動態(tài)掃描延時
/ void led_delay(void)
{
unsigned char j;
for(j=0;j<200;j++)
;
}
/ 函數(shù)功能:按鍵值的數(shù)碼管顯示子程序
/ void display(unsigned char k)
{
P2=0xbf; //點亮數(shù)碼管DS6
P0=Tab[k/10]; //顯示十位
led_delay(); //動態(tài)掃描延時
P2=0x7f; //點亮數(shù)碼管DS7
P0=Tab[k%10]; //顯示個位
led_delay(); //動態(tài)掃描延時
}
/ 函數(shù)功能:軟件延時子程序
/ void delay20ms(void)
{
unsigned char i,j;
for(i=0;i<100;i++)
for(j=0;j<60;j++)
;
}
/ 函數(shù)功能:主函數(shù)
/ 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) //無限循環(huán)
{
display(keyval); //調(diào)用按鍵值的數(shù)碼管顯示子程序
}
}
/ 函數(shù)功能:定時器0的中斷服務(wù)子程序,進行鍵盤掃描,判斷鍵位
/
void time0_interserve(void) interrupt 1 using 1 //定時器T0的中斷編號為1,使用第一組寄存器
{
TR0=0; //關(guān)閉定時器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<reg51.h> //包含51單片機寄存器定義的頭文件 sbit sound=P3^7; //將sound位定義為P3.7
/ 函數(shù)功能:蜂鳴器發(fā)聲延時約120ms
void delay_sound(void) {
unsigned char i; for(i=0;i<250;i++) ; }
/ 函數(shù)功能:軟件延時子程序約20ms
void delay20ms(void) {
unsigned char i,j; for(i=0;i<100;i++) for(j=0;j<60;j++) ; }
/ 函數(shù)功能:主函數(shù)
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) //無限循環(huán),等待鍵盤按下
;
}
/ 函數(shù)功能:定時器0的中斷服務(wù)子程序,進行鍵盤掃描,判斷鍵位
/
void time0_interserve(void) interrupt 1 using 1 //定時器T0的中斷編號為1,使用第一組寄存器
{
unsigned char i;
TR0=0; //關(guān)閉定時器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<reg51.h> //包含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; //全局變量,儲存定時器的定時常數(shù)
unsigned int f; //全局變量,儲存音階的頻率
//以下是C調(diào)低音的音頻宏定義
#define l_dao 262 //將“l(fā)_dao”宏定義為低音“1”的頻率262Hz #define l_re 286 //將“l(fā)_re”宏定義為低音“2”的頻率286Hz #define l_mi 311 //將“l(fā)_mi”宏定義為低音“3”的頻率311Hz #define l_fa 349 //將“l(fā)_fa”宏定義為低音“4”的頻率349Hz #define l_sao 392 //將“l(fā)_sao”宏定義為低音“5”的頻率392Hz #define l_la 440 //將“l(fā)_a”宏定義為低音“6”的頻率440Hz #define l_xi 494 //將“l(fā)_xi”宏定義為低音“7”的頻率494Hz
//以下是C調(diào)中音的音頻宏定義
#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 //將“l(fā)a”宏定義為中音“6”的頻率880Hz #define xi 987 //將“xi”宏定義為中音“7”的頻率53
//以下是C調(diào)高音的音頻宏定義
#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 / 函數(shù)功能:軟件延時子程序
/ void delay20ms(void)
{
unsigned char i,j;
for(i=0;i<100;i++)
for(j=0;j<60;j++)
;
}
/
函數(shù)功能:節(jié)拍的延時的基本單位,延時200ms
/
void delay()
{
unsigned char i,j;
for(i=0;i<250;i++)
for(j=0;j<250;j++)
;
}
/
函數(shù)功能:輸出音頻
入口參數(shù):F
/
void Output_Sound(void)
{
C=(46083/f) 10; //計算定時常數(shù)
TH0=(8192-C)/32; //可證明這是13位計數(shù)器TH0高8位的賦初值方法 TL0=(8192-C)%32; //可證明這是13位計數(shù)器TL0低5位的賦初值方法 TR0=1; //開定時T0
delay(); //延時200ms,播放音頻
TR0=0; //關(guān)閉定時器
sound=1; //關(guān)閉蜂鳴器
keyval=0xff; //播放按鍵音頻后,將按鍵值更改,停止播放 }
/
函數(shù)功能:主函數(shù)
/
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) //無限循環(huán)
{
switch(keyval)
{
case 1:f=dao; //如果第1個鍵按下,將中音1的頻率賦給f
Output_Sound(); //轉(zhuǎn)去計算定時常數(shù) break;
case 2:f=l_xi; //如果第2個鍵按下,將低音7的頻率賦給f
Output_Sound(); //轉(zhuǎn)去計算定時常數(shù) break;
case 3:f=l_la; //如果第3個鍵按下,將低音6的頻率賦給f
Output_Sound(); //轉(zhuǎn)去計算定時常數(shù) break;
case 4:f=l_sao; //如果第4個鍵按下,將低音5的頻率賦給f
Output_Sound(); //轉(zhuǎn)去計算定時常數(shù) break;
case 5:f=sao; //如果第5個鍵按下,將中音5的頻率賦給f
Output_Sound(); //轉(zhuǎn)去計算定時常數(shù) break;
case 6:f=fa; //如果第6個鍵按下,將中音4的頻率賦給f
Output_Sound(); //轉(zhuǎn)去計算定時常數(shù) break;
case 7:f=mi; //如果第7個鍵按下,將中音3的頻率賦給f
Output_Sound(); //轉(zhuǎn)去計算定時常數(shù) break;
case 8:f=re; //如果第8個鍵按下,將中音2的頻率賦給f
Output_Sound(); //轉(zhuǎn)去計算定時常數(shù) break;
case 9:f=h_re; //如果第9個鍵按下,將高音2的頻率賦給f
Output_Sound(); //轉(zhuǎn)去計算定時常數(shù) break;
case 10:f=h_dao; //如果第10個鍵按下,將高音1的頻率賦給f
Output_Sound(); //轉(zhuǎn)去計算定時常數(shù) break;
case 11:f=xi; //如果第11個鍵按下,將中音7的頻率賦給f
Output_Sound(); //轉(zhuǎn)去計算定時常數(shù) break;
case 12:f=la; //如果第12個鍵按下,將中音6的頻率賦給f
Output_Sound(); //轉(zhuǎn)去計算定時常數(shù) break;
case 13:f=h_la; //如果第13個鍵按下,將高音6的頻率賦給f
Output_Sound(); //轉(zhuǎn)去計算定時常數(shù) break;
case 14:f=h_sao; //如果第14個鍵按下,將高音5的頻率賦給f
Output_Sound(); //轉(zhuǎn)去計算定時常數(shù) break;
case 15:f=h_fa; //如果第15個鍵按下,將高音4的頻率賦給f
Output_Sound(); //轉(zhuǎn)去計算定時常數(shù) break;
case 16:f=h_mi; //如果第16個鍵按下,將高音3的頻率賦給f
Output_Sound(); //轉(zhuǎn)去計算定時常數(shù) break;
}
}
}
/ 函數(shù)功能:定時器T0的中斷服務(wù)子程序,使P3.7引腳輸出音頻方波
/
void Time0_serve(void ) interrupt 1 using 1
{
TH0=(8192-C)/32; //可證明這是13位計數(shù)器TH0高8位的賦初值方法
TL0=(8192-C)%32; //可證明這是13位計數(shù)器TL0低5位的賦初值方法
sound=!sound; //將P3.7引腳取反,輸出音頻方波
}
/ 函數(shù)功能:定時器T1的中斷服務(wù)子程序,進行鍵盤掃描,判斷鍵位
/
void time1_serve(void) interrupt 3 using 2 //定時器T1的中斷編號為3,使用第2組寄存器 {
TR1=0; //關(guān)閉定時器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:矩陣式鍵盤實現(xiàn)的電子密碼鎖
#include<reg51.h> //包含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; //儲存按鍵值
/ 函數(shù)功能:延時輸出音頻
/ void delay(void)
{
unsigned char i;
for(i=0;i<200;i++)
;
}
/ 函數(shù)功能:軟件延時子程序
void delay20ms(void)
{
unsigned char i,j;
for(i=0;i<100;i++)
for(j=0;j<60;j++)
;
}
/ 函數(shù)功能:主函數(shù)
void main(void)
{
unsigned char D[ ]={0,8,0,8,7,4,11}; //設(shè)定密碼
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
}
/ 函數(shù)功能:定時器0的中斷服務(wù)子程序,進行鍵盤掃描,判斷鍵位
/
void time0_interserve(void) interrupt 1 using 1 //定時器T0的中斷編號為1,使用第一組寄存器
{
unsigned char i;
TR0=0; //關(guān)閉定時器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位賦初值
聯(lián)系客服