51学习笔记《二》
一、数码管
数码管是一种可以显示数字和其他信息的电子设备。玻璃管中包括一个金属丝网制成的阳极和多个阴极。大部分数码管阴极的形状为数字。图片如下:
数码管可以用来显示输出结果,一些字母等。主要是一个显示设备。
8位共阴极数码管原理图:
数码管显示分为静态显示和动态显示
静态显示 | 动态显示 | |
---|---|---|
特点 | 每个数码管必须接在一个8位数据线来保持现实的字形码。当送入一次字形码字形可以一直保持,直到下一次送入新的字形 。只能显示一位数字 | 所有位选码管的段选线并联在一起,由位选线程控制位有效选亮数码管采取动态扫描显示,这样就可以通过人眼的视觉延迟来点亮多个数码管 |
显示代码 | 代码1[^1] | 代码2[^2] |
[^1]:静态显示1
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit DU=P2^6;//数码管段选
sbit WE=P2^7;//数码管位选
//毫秒级延时函数
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}
void main()
{
WE=1;//打开位选锁存器
P0=0xfe; //1111 1110
WE=0;//关闭位选锁存器
DU=1;//打开段选锁存器
P0=0X06;//0000 0110x显示1
DU=0;//关闭位选锁存器
while(1)
{
P0=0x01;
}
}
所谓的段选就是选择要点亮那个数码管,位选就是要让数码管显示的数。
[^2]:动态显示123
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit DU=P2^6;//段选
sbit WE=P2^7;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}
void main()
{
while(1)
{
P0=0xff;
WE=1;
P0=0XFE;
WE=0;
DU=1;
P0=0X06;
DU=0;
delay(5);
P0=0xff;
WE=1;
P0=0XFD;
WE=0;
DU=1;
P0=0X5B;
DU=0;
delay(5);
P0=0xff;
WE=1;
P0=0XFB;
WE=0;
DU=1;
P0=0X4F;
DU=0;
delay(5);
}
}
我们可以发现通过以上方式实现数码管的显示比较麻烦,我们可以定义一个数码管显示函数,通过调用这个函数改变函数的参数来实现数码管显示的数。代码如下:
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit DU=P2^6;//
sbit WE=P2^7;
uchar a[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//数码管显示数组表示0,1,2,3,4,5,6,7,8,9
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}
void display(uchar i)//计算出个位、十位、百位的数并显示
{
uchar bai,shi,ge;
bai=i/100;
shi=(i%100)/10;
ge=i%10;
P0=0xff;//清除断码
WE=1;
P0=0XFE; //1111 1110
WE=0;
DU=1;//???????????
P0=a[bai];//0000 0110
DU=0;
delay(5);
P0=0xff;
WE=1;
P0=0XFD;
WE=0;
DU=1;
P0=a[shi];
DU=0;
delay(5);
P0=0xff;//
WE=1;
P0=0XFB;
WE=0;
DU=1;
P0=a[ge];
DU=0;
delay(5);
}
void main()
{
while(1)
{
display(200);
}
}
二、独立键盘与矩阵键盘
基础知识:按键按照结构原理科分为两类,一类是触点式开关按键,如机械式开关、导电橡胶式开关灯;另一类是无触点式开关按键,如电气式按键,磁感应按键等。前者造价低,后者寿命长。目前,微机系统中最常见的是触点式开关按键。
对于一组键或一个键盘,总有一个接口电路与CPU相连。CPU可以采用查询或中断方式了解有无将按键输入,并检查是哪一个按键按下,将该键号送人累加器,然后通过跳转指令转入执行该键的功能程序,执行完成后再返回主程序。
上图就是矩阵键盘的样子。同时附上按键按下电压变化图:
所以并不是按键按下就会成为高电压,而有按键抖动。所以每次按键按下要使用延时函数进行按键消抖判断是否按下和松开。
原理图如下:
根据原理图写程序独立键盘进行加减并且数码管显示:
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit DU=P2^6;
sbit WE=P2^7;
sbit key_s2=P3^0;
sbit key_s3=P3^1;
uchar num;
uchar a[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}
void main()
{
WE=1;
P0=0XFE;
WE=0;
while(1)
{
if(key_s2==0)
{
delay(20);
if(key_s2==0)
{
num++;
if(num==10)
{
num=0;
}
while(!key_s2);//松手检测
}
}
if(key_s3==0)
{
delay(20);//按键消抖
if(key_s3==0)
{
if(num>0)
{
num--;
}
while(!key_s3);//判断是否松手
}
}
DU=1;
P0=a[num];
DU=0;
}
}
这样就能实现S2按下num加,S3按下num减。
同时键盘还能作为输入工具,接下来的程序将实现每按下一个按键数码管显示一个字符。
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit DU=P2^6;
sbit WE=P2^7;
uchar num;
uchar keyvalue=20;//按键值
//数码管显示数组
uchar table[]={
//0 1 2 3 4 5 6 7 8
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
//9 a b c d e f h l
0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x76,0x38,
//n u
0x37,0x3e,0x40,0x00};
uchar a[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}
void keyscan()
{
//4*4键盘扫描函数
P3=0xf0;
if(P3!=0XF0)//判断按键是否按下
{
delay(10);//按键消抖
if(P3!=0x0f)//再次判断
{
switch(P3)
{
case 0xe0:keyvalue=0;break; //第一列
case 0xd0:keyvalue=1;break; //第二列
case 0xb0:keyvalue=2;break;
case 0x70:keyvalue=3;break;
}
P3=0x0f;//行扫描
switch(P3)
{
case 0x0e:keyvalue=keyvalue;break;
case 0x0d:keyvalue=keyvalue+4;break;
case 0x0b:keyvalue=keyvalue+8;break;
case 0x07:keyvalue=keyvalue+12;break;
}
while(P3!=0x0f);
}
}
P3=0xff;
if(P3!=0XFF)
{
delay(10);
if(P3!=0XFF)
{
switch(P3)
{
case 0xfe:keyvalue=16;break;
case 0xfd:keyvalue=17;break;
case 0xfb:keyvalue=18;break;
case 0xf7:keyvalue=19;break;
}
while(P3!=0xff);
}
}
}
void main()
{
WE=1;
P0=0XFE;
WE=0;
while(1)
{
keyscan();//矩阵键盘扫描函数
DU=1;
P0=table[keyvalue];数码管显示
DU=0;
}
}
这样就能将数码管与键盘结合,一个输入一个输出。