进制转换器,实现16、10、8、2进制之间的转换
主控AT89C51 兼容STC89C51
仿真电路图proteus8.16 (需要安装包的私信作者)
#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define uchar unsigned char // 以后unsigned char就可以用uchar代替
#define uint unsigned int // 以后unsigned int 就可以用uint 代替
typedef unsigned char u8;
typedef unsigned int u16;
sbit LcdRs_P = P3 ^ 1; // 1602液晶的RS管脚
sbit LcdRw_P = P3 ^ 2; // 1602液晶的RW管脚
sbit LcdEn_P = P3 ^ 3; // 1602液晶的EN管脚
void LcdCmd(unsigned char cmd);
sbit srjz = P2 ^ 7; // 输入进制改变
sbit shiliujz = P2 ^ 6; // 16进制
sbit shijz = P2 ^ 5; // 10进制
sbit bajz = P2 ^ 4; // 8进制
sbit erjz = P2 ^ 3; // 2进制
sbit qp = P2 ^ 2; //清空屏幕
sbit row1 = P1 ^ 7; // 行引脚1
sbit row2 = P1 ^ 6; // 行引脚2
sbit row3 = P1 ^ 5; // 行引脚3
sbit row4 = P1 ^ 4; // 行引脚4
sbit col1 = P1 ^ 3; // 列引脚1
sbit col2 = P1 ^ 2; // 列引脚2
sbit col3 = P1 ^ 1; // 列引脚3
sbit col4 = P1 ^ 0; // 列引脚4
int i = 0;
int isNegative = 0;
int a,b,j;
char *y;
int strLen = 0;
char str[30] = ""; // 用于存储输入的字符组成的字符串
int strPos = 0; // 字符串位置
char num1[30]=""; // 用于存储输出的字符组成的字符串
int num; // 当前输入的数字
char temp; // 临时变量,交换两个值时用到
char key;
int base2 = 2; // 输出数字的进制,默认为二进制
int base1 = 10 ; // 输入数字的进制,默认为十进制
//int atoi(const char *nptr); // 字符串
/*********************************************************/
//将10进制的数转换为n(2<=n<36)进制
/*********************************************************/
char *itoa(int value, char *string, int radix); // value: 要转换的整数,string: 转换后的字符串,radix: 转换进制数,如2,8,10,16 进制等。
/*********************************************************/
//将2-36进制的数转换为10进制的数。
/*********************************************************/
long int strtol (const char* str, char** endptr, int base);
/*********************************************************/
// 毫秒级的延时函数,time是要延时的毫秒数
/*********************************************************/
void delay(uint time)
{
uint i, j;
for (i = 0; i < time; i++)
for (j = 0; j < 112; j++)
;
}
/*********************************************************/
// 1602液晶写命令函数,cmd就是要写入的命令
/*********************************************************/
void LcdWriteCmd(uchar cmd)
{
LcdRs_P = 0;
LcdRw_P = 0;
LcdEn_P = 0;
P0 = cmd;
delay(2);
LcdEn_P = 1;
delay(2);
LcdEn_P = 0;
}
/*********************************************************/
// 1602液晶写数据函数,dat就是要写入的数据
/*********************************************************/
void LcdWriteData(uchar dat)
{
LcdRs_P = 1;
LcdRw_P = 0;
LcdEn_P = 0;
P0 = dat;
delay(2);
LcdEn_P = 1;
delay(2);
LcdEn_P = 0;
}
/*********************************************************/
// 液晶光标定位函数
/*********************************************************/
void LcdGotoXY(uchar line, uchar column)
{
// 第一行
if (line == 0)
LcdWriteCmd(0x80 + column);
// 第二行
if (line == 1)
LcdWriteCmd(0x80 + 0x40 + column);
}
/*********************************************************/
// 液晶输出字符串函数
/*********************************************************/
void LcdPrintStr(uchar *str)
{
while (*str != '\0')
LcdWriteData(*str++);
}
/*********************************************************/
// 1602液晶功能初始化
/*********************************************************/
void LcdInit()
{
LcdWriteCmd(0x38); // 16*2显示,5*7点阵,8位数据口
LcdWriteCmd(0x0C); // 开显示,不显示光标
LcdWriteCmd(0x06); // 地址加1,当写入数据后光标右移
LcdWriteCmd(0x01); // 清屏
}
/*********************************************************/
// 1602液晶显示内容初始化
/*********************************************************/
void LcdShowInit()
{
LcdGotoXY(0, 3); // 定位到第0行第3列
LcdPrintStr(":"); // 第0行显示“:”
LcdGotoXY(1, 3); // 定位到第1行第3列
LcdPrintStr(":"); // 第1行显示“:”
}
// 4x4矩阵按键扫描
u8 getKey()
{
u8 isKeyPressed = 0; // 记录当前是否有按键按下
while (1)
{
row1 = 0; // 第一行置低
row2 = 1; // 第二行置高
row3 = 1; // 第三行置高
row4 = 1; // 第四行置高
if (col1 == 0)
{
delay(20); // 延时一段时间
if (col1 == 0)
{
isKeyPressed = 1; // 按键按下
return '0'; // 检测按键状态相同则返回
}
}
if (col2 == 0)
{
delay(20);
if (col2 == 0)
{
isKeyPressed = 1;
return '1';
}
}
if (col3 == 0)
{
delay(20);
if (col3 == 0)
{
isKeyPressed = 1;
return '2';
}
}
if (col4 == 0)
{
delay(20);
if (col4 == 0)
{
isKeyPressed = 1;
return '3';
}
}
row1 = 1; // 第一行置高
row2 = 0; // 第二行置低
row3 = 1; // 第三行置高
row4 = 1; // 第四行置高
if (col1 == 0)
{
delay(20);
if (col1 == 0)
{
isKeyPressed = 1;
return '4';
}
}
if (col2 == 0)
{
delay(20);
if (col2 == 0)
{
isKeyPressed = 1;
return '5';
}
}
if (col3 == 0)
{
delay(20);
if (col3 == 0)
{
isKeyPressed = 1;
return '6';
}
}
if (col4 == 0)
{
delay(20);
if (col4 == 0)
{
isKeyPressed = 1;
return '7';
}
}
row1 = 1; // 第一行置高
row2 = 1; // 第二行置高
row3 = 0; // 第三行置低
row4 = 1; // 第四行置高
if (col1 == 0)
{
delay(20);
if (col1 == 0)
{
isKeyPressed = 1;
return '8';
}
}
if (col2 == 0)
{
delay(20);
if (col2 == 0)
{
isKeyPressed = 1;
return '9';
}
}
if (col3 == 0)
{
delay(20);
if (col3 == 0)
{
isKeyPressed = 1;
return 'A';
}
}
if (col4 == 0)
{
delay(20);
if (col4 == 0)
{
isKeyPressed = 1;
return 'B';
}
}
row1 = 1; // 第一行置高
row2 = 1; // 第二行置高
row3 = 1; // 第三行置高
row4 = 0; // 第四行置低
if (col1 == 0)
{
delay(20);
if (col1 == 0)
{
isKeyPressed = 1;
return 'C';
}
}
if (col2 == 0)
{
delay(20);
if (col2 == 0)
{
isKeyPressed = 1;
return 'D';
}
}
if (col3 == 0)
{
delay(20);
if (col3 == 0)
{
isKeyPressed = 1;
return 'E';
}
}
if (col4 == 0)
{
delay(20);
if (col4 == 0)
{
isKeyPressed = 1;
return 'F';
}
}
if (srjz == 1) // 检测到输入进制改变
{
if (shiliujz == 0) // 16进制
{
base2 = 16;
return '-';
}
else if (shijz == 0) // 10进制
{
base2 = 10;
return '-';
}
else if (bajz == 0) // 8进制
{
base2 = 8;
return '-';
}
else if (erjz == 0) // 2进制
{
base2 = 2;
return '-';
}
}
if (srjz == 0) // 检测到输入进制改变
{
if (shiliujz == 0) // 16进制
{
base1 = 16;
return '-';
}
else if (shijz == 0) // 10进制
{
base1 = 10;
return '-';
}
else if (bajz == 0) // 8进制
{
base1 = 8;
return '-';
}
else if (erjz == 0) // 2进制
{
base1 = 2;
return '-';
}
}
if (qp == 0) // 清空液晶屏
{
memset(str,'\0',sizeof(str));
strPos = 0;
memset(num1,'\0',sizeof(num1));
LcdInit(); // 液晶功能初始化
LcdShowInit(); // 液晶显示内容初始化
return '-';
}
// 检测是否有按键松开
if (isKeyPressed)
{
delay(20);
if (col1 == 1 && col2 == 1 && col3 == 1 && col4 == 1)
{
isKeyPressed = 0; // 按键松开
}
}
}
}
/*********************************************************/
//10进制转其他进制------输出字符串
/*********************************************************/
void reverse(char str[], int length) {
int start = 0;
int end = length - 1;
while (start < end) {
char temp = str[start];
str[start] = str[end];
str[end] = temp;
start++;
end--;
}
}
char *itoa(int value, char str[], int base) {
// 处理 0 的情况
if (value == 0) {
str[0] = '0';
str[1] = '\0';
return str;
}
// 处理负数的情况
if (value < 0 && base == 10) {
isNegative = 1;
value = -value;
}
// 按基数进行转换
while (value != 0) {
int rem = value % base;
str[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
value = value / base;
}
// 处理负号
if (isNegative) {
str[i++] = '-';
}
str[i] = '\0';
// 反转字符串
reverse(str, i);
return str;
}
/*********************************************************/
// 主函数
/*********************************************************/
void main()
{
LcdInit(); // 液晶功能初始化
LcdShowInit(); // 液晶显示内容初始化
while (1){
switch (base1)
{
case 2:
LcdShowInit();
LcdGotoXY(0, 0);
LcdPrintStr("02"); // 当前进制为2进制
memset(num1,'\0',sizeof(num1));
b=strtol(str,&y,base1); //x转10进制
i=0; //i清零
itoa(b,num1,base2); //10转x进制
break;
case 8:
LcdShowInit();
LcdGotoXY(0, 0);
LcdPrintStr("08"); // 当前进制为8进制
memset(num1,'\0',sizeof(num1));
b=strtol(str,&y,base1); //x转10进制
i=0; //i清零
itoa(b,num1,base2); //10转x进制
break;
case 10:
LcdShowInit();
LcdGotoXY(0, 0);
LcdPrintStr("10"); // 当前进制为10进制
memset(num1,'\0',sizeof(num1));
b=strtol(str,&y,base1); //x转10进制
i=0; //i清零
itoa(b,num1,base2); //10转x进制
break;
case 16:
LcdShowInit();
LcdGotoXY(0, 0);
LcdPrintStr("16"); // 当前进制为16进制
memset(num1,'\0',sizeof(num1));
b=strtol(str,&y,base1); //x转10进制
i=0; //i清零
itoa(b,num1,base2); //10转x进制
break;
}
switch (base2)
{
case 2:
LcdShowInit();
LcdGotoXY(1, 0);
LcdPrintStr("02"); // 当前进制为2进制
memset(num1,'\0',sizeof(num1));
b=strtol(str,&y,base1); //x转10进制
i=0; //i清零
itoa(b,num1,base2); //10转x进制
break;
case 8:
LcdShowInit();
LcdGotoXY(1, 0);
LcdPrintStr("08"); // 当前进制为8进制
memset(num1,'\0',sizeof(num1));
b=strtol(str,&y,base1); //x转10进制
i=0; //i清零
itoa(b,num1,base2); //10转x进制
break;
case 10:
LcdShowInit();
LcdGotoXY(1, 0);
LcdPrintStr("10"); // 当前进制为10进制
memset(num1,'\0',sizeof(num1));
b=strtol(str,&y,base1); //x转10进制
i=0; //i清零
itoa(b,num1,base2); //10转x进制
break;
case 16:
LcdShowInit();
LcdGotoXY(1, 0);
LcdPrintStr("16"); // 当前进制为16进制
memset(num1,'\0',sizeof(num1));
b=strtol(str,&y,base1); //x转10进制
i=0; //i清零
itoa(b,num1,base2); //10转x进制
break;
}
key = getKey(); // 获取按下的按键字符
if (key != '\0') // 按键字符不为空时才进行处理
{
if (strPos < 16) // 字符串位置不超过16时才进行处理
{
if (key != '-') {
str[strPos] = key; // 将当前按键字符存入对应位置
strPos++; // 字符串位置加一
str[strPos] = '\0'; // 在字符串末尾添加终止符,形成一个合法的字符串
}
LcdGotoXY(0, 4); // 定位到第1行第0列
LcdPrintStr(" \0"); // 在液晶屏上显示字符串
LcdGotoXY(0, 4); // 定位到第1行第0列
LcdPrintStr(str); // 在液晶屏上显示字符串
b=strtol(str,&y,base1); //x转10进制
if(b!=0){
i=0; //i清零
itoa(b,num1,base2); //10转x进制
}
LcdGotoXY(1, 4); // 定位到第1行第0列
LcdPrintStr(" \0"); // 在液晶屏上显示字符串
LcdGotoXY(1, 4); // 定位到第1行第0列
LcdPrintStr(num1); // 在液晶屏上显示字符串
}
}
delay(200); // 延时一段时间以防止按键重复检
}
}