网站与网站之间做的好坏对比,新能源电动汽车电池价格,辽宁省建设科学研究院网站,alexa排名前三十本文对矩阵按键的一个扩展#xff0c;利用矩阵按键和动态数码管设计一个简易计算器。代码参考#xff1a;https://blog.csdn.net/weixin_47060099/article/details/106664393 实现功能#xff1a;使用矩阵按键#xff0c;实现一个简易计算器#xff0c;将计算数据及计算结… 本文对矩阵按键的一个扩展利用矩阵按键和动态数码管设计一个简易计算器。代码参考https://blog.csdn.net/weixin_47060099/article/details/106664393 实现功能使用矩阵按键实现一个简易计算器将计算数据及计算结果显示在数码管中。
矩阵按键设计如下图 代码实现
/*实现功能使用矩阵按键实现简易计算器[2023-12-07] zoya
*/
#include reg52.htypedef unsigned char u8;
typedef unsigned int u16;sbit LSA P2^2;
sbit LSB P2^3;
sbit LSC P2^4;#define GPIO_DIG P0 // 动态数码管
#define GPIO_KEY P1 // 矩阵按键u16 KeyValue; // 存放读取到的键值
u16 keyflag, i; // 用来判断按下的数字还是运算符或是清空键
u8 code smg[] {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x00}; // 共阴极数码管u16 wei[8] {0}; // 存放每一位数码管数字的数组// 延时函数i1延时10us
void delay(u16 i)
{while(i--);
}// 扫描显示动态数码管
void Display()
{LSA 0; LSB 0; LSC 0; GPIO_DIG smg[wei[7]]; delay(50); GPIO_DIG 0x00; // 段选Y0位选显示延时消隐LSA 1; LSB 0; LSC 0; GPIO_DIG smg[wei[6]]; delay(50); GPIO_DIG 0x00; // 段选Y0位选显示延时消隐LSA 0; LSB 1; LSC 0; GPIO_DIG smg[wei[5]]; delay(50); GPIO_DIG 0x00; // 段选Y0位选显示延时消隐LSA 1; LSB 1; LSC 0; GPIO_DIG smg[wei[4]]; delay(50); GPIO_DIG 0x00; // 段选Y0位选显示延时消隐LSA 0; LSB 0; LSC 1; GPIO_DIG smg[wei[3]]; delay(50); GPIO_DIG 0x00; // 段选Y0位选显示延时消隐LSA 1; LSB 0; LSC 1; GPIO_DIG smg[wei[2]]; delay(50); GPIO_DIG 0x00; // 段选Y0位选显示延时消隐LSA 0; LSB 1; LSC 1; GPIO_DIG smg[wei[1]]; delay(50); GPIO_DIG 0x00; // 段选Y0位选显示延时消隐LSA 1; LSB 1; LSC 1; GPIO_DIG smg[wei[0]]; delay(50); GPIO_DIG 0x00; // 段选Y0位选显示延时消隐
}// 检测有按键按下并读取键值
void KeyDown()
{u16 a 0;GPIO_KEY 0x0f; // 行全部为低电平列全部为高电平if(0x0f ! GPIO_KEY) // 读取按键是否按下{delay(1000); // 延时10ms进行消隐if(0x0f ! GPIO_KEY){// 测试列GPIO_KEY 0x0f;switch(GPIO_KEY) // 行列扫描法{case 0x07: KeyValue 0; break;case 0x0b: KeyValue 1; break;case 0x0d: KeyValue 2; break;case 0x0e: KeyValue 3; break;}// 测试行GPIO_KEY 0xf0;switch(GPIO_KEY) // 行列扫描法{case 0x70: KeyValue KeyValue; break;case 0xb0: KeyValue KeyValue 4; break;case 0xd0: KeyValue KeyValue 8; break;case 0xe0: KeyValue KeyValue 12; break;}if(KeyValue0 || KeyValue1 || KeyValue2 || KeyValue3 || KeyValue4 || KeyValue5|| KeyValue6 || KeyValue7 || KeyValue8 || KeyValue9){keyflag1;}}while( (a 50) (GPIO_KEY ! 0xf0) ) // 按键松手检测{delay(1000);a;}}
}void main()
{u16 a0, b0, c0;while(1){Display(); KeyDown(); // 键入第一个数字if(1 keyflag){for(i7;i0;i--){wei[i] wei[i-1]; // 键入一位数字向左移动一位}wei[0] KeyValue;keyflag 0;}else if(14 KeyValue) // 清空显示{for(i0;i8;i){wei[i] 0;}Display();}else if(10 KeyValue) // 加法运算{a wei[0] wei[1]*10 wei[2]*100 wei[3]*1000 wei[4]*10000 wei[5]*100000 wei[6]*1000000 wei[7]*10000000;for(i0; i8; i){wei[i] 0;}// 输入第二个数while(1){Display();KeyDown(); // 输入第二个数if(15 KeyValue)break; // 当识别到等号时停止输入if(1 keyflag){for(i7; i0; i--){wei[i] wei[i-1];}wei[0] KeyValue;keyflag 0;}}b wei[0] wei[1]*10 wei[2]*100 wei[3]*1000 wei[4]*10000 wei[5]*100000 wei[6]*1000000 wei[7]*10000000;c a b;wei[0] c%10; // 计算C的各个位的数字wei[1] c/10%10;wei[2] c/100%10;wei[3] c/1000%10;wei[4] c/10000%10;wei[5] c/100000%10;wei[6] c/1000000%10;wei[7] c/10000000%10;Display();}else if(11 KeyValue) // 减法运算{a wei[0] wei[1]*10 wei[2]*100 wei[3]*1000 wei[4]*10000 wei[5]*100000 wei[6]*1000000 wei[7]*10000000;for(i0; i8; i) // 清空数码管{wei[i] 0;}// 输入第二个数while(1){Display();KeyDown(); // 输入第二个数if(15 KeyValue)break; // 当识别到等号时停止输入if(1 keyflag){for(i7; i0; i--){wei[i] wei[i-1];}wei[0] KeyValue;keyflag 0;}}b wei[0] wei[1]*10 wei[2]*100 wei[3]*1000 wei[4]*10000 wei[5]*100000 wei[6]*1000000 wei[7]*10000000;if(a b){c a - b;wei[0] c%10; // 计算C的各个位的数字wei[1] c/10%10;wei[2] c/100%10;wei[3] c/1000%10;wei[4] c/10000%10;wei[5] c/100000%10;wei[6] c/1000000%10;wei[7] c/10000000%10;}else if(a b){u16 e 0;c b-a;wei[0] c%10;wei[1] c/10%10;if(wei[1] 0){wei[1] 16;e1;}wei[2] c/100%10;if(wei[2]0 e0){wei[2] 16;e1;}wei[3] c/1000%10;if(wei[3]0 e0){wei[3] 16;e1;}wei[4] c/10000%10;if(wei[4]0 e0){wei[4] 16;e1;}wei[5] c/100000%10;if(wei[5]0 e0){wei[5] 16;e1;}wei[6] c/1000000%10;if(wei[6]0 e0){wei[6] 16;e1;}wei[7] c/10000000%10;if(wei[7]0 e0){wei[7] 16;e1;}}Display();}else if(12 KeyValue) // 乘法运算{a wei[0] wei[1]*10 wei[2]*100 wei[3]*1000 wei[4]*10000 wei[5]*100000 wei[6]*1000000 wei[7]*10000000;for(i0; i8; i){wei[i] 0;}// 输入第二个数while(1){Display();KeyDown(); // 输入第二个数if(15 KeyValue)break; // 当识别到等号时停止输入if(1 keyflag){for(i7; i0; i--){wei[i] wei[i-1];}wei[0] KeyValue;keyflag 0;}}b wei[0] wei[1]*10 wei[2]*100 wei[3]*1000 wei[4]*10000 wei[5]*100000 wei[6]*1000000 wei[7]*10000000;c a * b;wei[0] c%10; // 计算C的各个位的数字wei[1] c/10%10;wei[2] c/100%10;wei[3] c/1000%10;wei[4] c/10000%10;wei[5] c/100000%10;wei[6] c/1000000%10;wei[7] c/10000000%10;Display();}else if(13 KeyValue) // 除法运算{a wei[0] wei[1]*10 wei[2]*100 wei[3]*1000 wei[4]*10000 wei[5]*100000 wei[6]*1000000 wei[7]*10000000;for(i0; i8; i){wei[i] 0;}// 输入第二个数while(1){Display();KeyDown(); // 输入第二个数if(15 KeyValue)break; // 当识别到等号时停止输入if(1 keyflag){for(i7; i0; i--){wei[i] wei[i-1];}wei[0] KeyValue;keyflag 0;}}b wei[0] wei[1]*10 wei[2]*100 wei[3]*1000 wei[4]*10000 wei[5]*100000 wei[6]*1000000 wei[7]*10000000;if(0 ! b){c a / b;wei[0] c%10; // 计算C的各个位的数字wei[1] c/10%10;wei[2] c/100%10;wei[3] c/1000%10;wei[4] c/10000%10;wei[5] c/100000%10;wei[6] c/1000000%10;wei[7] c/10000000%10;Display();}}}
}仿真结果