ATC52 学习记录
实验2.2.1:控制一个数码管循环显示0~9
#include <reg52.h>//包含51头文件
#include <intrins.h>//包含移位标准库函数头文件
#define uint unsigned int
#define uchar unsigned char
sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
uchar count = 0; // 控制数码管显示的变量
uchar i = 0; // 控制循环次数的变量
bit flag;
//共阴数码管段选表0-9
uchar code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};
/*====================================
函数 : delay(uint z)
参数 :z 延时毫秒设定,取值范围0-65535
返回值 :无
描述 :12T/Fosc11.0592M毫秒级延时
====================================*/
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
/*====================================
描述 :两位共阴数码管动态显示
====================================*/
void display(uchar num1, uchar num2)
{
/*第一位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[num2];//
DU = 0;//锁存段选数据
delay(1);
/*第二位显示*
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFD; //1111 1101
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[num2];//
DU = 0;//锁存段选数据
delay(1); */
}
/*====================================
变量 count:负责控制点亮哪2个数码管,例如count 为1 则点亮 01 数码管
描述 :由于同时点亮2个数码管,需要2个数码管不断的循环才能实现2个数码管同时点亮
所以在这里将数码管显示在单片机的代码封装起来,来让我们调用。
====================================*/
void singlechip_show_num(uchar count){
switch(count){ // 通过 switch case 语句对 数码管的数值进行精准的管理
case 0 :
display(0 , 0);
break;
case 1 :
display(0 , 1);
break;
case 2 :
display(0 , 2);
break;
case 3 :
display(0 , 3);
break;
case 4 :
display(0 , 4);
break;
case 5 :
display(0 , 5);
break;
case 6 :
display(0 , 6);
break;
case 7 :
display(0 , 7);
break;
case 8 :
display(0 , 8);
break;
case 9 :
display(0 , 9);
break;
case 10 :
display(1 , 0);
break;
}
}
void main()//main函数自身会循环
{
IT1=1;
EA=1;
EX1=1;
while(1){
while(1)
{
for (i = 0; i < 200; i++){ // 使点亮的数码管循环 200 次,保证人眼能够看到的数码管是同时显示的。
singlechip_show_num(count); // 调用数码管显示函数
}
if(flag==0){
count++; }//每次循环200次结束, count 变量自身+1,单片机显示+1后的数值
if(count == 11){ // 当count 变量 等于11时,我们把变量再重新初始化为0,从0重新开始计数循环
count = 0;
}
}
}
}
void wint0(void) interrupt 2
{
flag=~flag;
}
实验2.2.2:要求利用开关或者按键作为中断源
#include <reg51.h>
void main()
{
P1=0xF0;
IT1=1;
EA=1;
EX1=1;
while(1);
}
void wint0(void) interrupt 3
{
P1=~P1;
}
实验2.2.2.1:用开关或者按键作为外部中断源,控制某个或者某组灯亮、灭,并且验证中断的优先级
#include<reg51.h>
#include<intrins.h>
void delay(unsigned int d){
while(d--);
}
void main()
{
unsigned char sel;
sel=0xfe;
IE=0x85;
IP=0x01;
while(1){
P1=sel;delay(10000);
sel=_crol_(sel,1);
}
}
/*中断0,高优先级,隔一个亮一个*/
void my_int0(void)interrupt 0{
unsigned saved=P1;
P1=0xaa;
delay(500);
P1=saved;
}
/*中断1,低优先级,全亮,并保持一段时间*/
void my_int1(void)interrupt 1{
int i=1000;
while(i--)
{
unsigned saved=P1;
P1=0x00;
delay(250);
P1=saved;
}
}
其中实验2.2.2.2:用开关或者按键作为定时/计数器的外部脉冲输
入,数码管随之计量(每按1次显示数字加1)
#include <reg52.h>//包含51头文件
#include <intrins.h>//包含移位标准库函数头文件
#define uint unsigned int
#define uchar unsigned char
sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
uchar count = 0; // 控制数码管显示的变量
uchar i = 0; // 控制循环次数的变量
bit flag;
//共阴数码管段选表0-9
uchar code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};
/*====================================
函数 : delay(uint z)
参数 :z 延时毫秒设定,取值范围0-65535
返回值 :无
描述 :12T/Fosc11.0592M毫秒级延时
====================================*/
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
/*====================================
描述 :两位共阴数码管动态显示
====================================*/
void display(uchar num1, uchar num2)
{
/*第一位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[num2];//
DU = 0;//锁存段选数据
delay(1);
/*第二位显示*
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFD; //1111 1101
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[num2];//
DU = 0;//锁存段选数据
delay(1); */
}
/*====================================
变量 count:负责控制点亮哪2个数码管,例如count 为1 则点亮 01 数码管
描述 :由于同时点亮2个数码管,需要2个数码管不断的循环才能实现2个数码管同时点亮
所以在这里将数码管显示在单片机的代码封装起来,来让我们调用。
====================================*/
void singlechip_show_num(uchar count){
switch(count){ // 通过 switch case 语句对 数码管的数值进行精准的管理
case 0 :
display(0 , 0);
break;
case 1 :
display(0 , 1);
break;
case 2 :
display(0 , 2);
break;
case 3 :
display(0 , 3);
break;
case 4 :
display(0 , 4);
break;
case 5 :
display(0 , 5);
break;
case 6 :
display(0 , 6);
break;
case 7 :
display(0 , 7);
break;
case 8 :
display(0 , 8);
break;
case 9 :
display(0 , 9);
break;
}
}
void main()//main函数自身会循环
{
IT1=1;
EA=1;
EX1=1;
while(1){
while(1)
{
for (i = 0; i < 200; i++){ // 使点亮的数码管循环 200 次,保证人眼能够看到的数码管是同时显示的。
singlechip_show_num(count); // 调用数码管显示函数
}
if(flag==1){
count++;
flag=0;
}//每次循环200次结束, count 变量自身+1,单片机显示+1后的数值
if(count == 10){ // 当count 变量 等于11时,我们把变量再重新初始化为0,从0重新开始计数循环
count = 0;
}
}
}
}
void wint0(void) interrupt 2
{
flag=1;
}
功能测试1,用矩阵按键显示0~F
#include <reg52.h>//包含51头文件
#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 code tabel[]= {
//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
};
/*====================================
函数 : delay(uint z)
参数 :z 延时毫秒设定,取值范围0-65535
返回值 :无
描述 :12T/Fosc11.0592M毫秒级延时
====================================*/
void delay(uint z){
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
/*====================================
函数 :KeyScan()
参数 :无
返回值 :无
描述 :4*4矩阵键盘与独立键盘扫描
按键按下KeyValue全局变量值发生相应变化
====================================*/
void KeyScan(){
//4*4矩阵键盘扫描
P3 = 0XF0;//列扫描
if(P3 != 0XF0){ //判断按键是否被按下
delay(10);//软件消抖10ms
if(P3 != 0XF0){ // 判断按键是否被按下
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); // 软件消抖10ms
if(P3 != 0XFF){
switch(P3){ // 判断那一行被按下
case 0xfe:
KeyValue = 16;
break; // S2被按下
case 0xfd:
KeyValue = 17;
break; // S3被按下
case 0xfb:
KeyValue = 18;
break; // S4被按下
case 0xf7:
KeyValue = 19;
break; // S5被按下
}
while(P3 != 0XFF); // 松手检测
}
}
}
void main(){ // main函数自身会循环
WE = 1; // 打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0; // 锁存位选数据
DU = 1; // 打开段选锁存器
while(1){
KeyScan(); // 20个按键键盘扫描
P0 = tabel[KeyValue]; // 显示按键值
}
}
功能测试,用4个数码管显示如下要求:
以输入2761为例,数码管显示 2761-276.1-27.61-2.761-7612-761.2-76.12-7.612-7127-612.7-61.27-6.127-1276-127.6-12.76-1.276-2761-…。
#include <reg52.h>//包含51头文件
#include <intrins.h>//包含移位标准库函数头文件
#define uint unsigned int
#define uchar unsigned char
sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
uchar num;//数码管显示的值
uchar I_1 ,I_2,I_3,I_4,temp_5;
uint x,y;
//共阴数码管段选表 不带小数点
uchar code table1[]= {
//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
};
//共阴数码管段选表 带小数点 +8即可
uchar code table2[16]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7,0xfc,0xb9,0xde,0xf9,0xf1};
// 控制第几个数码管亮1111 1110 1111 1101 1111 1011 1111 0111
uchar code table3[5]={0xFF,0xFE,0xFD,0xFB,0xF7};
/*====================================
函数 : delay(uint z)
参数 :z 延时毫秒设定,取值范围0-65535
返回值 :无
描述 :12T/Fosc11.0592M毫秒级延时
====================================*/
void delay(uint z){
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
/*====================================
描述 :4位共阴数码管动态显示 不带小数点
====================================*/
void display(uchar num1, uchar num2,uchar num3, uchar num4){
/*第一位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table1[num1];//
DU = 0;//锁存段选数据
delay(1);
/*第二位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFD; //1111 1101
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table1[num2];//
DU = 0;//锁存段选数据
delay(1);
/*第三位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFB; //1111 1011
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table1[num3];//
DU = 0;//锁存段选数据
delay(1);
/*第四位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XF7; //1111 0111
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table1[num4];//
DU = 0;//锁存段选数据
delay(1);
}
/*====================================
描述 :第i位 带小数点显示
====================================*/
void displaydot1(uchar num1,uint i){
/*第一位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = table3[i];//第i数码管显示
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table2[num1];//
DU = 0;//锁存段选数据
delay(1);
}
/*====================================
描述 :第i位 不带小数点显示
====================================*/
void display_no_dot1(uchar num1,uint i){
/*第一位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = table3[i];//第i数码管显示
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table1[num1];//
DU = 0;//锁存段选数据
delay(1);
}
/*====================================
描述 :合并显示
====================================*/
void displayall(uchar num1, uchar num2,uchar num3, uchar num4){
for(x = 1000; x > 0; x--){
for(y = 114; y > 0 ; y--);
display(num1,num2,num3,num4);
}
for(x = 1000; x > 0; x--){
for(y = 114; y > 0 ; y--);
display_no_dot1(num1,1);
display_no_dot1(num2,2);
displaydot1(num3,3) ;
display_no_dot1(num4,4);
}
for(x = 1000; x > 0; x--){
for(y = 114; y > 0 ; y--);
display_no_dot1(num1,1);
displaydot1(num2,2);
display_no_dot1(num3,3);
display_no_dot1(num4,4);
}
for(x = 1000; x > 0; x--){
for(y = 114; y > 0 ; y--);
displaydot1(num1,1);
display_no_dot1(num2,2);
display_no_dot1(num3,3);
display_no_dot1(num4,4);
}
}
/*====================================
函数 :KeyScan()
参数 :无
返回值 :无
描述 :4*4矩阵键盘与独立键盘扫描
按键按下KeyValue全局变量值发生相应变化
====================================*/
uchar KeyScan(){
uchar KeyValue = 20;//按键值 显示-
//4*4矩阵键盘扫描
P3 = 0XF0;//列扫描
if(P3 != 0XF0){ //判断按键是否被按下
delay(10);//软件消抖10ms
if(P3 != 0XF0){ // 判断按键是否被按下
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); // 软件消抖10ms
if(P3 != 0XFF){
switch(P3){ // 判断那一行被按下
case 0xfe:
KeyValue = 16;
break; // S2被按下
case 0xfd:
KeyValue = 17;
break; // S3被按下
case 0xfb:
KeyValue = 18;
break; // S4被按下
case 0xf7:
KeyValue = 19;
break; // S5被按下
}
while(P3 != 0XFF); // 松手检测
}
}
return KeyValue;
}
void main(){ // main函数自身会循环
while(1)
{
I_1=1;
I_2=5;
I_3=6;
I_4=8;
displayall(I_1,I_2,I_3,I_4);
displayall(I_2,I_3,I_4,I_1);
displayall(I_3,I_4,I_1,I_2);
displayall(I_4,I_1,I_2,I_3);
}
}
测试功能3 用矩阵接收数字并显示
#include <reg52.h>//包含51头文件
#include <intrins.h>//包含移位标准库函数头文件
#define uint unsigned int
#define uchar unsigned char
sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
uchar num;//数码管显示的值
uchar num1,num2,num3,num4;//按键值 显示-
//共阴数码管段选表
uchar code tabel[]= {
//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
};
/*====================================
函数 : delay(uint z)
参数 :z 延时毫秒设定,取值范围0-65535
返回值 :无
描述 :12T/Fosc11.0592M毫秒级延时
====================================*/
void delay(uint z){
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
/*====================================
函数 :KeyScan()
参数 :无
返回值 :无
描述 :4*4矩阵键盘与独立键盘扫描
按键按下KeyValue全局变量值发生相应变化
====================================*/
uchar KeyScan(void){
uchar KeyValue = 20;
//4*4矩阵键盘扫描
P3 = 0XF0;//列扫描
if(P3 != 0XF0){ //判断按键是否被按下
delay(10);//软件消抖10ms
if(P3 != 0XF0){ // 判断按键是否被按下
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); // 软件消抖10ms
if(P3 != 0XFF){
switch(P3){ // 判断那一行被按下
case 0xfe:
KeyValue = 16;
break; // S2被按下
case 0xfd:
KeyValue = 17;
break; // S3被按下
case 0xfb:
KeyValue = 18;
break; // S4被按下
case 0xf7:
KeyValue = 19;
break; // S5被按下
}
while(P3 != 0XFF); // 松手检测
}
}
return KeyValue ;
}
void main(){ // main函数自身会循环
while(1){
num1=KeyScan(); // 20个按键键盘扫描 ,记入第一位数字
if(num1!=20)
break; //
}
while(1){
num2=KeyScan();
if(num2!=20)
break; // 显示按键值
}
while(1){
num3=KeyScan();
if(num3!=20)
break; // 显示按键值
}
while(1){
num4=KeyScan();
if(num4!=20)
break; // 显示按键值
}
WE = 1; // 打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0; // 锁存位选数据
DU = 1; // 打开段选锁存器
while(1){
P0 = tabel[num1];
delay(100);
P0 = tabel[num2];
delay(100);
P0 = tabel[num3];
delay(100);
P0 = tabel[num4];
delay(100);
// 显示按键值
}
}
最终版
#include <reg52.h>//包含51头文件
#include <intrins.h>//包含移位标准库函数头文件
#define uint unsigned int
#define uchar unsigned char
sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
uchar num;//数码管显示的值
uchar I_1 ,I_2,I_3,I_4,temp_5;
uchar num1,num2,num3,num4;//按键值 显示-
uint x,y;
//共阴数码管段选表 不带小数点
uchar code table1[]= {
//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
};
//共阴数码管段选表 带小数点 +8即可
uchar code table2[16]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7,0xfc,0xb9,0xde,0xf9,0xf1};
// 控制第几个数码管亮1111 1110 1111 1101 1111 1011 1111 0111
uchar code table3[5]={0xFF,0xFE,0xFD,0xFB,0xF7};
/*====================================
函数 : delay(uint z)
参数 :z 延时毫秒设定,取值范围0-65535
返回值 :无
描述 :12T/Fosc11.0592M毫秒级延时
====================================*/
void delay(uint z){
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
/*====================================
描述 :4位共阴数码管动态显示 不带小数点
====================================*/
void display(uchar num1, uchar num2,uchar num3, uchar num4){
/*第一位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table1[num1];//
DU = 0;//锁存段选数据
delay(1);
/*第二位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFD; //1111 1101
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table1[num2];//
DU = 0;//锁存段选数据
delay(1);
/*第三位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFB; //1111 1011
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table1[num3];//
DU = 0;//锁存段选数据
delay(1);
/*第四位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XF7; //1111 0111
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table1[num4];//
DU = 0;//锁存段选数据
delay(1);
}
/*====================================
描述 :第i位 带小数点显示
====================================*/
void displaydot1(uchar num1,uint i){
/*第一位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = table3[i];//第i数码管显示
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table2[num1];//
DU = 0;//锁存段选数据
delay(1);
}
/*====================================
描述 :第i位 不带小数点显示
====================================*/
void display_no_dot1(uchar num1,uint i){
/*第一位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = table3[i];//第i数码管显示
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table1[num1];//
DU = 0;//锁存段选数据
delay(1);
}
/*====================================
描述 :合并显示
====================================*/
void displayall(uchar num1, uchar num2,uchar num3, uchar num4){
for(x = 1000; x > 0; x--){
for(y = 114; y > 0 ; y--);
display(num1,num2,num3,num4);
}
for(x = 1000; x > 0; x--){
for(y = 114; y > 0 ; y--);
display_no_dot1(num1,1);
display_no_dot1(num2,2);
displaydot1(num3,3) ;
display_no_dot1(num4,4);
}
for(x = 1000; x > 0; x--){
for(y = 114; y > 0 ; y--);
display_no_dot1(num1,1);
displaydot1(num2,2);
display_no_dot1(num3,3);
display_no_dot1(num4,4);
}
for(x = 1000; x > 0; x--){
for(y = 114; y > 0 ; y--);
displaydot1(num1,1);
display_no_dot1(num2,2);
display_no_dot1(num3,3);
display_no_dot1(num4,4);
}
}
/*====================================
函数 :KeyScan()
参数 :无
返回值 :无
描述 :4*4矩阵键盘与独立键盘扫描
按键按下KeyValue全局变量值发生相应变化
====================================*/
uchar KeyScan(void){
uchar KeyValue = 20;
//4*4矩阵键盘扫描
P3 = 0XF0;//列扫描
if(P3 != 0XF0){ //判断按键是否被按下
delay(10);//软件消抖10ms
if(P3 != 0XF0){ // 判断按键是否被按下
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); // 软件消抖10ms
if(P3 != 0XFF){
switch(P3){ // 判断那一行被按下
case 0xfe:
KeyValue = 16;
break; // S2被按下
case 0xfd:
KeyValue = 17;
break; // S3被按下
case 0xfb:
KeyValue = 18;
break; // S4被按下
case 0xf7:
KeyValue = 19;
break; // S5被按下
}
while(P3 != 0XFF); // 松手检测
}
}
return KeyValue ;
}
void main(){ // main函数自身会循环
while(1){
I_1=KeyScan(); // 20个按键键盘扫描 ,记入第一位数字
if(I_1!=20)
break; //
}
while(1){
I_2=KeyScan();
if(I_2!=20)
break; // 显示按键值
}
while(1){
I_3=KeyScan();
if(I_3!=20)
break; // 显示按键值
}
while(1){
I_4=KeyScan();
if(I_4!=20)
break; // 显示按键值
}
WE = 1; // 打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0; // 锁存位选数据
DU = 1; // 打开段选锁存器
while(1){
displayall(I_1,I_2,I_3,I_4);
displayall(I_2,I_3,I_4,I_1);
displayall(I_3,I_4,I_1,I_2);
displayall(I_4,I_1,I_2,I_3);
}
}
自行设计1 输入4位0~F 的移位显示
#include <reg52.h>//包含51头文件
#include <intrins.h>//包含移位标准库函数头文件
#define uint unsigned int
#define uchar unsigned char
sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
uchar num;//数码管显示的值
uchar I_1 ,I_2,I_3,I_4,temp_5;
uchar num1,num2,num3,num4;//按键值 显示-
uint x,y;
//共阴数码管段选表 不带小数点
uchar code table1[]= {
//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
};
//共阴数码管段选表 带小数点 +8即可
uchar code table2[16]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7,0xfc,0xb9,0xde,0xf9,0xf1};
// 控制第几个数码管亮1111 1110 1111 1101 1111 1011 1111 0111
uchar code table3[5]={0xFF,0xFE,0xFD,0xFB,0xF7};
/*====================================
函数 : delay(uint z)
参数 :z 延时毫秒设定,取值范围0-65535
返回值 :无
描述 :12T/Fosc11.0592M毫秒级延时
====================================*/
void delay(uint z){
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
/*====================================
描述 :4位共阴数码管动态显示 不带小数点
====================================*/
void display(uchar num1, uchar num2,uchar num3, uchar num4){
/*第一位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table1[num1];//
DU = 0;//锁存段选数据
delay(1);
/*第二位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFD; //1111 1101
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table1[num2];//
DU = 0;//锁存段选数据
delay(1);
/*第三位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFB; //1111 1011
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table1[num3];//
DU = 0;//锁存段选数据
delay(1);
/*第四位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XF7; //1111 0111
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table1[num4];//
DU = 0;//锁存段选数据
delay(1);
}
/*====================================
描述 :第i位 带小数点显示
====================================*/
void displaydot1(uchar num1,uint i){
/*第一位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = table3[i];//第i数码管显示
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table2[num1];//
DU = 0;//锁存段选数据
delay(1);
}
/*====================================
描述 :第i位 不带小数点显示
====================================*/
void display_no_dot1(uchar num1,uint i){
/*第一位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = table3[i];//第i数码管显示
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table1[num1];//
DU = 0;//锁存段选数据
delay(1);
}
/*====================================
描述 :合并显示
====================================*/
void displayall(uchar num1, uchar num2,uchar num3, uchar num4){
for(x = 1000; x > 0; x--){
for(y = 114; y > 0 ; y--);
display(num1,num2,num3,num4);
}
}
/*====================================
函数 :KeyScan()
参数 :无
返回值 :无
描述 :4*4矩阵键盘与独立键盘扫描
按键按下KeyValue全局变量值发生相应变化
====================================*/
uchar KeyScan(void){
uchar KeyValue = 20;
//4*4矩阵键盘扫描
P3 = 0XF0;//列扫描
if(P3 != 0XF0){ //判断按键是否被按下
delay(10);//软件消抖10ms
if(P3 != 0XF0){ // 判断按键是否被按下
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); // 软件消抖10ms
if(P3 != 0XFF){
switch(P3){ // 判断那一行被按下
case 0xfe:
KeyValue = 16;
break; // S2被按下
case 0xfd:
KeyValue = 17;
break; // S3被按下
case 0xfb:
KeyValue = 18;
break; // S4被按下
case 0xf7:
KeyValue = 19;
break; // S5被按下
}
while(P3 != 0XFF); // 松手检测
}
}
return KeyValue ;
}
void main(){ // main函数自身会循环
while(1){
I_1=KeyScan(); // 20个按键键盘扫描 ,记入第一位数字
if(I_1!=20)
break; //
}
while(1){
I_2=KeyScan();
if(I_2!=20)
break; // 显示按键值
}
while(1){
I_3=KeyScan();
if(I_3!=20)
break; // 显示按键值
}
while(1){
I_4=KeyScan();
if(I_4!=20)
break; // 显示按键值
}
WE = 1; // 打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0; // 锁存位选数据
DU = 1; // 打开段选锁存器
while(1){
displayall(I_1,I_2,I_3,I_4);
displayall(I_2,I_3,I_4,I_1);
displayall(I_3,I_4,I_1,I_2);
displayall(I_4,I_1,I_2,I_3);
}
}
自行设计2 8位数码管的移位显示
/*
displayall(I_1,I_2,I_3,I_4,I_5,I_6,I_7,I_8);
displayall(I_2,I_3,I_4,I_5,I_6,I_7,I_8,I_1);
displayall(I_3,I_4,I_5,I_6,I_7,I_8,I_1,I_2);
displayall(I_4,I_5,I_6,I_7,I_8,I_1,I_2,I_3);
displayall(I_5,I_6,I_7,I_8,I_1,I_2,I_3,I_4);
displayall(I_6,I_7,I_8,I_1,I_2,I_3,I_4,I_5);
displayall(I_7,I_8,I_1,I_2,I_3,I_4,I_5,I_6);
displayall(I_8,I_1,I_2,I_3,I_4,I_5,I_6,I_7);
*/
#include <reg52.h>//包含51头文件
#include <intrins.h>//包含移位标准库函数头文件
#define uint unsigned int
#define uchar unsigned char
sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
uchar num;//数码管显示的值
uchar I_1 ,I_2,I_3,I_4,I_5,I_6,I_7,I_8,temp_5;
uchar num1,num2,num3,num4,num5,num6,num7,num8;//按键值 显示-
uint x,y;
//共阴数码管段选表 不带小数点
uchar code table1[]= {
//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
};
//共阴数码管段选表 带小数点 +8即可
uchar code table2[16]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7,0xfc,0xb9,0xde,0xf9,0xf1};
// 控制第几个数码管亮1111 1110 1111 1101 1111 1011 1111 0111
uchar code table3[10]={0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
/*====================================
函数 : delay(uint z)
参数 :z 延时毫秒设定,取值范围0-65535
返回值 :无
描述 :12T/Fosc11.0592M毫秒级延时
====================================*/
void delay(uint z){
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
/*====================================
描述 :第i位 带小数点显示
====================================*/
void displaydot1(uchar num1,uint i){
/*第一位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = table3[i];//第i数码管显示
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table2[num1];//
DU = 0;//锁存段选数据
delay(1);
}
/*====================================
描述 :第i位 不带小数点显示
====================================*/
void display_no_dot1(uchar num1,uint i){
/*第一位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = table3[i];//第i数码管显示
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table1[num1];//
DU = 0;//锁存段选数据
delay(1);
}
void display(uchar num1, uchar num2,uchar num3, uchar num4){
/*第一位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table1[num1];//
DU = 0;//锁存段选数据
delay(1);
/*第二位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFD; //1111 1101
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table1[num2];//
DU = 0;//锁存段选数据
delay(1);
/*第三位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFB; //1111 1011
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table1[num3];//
DU = 0;//锁存段选数据
delay(1);
/*第四位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XF7; //1111 0111
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = table1[num4];//
DU = 0;//锁存段选数据
delay(1);
}
/*====================================
描述 :合并显示
====================================*/
void displayall(uchar num1, uchar num2,uchar num3, uchar num4,uchar num5, uchar num6,uchar num7, uchar num8){
for(x = 100; x > 0; x--){
for(y = 114; y > 0 ; y--);
display_no_dot1(num1,1);
display_no_dot1(num2,2);
display_no_dot1(num3,3);
display_no_dot1(num4,4);
display_no_dot1(num5,5);
display_no_dot1(num6,6);
display_no_dot1(num7,7);
display_no_dot1(num8,8);
}
for(x = 100; x > 0; x--){
for(y = 114; y > 0 ; y--);
display_no_dot1(num1,1);
display_no_dot1(num2,2);
display_no_dot1(num3,3);
display_no_dot1(num4,4);
display_no_dot1(num5,5);
display_no_dot1(num6,6);
displaydot1(num7,7);
display_no_dot1(num8,8);
}
for(x = 100; x > 0; x--){
for(y = 114; y > 0 ; y--);
display_no_dot1(num1,1);
display_no_dot1(num2,2);
display_no_dot1(num3,3);
display_no_dot1(num4,4);
display_no_dot1(num5,5);
displaydot1(num6,6);
display_no_dot1(num7,7);
display_no_dot1(num8,8);
}
for(x = 100; x > 0; x--){
for(y = 114; y > 0 ; y--);
display_no_dot1(num1,1);
display_no_dot1(num2,2);
display_no_dot1(num3,3);
display_no_dot1(num4,4);
displaydot1(num5,5);
display_no_dot1(num6,6);
display_no_dot1(num7,7);
display_no_dot1(num8,8);
}
for(x = 100; x > 0; x--){
for(y = 114; y > 0 ; y--);
display_no_dot1(num1,1);
display_no_dot1(num2,2);
display_no_dot1(num3,3);
displaydot1(num4,4);
display_no_dot1(num5,5);
display_no_dot1(num6,6);
display_no_dot1(num7,7);
display_no_dot1(num8,8);
}
for(x = 100; x > 0; x--){
for(y = 114; y > 0 ; y--);
display_no_dot1(num1,1);
display_no_dot1(num2,2);
displaydot1(num3,3);
display_no_dot1(num4,4);
display_no_dot1(num5,5);
display_no_dot1(num6,6);
display_no_dot1(num7,7);
display_no_dot1(num8,8);
}
for(x = 100; x > 0; x--){
for(y = 114; y > 0 ; y--);
display_no_dot1(num1,1);
displaydot1(num2,2);
display_no_dot1(num3,3);
display_no_dot1(num4,4);
display_no_dot1(num5,5);
display_no_dot1(num6,6);
display_no_dot1(num7,7);
display_no_dot1(num8,8);
}
for(x = 100; x > 0; x--){
for(y = 114; y > 0 ; y--);
displaydot1(num1,1);
display_no_dot1(num2,2);
display_no_dot1(num3,3);
display_no_dot1(num4,4);
display_no_dot1(num5,5);
display_no_dot1(num6,6);
display_no_dot1(num7,7);
display_no_dot1(num8,8);
}
}
/*====================================
函数 :KeyScan()
参数 :无
返回值 :无
描述 :4*4矩阵键盘与独立键盘扫描
按键按下KeyValue全局变量值发生相应变化
====================================*/
uchar KeyScan(void){
uchar KeyValue = 20;
//4*4矩阵键盘扫描
P3 = 0XF0;//列扫描
if(P3 != 0XF0){ //判断按键是否被按下
delay(10);//软件消抖10ms
if(P3 != 0XF0){ // 判断按键是否被按下
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); // 软件消抖10ms
if(P3 != 0XFF){
switch(P3){ // 判断那一行被按下
case 0xfe:
KeyValue = 16;
break; // S2被按下
case 0xfd:
KeyValue = 17;
break; // S3被按下
case 0xfb:
KeyValue = 18;
break; // S4被按下
case 0xf7:
KeyValue = 19;
break; // S5被按下
}
while(P3 != 0XFF); // 松手检测
}
}
return KeyValue ;
}
void main(){ // main函数自身会循环
while(1){
I_1=KeyScan(); // 20个按键键盘扫描 ,记入第一位数字
if(I_1!=20)
break; //
}
while(1){
I_2=KeyScan();
if(I_2!=20)
break; // 显示按键值
}
while(1){
I_3=KeyScan();
if(I_3!=20)
break; // 显示按键值
}
while(1){
I_4=KeyScan();
if(I_4!=20)
break; // 显示按键值
}
while(1){
I_5=KeyScan(); // 20个按键键盘扫描 ,记入第一位数字
if(I_5!=20)
break; //
}
while(1){
I_6=KeyScan();
if(I_6!=20)
break; // 显示按键值
}
while(1){
I_7=KeyScan();
if(I_7!=20)
break; // 显示按键值
}
while(1){
I_8=KeyScan();
if(I_8!=20)
break; // 显示按键值
}
WE = 1; // 打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0; // 锁存位选数据
DU = 1; // 打开段选锁存器
while(1){
displayall(I_1,I_2,I_3,I_4,I_5,I_6,I_7,I_8);
displayall(I_2,I_3,I_4,I_5,I_6,I_7,I_8,I_1);
displayall(I_3,I_4,I_5,I_6,I_7,I_8,I_1,I_2);
displayall(I_4,I_5,I_6,I_7,I_8,I_1,I_2,I_3);
displayall(I_5,I_6,I_7,I_8,I_1,I_2,I_3,I_4);
displayall(I_6,I_7,I_8,I_1,I_2,I_3,I_4,I_5);
displayall(I_7,I_8,I_1,I_2,I_3,I_4,I_5,I_6);
displayall(I_8,I_1,I_2,I_3,I_4,I_5,I_6,I_7);
}
}