电子爱好者的乐趣,想啥做啥,😄😄;不受拘束的想象力加上强大的动手能力,我们几乎能做绝大部分东西,下面我们来一起简单的”小试牛刀“,做个计算器耍耍。
使用到的东西元器件:4*4矩阵键盘,1602液晶模块,arduino uno开发板,220Ω电阻
1602液晶模块连接注意的引脚:
VCC: 液晶模块供电正极
LED+:背光灯正极连接电源正极VCC
LED-:背光灯负极通过220Ω限流电阻连接负极GND
VO:设置液晶偏置电压连接至GND
RW:读写模式引脚,我们这里只要写,所以R/W接GND
GND:液晶模块供电负极
我们来看下实际运行效果:
矩阵键盘A,B,C,D分别代表 +,-,X,/; " * "代表清除," # "号代表" = "
代 码 部 分:
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
long first = 0;
long second = 0;
double total = 0;
char customKey;
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','+'},
{'4','5','6','-'},
{'7','8','9','*'},
{'C','0','=','/'}
};
byte rowPins[ROWS] = {7,6,5,4}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {3,2,1,0}; //connect to the column pinouts of the keypad
//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);
void setup()
{
lcd.begin(16, 2); // start lcd
for(int i=0;i<=3;i++);
lcd.setCursor(0,0);
lcd.print("Hello");
lcd.setCursor(0,1);
lcd.print("calc");
delay(4000);
lcd.clear();
lcd.setCursor(0, 0);
}
void loop()
{
customKey = customKeypad.getKey();
switch(customKey)
{
case '0' ... '9': // This keeps collecting the first value until a operator is pressed "+-*/"
lcd.setCursor(0,0);
first = first * 10 + (customKey - '0');
lcd.print(first);
break;
case '+':
first = (total != 0 ? total : first);
lcd.setCursor(0,1);
lcd.print("+");
second = SecondNumber(); // get the collected the second number
total = first + second;
lcd.setCursor(0,3);
lcd.print(total);
first = 0, second = 0; // reset values back to zero for next use
break;
case '-':
first = (total != 0 ? total : first);
lcd.setCursor(0,1);
lcd.print("-");
second = SecondNumber();
total = first - second;
lcd.setCursor(0,3);
lcd.print(total);
first = 0, second = 0;
break;
case '*':
first = (total != 0 ? total : first);
lcd.setCursor(0,1);
lcd.print("*");
second = SecondNumber();
total = first * second;
lcd.setCursor(0,3);
lcd.print(total);
first = 0, second = 0;
break;
case '/':
first = (total != 0 ? total : first);
lcd.setCursor(0,1);
lcd.print("/");
second = SecondNumber();
lcd.setCursor(0,3);
second == 0 ? lcd.print("Invalid") : total = (float)first / (float)second;
lcd.print(total);
first = 0, second = 0;
break;
case 'C':
total = 0;
lcd.clear();
break;
}
}
long SecondNumber()
{
while( 1 )
{
customKey = customKeypad.getKey();
if(customKey >= '0' && customKey <= '9')
{
second = second * 10 + (customKey - '0');
lcd.setCursor(0,2);
lcd.print(second);
}
if(customKey == '=') break; //return second;
}
return second;
}
代码解释:
我们这里用了arduino自带的液晶库#include <LiquidCrystal.h>和按键库#include <Keypad.h>
这样我们只要将重心挪到计算器核心的算法开发上就好了。
定义四线驱动1602的引脚:
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
按键行和列符号定义:
char keys[ROWS][COLS] = {
{'1','2','3','+'},
{'4','5','6','-'},
{'7','8','9','*'},
{'C','0','=','/'}
};
按键行和列引脚定义:
byte rowPins[ROWS] = {7,6,5,4};
byte colPins[COLS] = {3,2,1,0};
按键符号与行列引脚关联:
Keypad customKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);
第一个部分运算字符输入处理:
case '0' ... '9':
lcd.setCursor(0,0);
first = first * 10 + (customKey - '0');
lcd.print(first);
break;
加法处理部分:
case '+':
first = (total != 0 ? total : first);
lcd.setCursor(0,1);
lcd.print("+");
second = SecondNumber();
total = first + second;
lcd.setCursor(0,3);
lcd.print(total);
first = 0, second = 0;
break;
减法处理部分:
case '-':
first = (total != 0 ? total : first);
lcd.setCursor(0,1);
lcd.print("-");
second = SecondNumber();
total = first - second;
lcd.setCursor(0,3);
lcd.print(total);
first = 0, second = 0;
break;
乘法处理部分:
case '*':
first = (total != 0 ? total : first);
lcd.setCursor(0,1);
lcd.print("*");
second = SecondNumber();
total = first * second;
lcd.setCursor(0,3);
lcd.print(total);
first = 0, second = 0;
break;
除法处理部分:除法里面还做了除0非法操作
case '/':
first = (total != 0 ? total : first);
lcd.setCursor(0,1);
lcd.print("/");
second = SecondNumber();
lcd.setCursor(0,3);
second == 0 ? lcd.print("Invalid") : total = (float)first / (float)second;
lcd.print(total);
first = 0, second = 0;
break;
清除计算处理:
case 'C':
total = 0;
lcd.clear();
break;
另外还有第二个数据字符输入处理:
long SecondNumber()
{
while( 1 )
{
customKey = customKeypad.getKey();
if(customKey >= '0' && customKey <= '9')
{
second = second * 10 + (customKey - '0');
lcd.setCursor(0,2);
lcd.print(second);
}
if(customKey == '=') break; //return second;
}
return second;
}
我们输入第一个数据字符串后,如果检测到有输入运算符,那么就直接进入到第二个数据字符串里面,一直到有输入“=”符号,输出计算结果,并跳出当前计算;注意到每个数据字符串里面还做了数据转换,将字符转换为十进制数。
大家可以思考下?
我们看到里面的数据定义都是long型的,如果超过long型所能表达的最大数据会出现什么情况?又该如何处理?大家可以尝试去完善下。
另外我们这里面基本上都是调用arduino的库函数在处理,如果放到51单片机上或者其它单片机上,那么又该如何操作?这些函数大家都可以大胆的去尝试实现。