51单片机新手小白,想要用矩阵按键和八位共阴极数码管实现简单计算器(三位数运算,输出八位),但是写出来数码管不能正常显示,求大佬支招;
#include "reg52.h"
typedef unsigned int u16;
typedef unsigned char u8;
#define KEY_MATRIX_PORT P1 //使用宏定义矩阵按键控制口
#define SMG_A_DP_PORT P0 //宏定义数码管段码口
//数码管位选信号控制脚 ps:通过控制脚排列二进制决定位选数码管
sbit LSA = P2 ^ 2;
sbit LSB = P2 ^ 3;
sbit LSC = P2 ^ 4;
//定义数组 用于储存数码管显示0~F的断码数据
u8 gsmg_code[17] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71
};
//使用宏定义矩阵按键按下的键值
#define K1 1
#define K2 2
#define K3 3
#define K4 4
#define K5 5
#define K6 6
#define K7 7
#define K8 8
#define K9 9
#define K0 10
#define KPl 11
#define KMi 12
#define KTi 13
#define KDi 14
#define Del 15
#define Equ 16
#define Kno 0
//定义延时函数
void delay_10us(u16 ten_us) {
while (ten_us--);
}
//判断按键函数
u8 key_matrix_ranks_scan(void) {
u8 key_value = 0;
KEY_MATRIX_PORT = 0xf7; //给第一列赋值0,其余全为1
if (KEY_MATRIX_PORT != 0xf7) { //判断第一列按键是否按下
delay_10us(1000);//消抖
switch (KEY_MATRIX_PORT) { //保存第一列按键按下后的键值
case 0x77:
return K1;
case 0xb7:
return K4;
case 0xd7:
return K7;
case 0xe7:
return K0;//零
}
}
while (KEY_MATRIX_PORT != 0xf7); //等待按键松开
KEY_MATRIX_PORT = 0xfb; //给第二列赋值0,其余全为1
if (KEY_MATRIX_PORT != 0xfb) { //判断第二列按键是否按下
delay_10us(1000);//消抖
switch (KEY_MATRIX_PORT) { //保存第二列按键按下后的键值
case 0x7b:
return K2;
case 0xbb:
return K5;
case 0xdb:
return K8;
case 0xeb:
return KTi;//乘
}
}
while (KEY_MATRIX_PORT != 0xfb); //等待按键松开
KEY_MATRIX_PORT = 0xfd; //给第三列赋值0,其余全为1
if (KEY_MATRIX_PORT != 0xfd) { //判断第三列按键是否按下
delay_10us(1000);//消抖
switch (KEY_MATRIX_PORT) { //保存第三列按键按下后的键值
case 0x7d:
return K3;
case 0xbd:
return K6;
case 0xdd:
return K9;
case 0xed:
return KDi;//除
}
}
while (KEY_MATRIX_PORT != 0xfd); //等待按键松开
KEY_MATRIX_PORT = 0xfe; //给第四列赋值0,其余全为1
if (KEY_MATRIX_PORT != 0xfe) { //判断第四列按键是否按下
delay_10us(1000);//消抖
switch (KEY_MATRIX_PORT) { //保存第四列按键按下后的键值
case 0x7e:
return Del;//消除
case 0xbe:
return KPl;//加
case 0xde:
return KMi;//减
case 0xee:
return Equ;//等于
}
}
while (KEY_MATRIX_PORT != 0xfe); //等待按键松开
return Kno;
}
void main() {
u8 A[3] = {0}, B[3] = {0}, C[8] = {0};
u8 Fu = 0, K = 0, M = 0, N = 0, m = 0, n = 0, a = 0, b = 0, c = 0;
while (1) {
u8 i = 0, j = 0;
K = key_matrix_ranks_scan();
//判断按键函数
if (K > 10 && K < 15) {
M++;
m = N - 1; //m储存A[]数组长度;
N = 0;
Fu = K; //Fu储存符号信息;
}
switch (K) { //转存数据;M-判断符号输入;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
if (M == 0) {
A[N] = K;
N++;
} else if (M == 1) {
B[N] = K;
N++;
}
break;
case 11:
case 12:
case 13:
case 14:
break;
case 15:
if (M == 0 && N != 0) {
N--;
A[N] = 0;
} else if (M == 1) {
if (N == 0) {
M = 0;
Fu = 0;
N = m;
} else {
N--;
B[N] = 0;
}
}
break;
case 16:
M++;
break;
default:
break;
}
for (i = 2; i >= 0; i--) {
if (A[i] > 9) A[i] = 0;
if (B[i] > 9) B[i] = 0;
}
if (M == 0) {
for (i = 2, j = N - 1; j >= 0; i--, j--) {
C[i] = A[j];
}
} else if (M == 1) {
C[3] = Fu;
for (i = 7, j = N - 1; j >= 0; i--, j--) {
C[i] = B[j];
}
}
if (M == 2) {
for (i = 0; i < 8; i++) {
C[i] = 0;
}
a = A[0] * 100 + A[1] * 10 + A[2];
b = B[0] * 100 + B[1] * 10 + B[2];
switch (Fu) {
case 11:
c = a + b;
break;
case 12:
if (a >= b) c = a - b;
break;
case 13:
c = a*b;
break;
case 14:
if (b != 0) c = a / b;
break;
}
for (i = 7, n = 10; c >= 0; i--) {
C[i] = c % 10;
c = c / 10;
}
}
for (i = 0; i < 8; i++) {
c = C[i];
switch (i) { //位选
case 0:
LSC = 1;
LSB = 1;
LSA = 1;
break;
case 1:
LSC = 1;
LSB = 1;
LSA = 0;
break;
case 2:
LSC = 1;
LSB = 0;
LSA = 1;
break;
case 3:
LSC = 1;
LSB = 0;
LSA = 0;
break;
case 4:
LSC = 0;
LSB = 1;
LSA = 1;
break;
case 5:
LSC = 0;
LSB = 1;
LSA = 0;
break;
case 6:
LSC = 0;
LSB = 0;
LSA = 1;
break;
case 7:
LSC = 0;
LSB = 0;
LSA = 0;
break;
}
SMG_A_DP_PORT = gsmg_code[c]; //传送段选数据
delay_10us(100);//延时一段时间,等待显示稳定
SMG_A_DP_PORT = 0x00; //消音
}
}
}
这样写可以显示但输入的数A为AAA格式显示;
#include "reg52.h"
typedef unsigned int u16;
typedef unsigned char u8;
#define KEY_MATRIX_PORT P1 //使用宏定义矩阵按键控制口
#define SMG_A_DP_PORT P0 //宏定义数码管段码口
//数码管位选信号控制脚 ps:通过控制脚排列二进制决定位选数码管
sbit LSA = P2 ^ 2;
sbit LSB = P2 ^ 3;
sbit LSC = P2 ^ 4;
//定义数组 用于储存数码管显示0~F的断码数据
u8 gsmg_code[17] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71
};
//使用宏定义矩阵按键按下的键值
#define KEY1_PRESS 1
#define KEY2_PRESS 2
#define KEY3_PRESS 3
#define KEY4_PRESS 4
#define KEY5_PRESS 5
#define KEY6_PRESS 6
#define KEY7_PRESS 7
#define KEY8_PRESS 8
#define KEY9_PRESS 9
#define KEY0_PRESS 10
#define KEYTimes_PRESS 11
#define KEYdivi_PRESS 12
#define KEYPlus_PRESS 13
#define KEYMinus_PRESS 14
#define KEYDEL_PRESS 15
#define KEYEQU_PRESS 16
#define KEY_UNPRESS 0
//定义延时函数
void delay_10us(u16 ten_us) {
while (ten_us--);
}
//判断按键函数
u8 key_matrix_ranks_scan(void) {
u8 key_value = 0;
KEY_MATRIX_PORT = 0xf7; //给第一列赋值0,其余全为1
if (KEY_MATRIX_PORT != 0xf7) { //判断第一列按键是否按下
delay_10us(1000);//消抖
switch (KEY_MATRIX_PORT) { //保存第一列按键按下后的键值
case 0x77:
return KEY1_PRESS;
case 0xb7:
return KEY4_PRESS;
case 0xd7:
return KEY7_PRESS;
case 0xe7:
return KEY0_PRESS;//零
}
}
while (KEY_MATRIX_PORT != 0xf7); //等待按键松开
KEY_MATRIX_PORT = 0xfb; //给第二列赋值0,其余全为1
if (KEY_MATRIX_PORT != 0xfb) { //判断第二列按键是否按下
delay_10us(1000);//消抖
switch (KEY_MATRIX_PORT) { //保存第二列按键按下后的键值
case 0x7b:
return KEY2_PRESS;
case 0xbb:
return KEY5_PRESS;
case 0xdb:
return KEY8_PRESS;
case 0xeb:
return KEYTimes_PRESS;//乘
}
}
while (KEY_MATRIX_PORT != 0xfb); //等待按键松开
KEY_MATRIX_PORT = 0xfd; //给第三列赋值0,其余全为1
if (KEY_MATRIX_PORT != 0xfd) { //判断第三列按键是否按下
delay_10us(1000);//消抖
switch (KEY_MATRIX_PORT) { //保存第三列按键按下后的键值
case 0x7d:
return KEY3_PRESS;
case 0xbd:
return KEY6_PRESS;
case 0xdd:
return KEY9_PRESS;
case 0xed:
return KEYdivi_PRESS;//除
}
}
while (KEY_MATRIX_PORT != 0xfd); //等待按键松开
KEY_MATRIX_PORT = 0xfe; //给第四列赋值0,其余全为1
if (KEY_MATRIX_PORT != 0xfe) { //判断第四列按键是否按下
delay_10us(1000);//消抖
switch (KEY_MATRIX_PORT) { //保存第四列按键按下后的键值
case 0x7e:
return KEYDEL_PRESS;//消除
case 0xbe:
return KEYPlus_PRESS;//加
case 0xde:
return KEYMinus_PRESS;//减
case 0xee:
return KEYEQU_PRESS;//等于
}
}
while (KEY_MATRIX_PORT != 0xfe); //等待按键松开
return KEY_UNPRESS;
}
void main() {
u8 A[3] = {0}, B[3] = {0}, C[8] = {0}, All[8];
u8 K = 0, j = 0, fu = 0, Fu = 0, a = 0, b = 0, c = 0;
while (1) {
u8 i = 0, n = 0, sc = 0;
K = key_matrix_ranks_scan();
//插入判断按键函数
if (K > 10 && K < 15) {
fu = 1;
Fu = K;
}
switch (K) {//j-判断位数,sc-判断有效输入,fu-判断符号输入
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
All[j] = K;
if (j < 8) {
j++;
sc = 1;
}
break;
case 11:
case 12:
case 13:
case 14:
sc = 0;
break;
case 15:
if (j != 0) {
j--;
All[j] = 0;
sc = 1;
}
break;
case 16:
fu = 2;
break;
default:
break;
}
switch (j) {
case 1:A[2]=All[0];
//TODO
break;
case 2:A[1]=All[0];
A[2]=All[1];
//TODO
break;
case 3:A[0]=All[0];
A[1]=All[1];
A[2]=All[2];
//TODO
break;
case 4:A[0]=All[0];
A[1]=All[1];
A[2]=All[2];
B[2]=All[3];
//TODO
break;
case 5:A[0]=All[0];
A[1]=All[1];
A[2]=All[2];
B[1]=All[3];
B[2]=All[4];
//TODO
break;
case 6:A[0]=All[0];
A[1]=All[1];
A[2]=All[2];
B[0]=All[3];
B[1]=All[4];
B[2]=All[5];
//TODO
break;
default:
//TODO
break;
}
for (i = 2; i > 0; i--) {
if (A[i] > 9) A[i] = A[i] - 10;
if (B[i] > 9) B[i] = B[i] - 10;
}
if (fu < 2) {
for (i = 0; i < 3; i++) {
C[i] = A[i];
}
if (fu == 1) {
C[3] = Fu;
for (i = 0; i < 3; i++) {
C[i + 5] = B[i];
}
}
}
if (fu == 2) {
for (i = 0; i < 8; i++) {
C[i] = 0;
//TODO
}
a = A[0] * 100 + A[1] * 10 + A[2];
b = B[0] * 100 + B[1] * 10 + B[2];
switch (Fu) {
case 13:
c = a + b;
//TODO
break;
case 14:
c = a - b;
//TODO
break;
case 11:
c = a*b;
//TODO
break;
case 12:
if (b != 0) c = a / b;
//TODO
break;
}
for (i = 7, n = 10; c >= 0; i--) {
C[i] = c % 10;
c = c / 10;
//TODO
}
}
for (i = 0; i < 8; i++) {
c = C[i];
switch (i) { //位选
case 0:
LSC = 1;
LSB = 1;
LSA = 1;
break;
case 1:
LSC = 1;
LSB = 1;
LSA = 0;
break;
case 2:
LSC = 1;
LSB = 0;
LSA = 1;
break;
case 3:
LSC = 1;
LSB = 0;
LSA = 0;
break;
case 4:
LSC = 0;
LSB = 1;
LSA = 1;
break;
case 5:
LSC = 0;
LSB = 1;
LSA = 0;
break;
case 6:
LSC = 0;
LSB = 0;
LSA = 1;
break;
case 7:
LSC = 0;
LSB = 0;
LSA = 0;
break;
}
SMG_A_DP_PORT = gsmg_code[c]; //传送段选数据
delay_10us(100);//延时一段时间,等待显示稳定
SMG_A_DP_PORT = 0x00; //消音
}
}
}