分享

第六课 输入控制—键盘《中学生C51单片机易学实战入门教程》

 岐岐feng 2018-03-26
  • 实验准备

  • 课程内容

第六课 输入控制—键盘

实验准备:

使用前一课已装配好的实验板

共阳极单位数码管1只

蜂鸣器模块一件

电阻:10k 8只 或排阻(用于P0上拉)

(或直接使用完整的开发板)

课程内容:

一、8位独立键盘

第六课 输入控制—键盘《中学生C51单片机易学实战入门教程》

从原理图看到,8个按键都有一个脚 接GND,即 0;

也就是说,哪个键按下去,对应接这个键的管脚 就是 0。

实验,把独立键盘到P2组,注意P2的 IO 顺序与其他三排不同。刚好,这独立键盘的接口排序与P2的IO顺序相同。

就用前一课的程序,稍作修改。

void main()

{

for(;;)

{

if(P20==0) P15=0; //不停地判断,当按下K8,蜂鸣器响

if(P21==0) P15=1; //不停地判断,当按下K7,蜂鸣器静音

}

}

编译,下载到实验板,测试按键。

现在,单片机就在你控制之下了。

可以自由实验下用各个按键控制共阳极数码管显示不同的数。

二、矩阵键盘

独立键盘,一个按钮就占了一个IO端口,如果多于8个按钮,那实在是很浪费IO口,单片机本身资源有限,那么就要让有限的资源发挥更多的效用。

矩阵键盘,就是同样用8个IO端口,却能实现16个按钮的处理。一般应用于多于8个按键的场合。

第六课 输入控制—键盘《中学生C51单片机易学实战入门教程》

第六课 输入控制—键盘《中学生C51单片机易学实战入门教程》

第六课 输入控制—键盘《中学生C51单片机易学实战入门教程》

从成品与原理图中可以看到,矩阵键盘与前面课程中的LED点阵有点类似,只是这里仅用一组IO端口就够了,横线4条与纵线4条各连接按的一个脚。只要控制横线状态全1,纵线某线为0,当这纵线某键按下,判断对应的横线哪个变为0,就可以知道哪个键被按下了。

void main()

{

uchar a = 0x00;

for(;;)

{

P2 = 0xFE;

a = P2;

if(a==0xEE) P0=light[1];

if(a==0xDE) P0=light[2];

if(a==0xBE) P0=light[3];

if(a==0x7E) P0=light[10];//显示 A

P2 = 0xFD;

a = P2;

if(a==0xED) P0=light[4];

if(a==0xDD) P0=light[5];

if(a==0xBD) P0=light[6];

if(a==0x7D) P0=light[11];//显示 b

P2 = 0xFB;

a = P2;

if(a==0xEB) P0=light[7];

if(a==0xDB) P0=light[8];

if(a==0xBB) P0=light[9];

if(a==0x7B) P0=light[12];//显示 C

P2 = 0xF7;

a = P2;

if(a==0xE7) P15=0;//蜂鸣器响

if(a==0xD7) P0=light[0];

if(a==0xB7) P15=1;//蜂鸣器静音

if(a==0x77) P0=light[13];//显示 d

}

}

代码分析:

P2初值 0xFE(11111110)也就是仅让最低位的一条线为0,

按下后,如读到P2值是 0xEE (11101110),那么表示高4位的4线中排在开头的线与最低位连接了,从1变成0了,也就从这判断了 按下了矩阵键盘的1键。

a = P2; //读P2值

if(a==0xEE) P0=light[1];

判断,如果判断到这状态,表示键盘的1按下了,数码管显示1

其他按键类似。

三、程序优化与增补C语言基础

先看回之前的程序 中的 if 结构

if ---

if --- else ---

if--- else if ---else if --- else ---

if 语句 嵌套

if (条件)

{

if --- else ---

}

else

{

if ---

}

好用的条件运算符

表达式1?表达式2:表达式3

例如

求最大值

if (a>b) max=a;

else max = b;

直接换成一句: max= (a>b)?a:b;

多分支结构 swith/case

可以把前面的 矩阵键盘优化改造

循环:

除了以前的for 循环,还有 while 循环 和 do---while循环(P76流程图)

修改前面的程序 改用 while 循环

break 语句 修改前面的程序 按某键时退出循环

continue语句 修改前面的程序 加这句让后面的数不显示 即对应语句跳过

常量与变量

mDelay(1000);

可以定义一个 uchar speed; 然后调用 mDelay(speed);

实验,按不同的键 修改 延时的时间 快 慢

整型常量,整型变量 带符号,无符号

字符型常量,变量

(注意,字符在内存中也是以数字存放的)

即 char c=’a’; 与 int c=97;效果一样

注意 字符是用单引号括起的

如果用双引号,那么就成是字符串,字符串是字符的集合,以数组形式定义。

数组,可以看 function.h

单片机本身速度慢,一般不做有关负数的运算

数的溢出。之前实验中倒计时中 就是数的溢出造成BUG

实型数据 (又称为浮点数)

两种方式,一种是直接用10进制 带小数

另一种 类似于 平常讲的 科学记数法 123e3

C语言中 定义 实型数据 两种命名方法

Double(双精度) float(单精度)

平常使用,如果用到实数,一般用 double

C51单片机一般不用实型数据,即使要用,也是采用变通方式,

例如,用整数方式运算,然后在数码管某位显示 小数点 让整个数显示 成小数形式

C51特有常用数据 function.h 中有示例

sbit bit

程序存储位置 code

了解各种运算符

算述运算符 其中一个求字节数 sizeof

一个字节8位,所以function.h 的数组长度 可以直接用 sizeof 求得

强制转换与默认转换 (大概知道即可)

全局变量 局部变量

了解 变量有效作用范围即可

数组与指针

从 function.h 中认识数组

补充字符型数组

char a[]={“Welcome”};

注意其中用双引号而不是之前单个字符的单引号

这字符数组a长度 是8,因为最后一个符号 \0 是C语言自动加上的

指针的概念,例如,已有数组

uchar code light[] ={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0x8C,0x89,0xC7,0x91,0xBF,0xFF};

然后定义:

char *p;

p=&light[0];//把前面第一组数0xC0在电脑中存储的位置记在p中

如果之后 p++,就指向第二个数0xF9,如果这里用个命令

b = *p; 表示把p所指的位置的数取出给 b

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多