实验1 单片机IO口应用及数码管显示

1.   单片机驱动蜂鸣器的实验;

a)         说明:Lab51单片机实验板的蜂鸣器连接到单片机的P1.5

b)        基本要求:控制蜂鸣器每2秒响0.5秒。

 

#include <reg51.h>

#define unit unsigned int

 

void delay(unit x){

    unit i=x;

    unit j;

    for(;i>0;--i){

       for(j=x;j>0;--j);

    }

}

void main()

{

    while(1){

       P1=0x00;

       delay(250);   //0.5

       P1=0xff;

       delay(420);//2

    }

}

 

2.  单片机驱动继电器输出实验;

a)         说明:Lab51单片机实验板的蜂鸣器连接到单片机的P1.4

b)        基本要求:控制继电器每5秒吸合0.5秒。

#include <reg51.h>

#define unit unsigned int

 

void delay(unit x){

    unit i=x;

        unit j;

    for(;i>0;--i){

    for(j=x;j>0;--j);

    }

}

sbit JiDian=P1^4;

void main()

{

    while(1){

    JiDian=0x00;

    delay(250);   //0.5

    JiDian=0xff;

    delay(700);//2

    }

}

 

3.延时实现p2口LED流水灯效果(用循环移位指令)

#include <reg51.h>

#define unit unsigned int

 

unit table[]={~0x01,~0x02,~0x04,~0x08,~0x10,~0x20,~0x40,~0x80};

void delay(unit x){

    unit i=x;

        unit j;

    for(;i>0;--i){

    for(j=x;j>0;--j);

    }

}

 

void main()

{

       int i;

       P2=0x00;

       while(1){

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

                  P2=table[i];

                  delay(250);//2

           }

       }

}     

 

4.p2口八个灯作二进制加法。理解二进值的计算

#include<reg51.h>

#define unit unsigned int

 

void delay(unit x){

    unit i=x;

        unit j;

    for(;i>0;--i){

    for(j=x;j>0;--j);

    }

}

 

void main(){

   while(1){

    P2=0xff;

       while(P2!=0x00){

           P2++;

           delay(250);//2

       }

   }

}   

5.直接用IO口做位选信号,控制8位数码管上显示1,2,3,4F,循环显示

说明:P0是位选,P2是段选

 

#include <reg51.H>

#define unit unsigned int

unit code NumTable[]={0x06,~0x24,~0x30,~0x19,~0x12,~0x02,0x87,0xff,~0x10};

void delay(unit x){

    unit i=x;

        unit j;

    for(;i>0;--i){

    for(j=x;j>0;--j);

    }

}

void DisplayNumByOrder(unit DelayNum){

           int i;

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

                  P0=NumTable[i];

                  delay(DelayNum);//2

           }

}

void main(){

    //P0是段选,P2是位选

    P2=0x00;

    while(1){

           DisplayNumByOrder(250);    

    }

}

6.用译码器138做片选信号,控制4位数码管上做加1显示。从0000开始.

说明:JP15JP16 8个短路冒连接,JP10 P0)与J12 8PIN排线连接

#include <reg51.h>

#include <math.h>

#define unit unsigned int

unit code NumTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数字的编码

//  用译码器138做位选信号,控制4位数码管上做加1显示。从0000开始.

void delay_1ms(unit x){

    unit i=x;

        unit j;

    for(;i>0;--i){

       for(j=110;j>0;--j);

    }

}

/**

    在数码管上显示对应的值

**/

void display(unsignedchar k)

{

    P0=NumTable[k];

    delay_1ms(3);

}

sbit high=P2^4;

sbit mid=P2^3;

sbit low=P2^2;

/**

    控制数码管显示后4位,并分解计数值

**/

void DisplayNumByOrder(unit Count,unit delay_1msNum){

       low=0; mid=0; high=0;  display(0);        

        low=1; mid=0; high=0;  display(0);               

        low=0; mid=1; high=0;  display(0);

       low=1; mid=1; high=0;  display(0);

       low=0; mid=0; high=1;  display(Count%10000/1000);

       low=1; mid=0; high=1;  display(Count%1000/100);

       low=0; mid=1; high=1;  display(Count%100/10);

       low=1; mid=1; high=1;  display(Count%10);

}

 

//一个是位选,一个是段选

void main(){

    int count=0;

    while(1){

           count++;

           DisplayNumByOrder(count,300);  

           if(count==9999) count=0;

    }

}

7.利用动态扫描方法在八位数码管上显示出稳定的87654321.

#include <reg51.h>

#define unit unsigned int

unit table[]={~0x01,~0x02,~0x04,~0x08,~0x10,~0x20,~0x40,~0x80};

unit code NumTable[]={0x06,~0x24,~0x30,~0x19,~0x12,~0x02,0x87,0xff,~0x10};

void delay(unit x){

    unit i=x;

        unit j;

    for(;i>0;--i){

    for(j=x;j>0;--j);

    }

}

void DisplayNumByOrder(unit DelayNum){

           int i;

           for(i=0;i<=7;i++){

                  P0=NumTable[i];

                  P2=table[i];

                  delay(DelayNum);//5ms

           }

}

//一个是位选,一个是段选

void main(){

    //P0是位选,P2是段选

    //P2=0x00;

    while(1){

           DisplayNumByOrder(5);      

    }

}

8.  数码管前三位显示一个跑表,从000999之间以1%秒速度运行,当按下一个独立键盘时跑表停止,松开手后跑表继续运行。

#include <reg51.h>

#define unit unsigned int

unit code NumTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数字的编码

//数码管前三位显示一个跑表,从000999之间以1%秒速度运行,当按下一个独立键盘时跑表停止,松开手后跑表继续运行。

sbit high=P2^4;

sbit mid=P2^3;

sbit low=P2^2;

sbit IsCountKey=P3^0;//是否计数的按键

const bit PRESSED=0;//0的时候运行,1的时候暂停

//监测

void delay_1ms(unit x){

    unit i=x;

    unit j;

    for(;i>0;--i){

       for(j=110;j>0;--j);

    }

}

/**

    在数码管上显示对应的值

**/

void display(unsignedchar Num)

{

    P0=NumTable[Num];

    delay_1ms(1);

    P0=0;      //送完段选信号后,进行消影的处理

}

 

/**

    控制数码管显示后3位,并分解计数值

**/

void DisplayNumByOrder(unit Count){

       low=0; mid=0; high=0;  display(0);        

        low=1; mid=0; high=0;  display(0);               

        low=0; mid=1; high=0;  display(0);

       low=1; mid=1; high=0;  display(0);

       low=0; mid=0; high=1;  display(0);

       low=1; mid=0; high=1;  display(Count%1000/100);

       low=0; mid=1; high=1;  display(Count%100/10);

       low=1; mid=1; high=1;  display(Count%10);

}

//是否计数

void IsCount(unit count){

    if(PRESSED==IsCountKey){    //当按键按下

       delay_1ms(10);       //去抖动

       if(PRESSED==IsCountKey){//当按键按下

           while(PRESSED==IsCountKey){//当按键一直按下

              DisplayNumByOrder(count);//显示原数值

           }

       }

    }

}

//扫描键盘

void main(){

    int count=0;

    while(1){

           IsCount(count);

           count++;

           DisplayNumByOrder(count);  

           if(count==999) count=0;

    }

}

 

 

9.  在上题的基础上,用另外三个独立键盘实现按下第一个时计时停止,按下第二个时计时开始,按下第三个是计数值清零从头开始。

#include <reg51.h>

#define unit unsigned int

unit code NumTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数字的编码

//数码管前三位显示一个跑表,从000999之间以1%秒速度运行,当按下一个独立键盘时跑表停止,松开手后跑表继续运行。

sbit high=P2^4;

sbit mid=P2^3;

sbit low=P2^2;

sbit Key1=P3^0;//开始

sbit Key2=P3^1;//暂停

sbit Key3=P3^2;//清零

const bit PRESSED=0;//按下

const bit SUSPEND=1;//0的时候运行,1的时候暂停

//监测

void delay_1ms(unit x){

    unit i=x;

    unit j;

    for(;i>0;--i){

       for(j=110;j>0;--j);

    }

}

/**

    在数码管上显示对应的值

**/

void display(unsignedchar Num)

{

    P0=NumTable[Num];

    delay_1ms(1);

    P0=0;      //送完段选信号后,进行消影的处理

}

 

/**

    控制数码管显示后3位,并分解计数值

**/

void DisplayNumByOrder(unit Count){

       low=0; mid=0; high=0;  display(0);        

        low=1; mid=0; high=0;  display(0);               

        low=0; mid=1; high=0;  display(0);

       low=1; mid=1; high=0;  display(0);

       low=0; mid=0; high=1;  display(0);

       low=1; mid=0; high=1;  display(Count%1000/100);

       low=0; mid=1; high=1;  display(Count%100/10);

       low=1; mid=1; high=1;  display(Count%10);

}

 

//是否清零

void IsClear(unit * count){

    if(PRESSED==Key3){       //当按键按下

       delay_1ms(10);       //去抖动

       if(PRESSED==Key3){   //当按键按下

           *count=0;

       }

    }

}

//是否暂停

void IsSuspend(unit * count){

    if(PRESSED==Key2){       //当按键按下

       delay_1ms(10);       //去抖动

       if(PRESSED==Key2){   //当按键按下

           while(SUSPEND){  

              IsClear(count);          //监测是否需要清零

              if(PRESSED==Key1)return;//跳出暂停

              DisplayNumByOrder(*count);//显示原数值

           }

       }

    }

}

 

 

//扫描键盘

void main(){

    int count=0;

    while(1){

           IsSuspend(&count);

           IsClear(&count);

           count++;

           DisplayNumByOrder(count);  

           if(count==999) count=0;

    }

}

 

 

 

10.按下16个矩阵键盘依次在数码管上显示1-16的平方。如按下第一个显示1,第二个显示4...

#include <reg51.h>

#include <stdio.h>

#define unit unsigned int

#define uchar unsigned char

 

unit code NumTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数字的编码

//10.按下16个矩阵键盘依次在数码管上显示1-16的平方。如按下第一个显示1,第二个显示4...

 

sbit high=P2^4;

sbit mid=P2^3;

sbit low=P2^2;

sbit Key1=P3^0;//开始

sbit Key2=P3^1;//暂停

sbit Key3=P3^2;//清零

const bit PRESSED=0;//按下

const bit SUSPEND=1;//0的时候运行,1的时候暂停

//延时

void delay_1ms(unit x){

    unit i=x;

    unit j;

    for(;i>0;--i){

       for(j=110;j>0;--j);

    }

}

/**

    在数码管上显示对应的值

**/

void display(unsignedchar Num)

{

    P0=NumTable[Num];

    delay_1ms(1);

    P0=0;      //送完段选信号后,进行消影的处理

}

 

/**

    控制数码管显示后3位,并分解计数值

**/

void DisplayNumByOrder(unit Count){

       low=0; mid=0; high=0;  display(0);        

        low=1; mid=0; high=0;  display(0);               

        low=0; mid=1; high=0;  display(0);

       low=1; mid=1; high=0;  display(0);

       low=0; mid=0; high=1;  display(0);

       low=1; mid=0; high=1;  display(Count%1000/100);

       low=0; mid=1; high=1;  display(Count%100/10);

       low=1; mid=1; high=1;  display(Count%10);

}

 

//是否清零

void IsClear(unit * count){

    if(PRESSED==Key3){       //当按键按下

       delay_1ms(10);       //去抖动

       if(PRESSED==Key3){   //当按键按下

           *count=0;

       }

    }

}

//是否暂停

void IsSuspend(unit * count){

    if(PRESSED==Key2){       //当按键按下

       delay_1ms(10);       //去抖动

       if(PRESSED==Key2){   //当按键按下

           while(SUSPEND){  

              IsClear(count);          //监测是否需要清零

              if(PRESSED==Key1)return;//跳出暂停

              DisplayNumByOrder(*count);//显示原数值

           }

       }

    }

}

 

uchar scanKey(){

    uchar tmp, key;

 

    P3 =0xf0;

    tmp = P3;

    tmp = tmp &0xf0;

    if(tmp !=0xf0){//确定列

       switch(tmp){

       case0xe0:key =1;break;

       case0xd0:key =2;break;

       case0xb0:key =3;break;

       case0x70:key =4;break;

       }

    }

    //确定行

    P3 =0x0f;

    tmp = P3;

    tmp = tmp &0x0f;

    if(tmp !=0x0f){

       switch(tmp){

       case0x0d:key = key;break;

       case0x0b:key =4+ key;break;

       case0x07:key =8+ key;break;

       }         

    }

    return key;

}

 

//扫描键盘

void main(){

    // int count=0;

    while(1){

       unit key= scanKey();

       DisplayNumByOrder(key*key);

    }

}

 

 

posted @ 2013-07-05 21:44  陈哈哈  阅读(4484)  评论(0编辑  收藏  举报