C51编程10-I/O口综合练习

最新更新时间:2022-06-23来源: eefocus关键字:C51  编程  I  O口 手机看文章 扫描二维码
随时随地手机看文章

I/O口综合实践项目


    1)矩阵键盘键盘的每一个按键,进行编码键值码(1~16);


    2)单片将对应的键值码转换为数码管编码;


    3)数码管持续显示键值码(0~15);


    4)按下按键,释放按键后,持续持续显示键值码,直到下一次按键被按下为止。


软件系统框图如下:

功能需求分析:


按下按键,释放按键后,持续持续显示键值码,直到下一次按键被按下为止。当按键被按下,才会产生键值码,当手释放后,键值码为0。如果需要按下按键后释放,还有显示,需要将数据保存起来。


由于键值码最多只有两位数,因此建立以下的一维数组进行数组储存键值码。 


uchar table2[]={0,0};

新增inputNum函数对按键的键值,进行存储


/*******************************************************

*

* Function name :inputNum

* Description        : 将键值码保存在一维数组

* Parameter         :

*

* Return          :None

**********************************************************/

void inputNum()

{

      uchar num,i;

    i=0;

    //调用KeyDown函数,返回键值码;

    num  = keyDown();

  

    //当键值码>1时,按键被拿下

    if(num>0){

       num--;

      //将上一次的数据进行清零

      for(i;i<2;i++){

        table2[i]=0;

      }

      //保存键值码

      if(num<10){

        

        table2[0]=num;

      }

      else{

        //保存个位数

        table2[0]=num%10;

        //保存十位数

        table2[1]=num/10;      

      }        

  }    

            

}

 


main函数


    系统初始化,然后扫描键盘与显示


/*******************************************************

*

* Function name :main

* Description        :扫描键盘与显示

* Parameter         :None

* Return          :None

**********************************************************/

void main() {

   

    sysinit();

    while(1) { 

      //扫描键盘将键值码保存到一维数组

      inputNum(); 

      

      //显示数组 

       showsmg(0,table2[0]);

      delay(5);  //添加延时函数,防止会有显示乱码,必须加

      if(table2[1]==1){

      showsmg(1,table2[1]);

        delay(5);  //添加延时函数,防止会有显示乱码,必须加

      }    

   }

}

 


项目详细实现代码:



/********************************************************************************

* @File name: main.c

* @Author: adamChen

* @Version: 1.1

* @Date: 2020-08-17

* @Description: LED display

* @contact:975805363@qq.com

********************************************************************************/

#include "reg52.h"

typedef unsigned char uchar;

typedef unsigned int uint;

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

uchar table2[]={0,0};

sbit smg2 = P2^4;

sbit smg1 = P2^3;

sbit smg0 = P2^2;

sbit driver_key1 = P1^7;

sbit driver_key2 = P1^6;

sbit driver_key3 = P1^5;

sbit driver_key4 = P1^4;

sbit snesor_key1 = P1^3;

sbit snesor_key2 = P1^2;

sbit snesor_key3 = P1^1;

sbit snesor_key4 = P1^0;

void sysinit();

void delay(uint ms);

uchar keyDown();

void showsmg(uchar selSmg,uchar dat);

void inputNum();

/*******************************************************

*

* Function name :main

* Description        :扫描键盘与显示

* Parameter         :None

* Return          :None

**********************************************************/

void main() {

   

    sysinit();

    while(1) { 

      //扫描键盘将键值码保存到一维数组

      inputNum(); 

      

      //显示数组 

       showsmg(0,table2[0]);

      delay(5);  //添加延时函数,防止会有显示乱码,必须加

      if(table2[1]==1){

      showsmg(1,table2[1]);

        delay(5);  //添加延时函数,防止会有显示乱码,必须加

      }    

   }

}

/*******************************************************

*

* Function name :sysinit

* Description        : 系统初始化

* Parameter         :

*

* Return          :None

**********************************************************/

void sysinit() // ms代表需要延时的毫秒数

{

    showsmg(0,0);

}

/*******************************************************

*

* Function name :inputNum

* Description        : 将键值码保存在一维数组

* Parameter         :

*

* Return          :None

**********************************************************/

void inputNum()

{

      uchar num,i;

    i=0;

    //调用KeyDown函数,返回键值码;

    num  = keyDown();

  

    //当键值码>1时,按键被拿下

    if(num>0){

       num--;

      //将上一次的数据进行清零

      for(i;i<2;i++){

        table2[i]=0;

      }

      //保存键值码

      if(num<10){

        

        table2[0]=num;

      }

      else{

        //保存个位数

        table2[0]=num%10;

        //保存十位数

        table2[1]=num/10;      

      }        

  }    

            

}

     

     

/*******************************************************

*

* Function name :delay

* Description        : 延时函数

* Parameter         :

  @ms        millisecond(毫秒)

*

* Return          :None

**********************************************************/

void delay(unsigned int ms) // ms代表需要延时的毫秒数

{

    uint x,y;

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

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

}

/*******************************************************

*

* Function name :KeyDown

* Description        : 扫描按键

* Parameter         :

  @selsmg      选择数码管第几个

  @num      显示数值

*

* Return          :KeyNum

**********************************************************/

uchar keyDown() {

    uchar num=0;

    driver_key1 = 0;

    if(snesor_key1==0)

    {

       delay(10);

      if(snesor_key1==0)

      num = 1;

    }

        

    if(snesor_key2==0)

        {

       delay(10);

      if(snesor_key2==0)

      num = 2;

    }

    if(snesor_key3==0)

  {

       delay(10);

      if(snesor_key3==0)

      num = 3;

    }

        

    if(snesor_key4==0)

        {

       delay(10);

      if(snesor_key4==0)

      num = 4;

    }

    driver_key1 = 1;

    driver_key2 = 0;

    if(snesor_key1==0)

  {

       delay(10);

      if(snesor_key1==0)

      num = 5;

    }

        

    if(snesor_key2==0)

        {

       delay(10);

      if(snesor_key2==0)

      num = 6;

    }

    if(snesor_key3==0)

          {

       delay(10);

      if(snesor_key3==0)

      num = 7;

    }

    if(snesor_key4==0)

         {

      delay(10);

      if(snesor_key4==0)

      num = 8;

    }

    driver_key2 = 1;

    driver_key3 = 0;

    if(snesor_key1==0)

          {

       delay(10);

      if(snesor_key1==0)

      num = 9;

    }

        

    if(snesor_key2==0)

          {

       delay(10);

      if(snesor_key2==0)

      num = 10;

    }

    if(snesor_key3==0)

          {

      delay(20);

      if(snesor_key3==0)

      num = 11;

      }

    if(snesor_key4==0)

          {

       delay(10);

      if(snesor_key4==0)

      num = 12;

    }

    driver_key3 = 1;

    driver_key4 = 0;

    if(snesor_key1==0)

               {

      delay(10);

      if(snesor_key1==0)

      num = 13;

    }

    if(snesor_key2==0)

            {

      delay(10);

      if(snesor_key2==0)

      num = 14;

    }

    if(snesor_key3==0)

          {

      delay(10);

      if(snesor_key3==0)

      num = 15;

      }

    if(snesor_key4==0)

           {

      delay(10);

      if(snesor_key4==0)

      num = 16;

    }

    driver_key4 = 1;

   

    return num;

}

/*******************************************************

*

* Function name :showsmg

* Description        : 数码管显示

* Parameter         :

  @selsmg      选择数码管第几个

[1] [2]
关键字:C51  编程  I  O口 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic614506.html

上一篇:C51编程9-数码管(显示)
下一篇:C51编程11-中断篇(中断原理1)

推荐阅读

C51编程5-输入电平(矩阵键盘)
独立按键,一个按键需要占用一个I/O口,如果需要16个按键,那么就会 占用16个I/O口,占据MCS-51系列单片机一半的I/O口。理论基础为了解决I/O这个问题,设计出了矩阵键盘,下图是一个4*4的矩阵键盘原理图。按键按照4*4的格局进行摆放,组成4行4列,将按键的同行或同列连接在一起,分别连接到P1口。怎么才能识别是哪个按键被按下呢?以上图的S1为例,当按键被按下S1导通,P17与P13导通,可以通过判断P17与P13端口的电平是否一致,判断按键是否被按下。可以先设置P13(检测端口)电平为高电平,假设P17(驱动端口)为低电平,当按键按下,按键导通,读取P13的电平可以读到低电平。(1)设置驱动端口电平为高电平(1)或者低电平
发表于 2022-06-22
C51<font color='red'>编程</font>5-输入电平(矩阵键盘)
C51编程4-输入电平(独立按键)
I/O口,I代表Inpout,O代表Output。前面的所讲的点亮LED,是单片机输出高低电平,从而达到控制LED;这一讲将会通过按键输入电平,单片机检测到输入高低电平,将会有对应的动作。STC89C52的输入电平识别。独立按键按键的一端接单片的I/O口,另一端接GND或者VCC(接VCC的时候需要注意,电压是需要单片机能够识别的输入的电压。) ,下图是接GND的连接方式。当独立按键按下时,高低电平(VCC或者GND)会直接到达I/O口,此时单片机可以检测到该I/O口是高电平(1)或者低电平(0),然后做独立按键被按下的对应处理。现在有一个功能需求,当按下按键时LED被点亮,手松开时LED熄灭。代码应该如何写呢?#include &
发表于 2022-06-22
C51<font color='red'>编程</font>4-输入电平(独立按键)
C51编程3-输出电平(点亮LED3)
P2口的I/O口连接8个led,假设现在点亮第1个led(LED1),而其他led不亮。不用C51的位变量进行直接操作,而是使用标准51的写法,会有以下的代码。#include "reg52.h"void main(){ P2 = 0xfe;}假设有需要要最后一个led(LED8)点亮,我们会写以下的代码。#include "reg52.h"void main(){ P2 = 0x7f;}现在提出一个新的需求,先点亮LED1,再点亮LED8,点亮LED8,LED1也是正常工作的。聪明的你,肯定很快下出以下代码。#include "reg52.h"void main(){
发表于 2022-06-22
C51<font color='red'>编程</font>3-输出电平(点亮LED3)
C51编程2-输出电平(点亮LED2)
上一讲中,直接通过变量sbit来控制P2口中一个LED的亮灭。除了可以通过sbit位控制来设置LED,我们还可以通过P2口,直接控制P2口的LED。下面的代码可以实现上一讲一样的功能,控制led0亮。#include "reg52.h"void main(){ P2 = 0xfe;}从上面的代码中,将0xfe直接赋值给P2为什么实现的功能跟位操作的一样?而我们学习的C语言中,貌似没有都见过sbit,P2这两个东西。在《标准C与C51》的文章中,提到为发挥C51单片机的特性,编译器会增加对MCS51单片特性的支持,而sbit与P2就是为了发挥MCS51单片机增加的特性支持。有兴趣的,可以通过下面的连接看到《标准C
发表于 2022-06-22
C51<font color='red'>编程</font>2-输出电平(点亮LED2)
C51编程1-输出电平(点亮LED1)
51单片机中,有4个组I/O口,分别是P0、P1、P2、P3;I/O(Input/Output)口,Input表示输入电平信号,Out表示输出电平信号。在数字电路中,电平有高低电平两种,也就是说I/O口,这个端口可以输入或者输出高低电平。不同数字电路系统中,对于电平的定义的电压不一样。而在STC89C52中5V的系统中(如下图所示),低于0.8V被识别为低电平,而高于2.0V被识别为高电平。LED电路原理图:在51单片机系统中,LED正极接电源VCC(5V),负极接串联一个470欧电阻,连接到单片接P2。LED点亮原理 :以P20口为例说明,LED可以点亮的原理。当单片机P20口的引脚为高电平,LED连接的VCC为端高电平,没有形成
发表于 2022-06-22
C51<font color='red'>编程</font>1-输出电平(点亮LED1)
C51编程22-应用篇(解码红外遥控器)
在使用家电过程中,必不可少的就是遥控器了。 常用的红外遥控系统一般分发射和接收两个部分。应用编/解码专用集成电路芯片来进行控制操作,如下图所示。发射部分包括键盘矩阵、编码调制、LED红外发送器;接收部分包括光、电转换放大器、解调、解码电路。 发射部分的主要元件为红外发光二极管。它实际上是一只特殊的发光二极管;由于其内部材料不同于普通发光二极管,因而在其两端施加一定电压时,它便发出的是红外线而不是可见光。目前大量的使用的红外发光二极管发出的红外线波长为940nm左右。 由于我们目的不是制作遥控器,而是利用遥控器控制单片机的功能,我们将会重点在于红外接收到信号部分。红外接收头通常使 HS0038(38KHZ)。
发表于 2022-06-22
C51<font color='red'>编程</font>22-应用篇(解码红外遥控器)
小广播
实战 培训 开发板 精华推荐

何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2022 EEWORLD.com.cn, Inc. All rights reserved