进制转换——基于STC89C52RC系列单片机

该博客介绍了一个基于STC89C52RC单片机的数字转换系统,能够实现二进制、八进制和十进制之间的相互转换。通过4x4矩阵键盘输入数字,使用LCD1602显示屏显示转换结果。系统包括模式选择、进制转换功能键和转换键,确保了用户友好交互。文章详细阐述了单片机程序设计,包括延时函数、LCD初始化和键盘扫描等关键模块,展示了数字系统在日常生活和工作中日益重要的作用。
摘要由CSDN通过智能技术生成

随着Internet技术的发展,人们的日常生活已经离不开网络。未来社会人们的生活和工作将越来越依赖于数字技术的发展,越来越数字化、网络化、电子化、虚拟化。Internet的发展历程以及目前的应用状况和发展趋势,可以充分地相信网络技术将极大的改变我们的生活和工作方式,甚至社会的价值观也会发生某种变化。

本设计实现在二进制、八进制、十进制间的转换。主要用到的是STC89C52RC系列的单片机,LCD1602显示屏以及4x4矩阵键盘。首先进行模式选择(共有六种模式)然后从矩阵键盘输入要转换的数字,按下转换键,在LCD1602显示屏上显示结果。

 将4×4矩阵键盘的S1、S2、S3、S5、S6、S7、S9、S10、S11、S14设为数字键(0~9),S15设置为功能键,S16为转换键。有六种进制转换的选项(B,O,D之间相互转换)。

#include<reg52.h>
#include<intrins.h>



sbit RS = P1^0;   //定义端口 
sbit RW = P1^1;
sbit EN = P2^5;
sbit DU = P2^6;
sbit WE = P2^7;

#define RS_CLR RS=0 
#define RS_SET RS=1

#define RW_CLR RW=0 
#define RW_SET RW=1 

#define EN_CLR EN=0
#define EN_SET EN=1

#define DataPort P0



void cmg88()//关数码管,点阵函数
{
	DU=1;
	WE=1;  
	P0=0X00;
	DU=0;
	WE=0;
}
/*------------------------------------------------
 uS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
 长度如下 T=tx2+5 uS 
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{   
 while(--t);
}
/*------------------------------------------------
 mS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{
     
 while(t--)
 {
     //大致延时1mS
     DelayUs2x(245);
	 DelayUs2x(245);
 }
}
/*------------------------------------------------
              判忙函数
------------------------------------------------*/
 bit LCD_Check_Busy(void) 
 { 
 DataPort= 0xFF; 
 RS_CLR; 
 RW_SET; 
 EN_CLR; 
 _nop_(); 
 EN_SET;
 return (bit)(DataPort & 0x80);
 }
/*------------------------------------------------
              写入命令函数
------------------------------------------------*/
 void LCD_Write_Com(unsigned char com) 
 {  
 while(LCD_Check_Busy()); //忙则等待
 RS_CLR; 
 RW_CLR; 
 EN_SET; 
 DataPort= com; 
 _nop_(); 
 EN_CLR;
 }
 
/*------------------------------------------------
              写入数据函数
------------------------------------------------*/
 void LCD_Write_Data(unsigned char Data) 
 { 
 while(LCD_Check_Busy()); //忙则等待
 RS_SET; 
 RW_CLR; 
 EN_SET; 
 DataPort= Data; 
 _nop_();
 EN_CLR;
 }

 //----------------------------------------------

/*------------------------------------------------
                清屏函数
------------------------------------------------*/
 void LCD_Clear(void) 
 { 
 LCD_Write_Com(0x01); 
 DelayMs(5);
 }
/*------------------------------------------------
              写入字符串函数
------------------------------------------------*/
 void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) 
 {     
	 if (y == 0) 
	 	{     
		 	LCD_Write_Com(0x80 + x);     //表示第一行
	 	}
	 else 
	 	{      
	 		LCD_Write_Com(0xC0 + x);      //表示第二行
	 	}        
	 while (*s) 
	 	{     
			 LCD_Write_Data( *s);     
			 s ++;     
	 	}
 }
/*------------------------------------------------
              写入字符函数
------------------------------------------------*/
 void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) 
 {     
	 if (y == 0) 
	 	{     
	 		LCD_Write_Com(0x80 + x);     
	 	}    
	 else 
	 	{     
	 		LCD_Write_Com(0xC0 + x);     
	 	}        
	 LCD_Write_Data( Data);  
 }
/*------------------------------------------------
              初始化函数
------------------------------------------------*/
 void LCD_Init(void) 
 {
   LCD_Write_Com(0x38);    /*显示模式设置*/ 
   DelayMs(5); 
   LCD_Write_Com(0x38); 
   DelayMs(5); 
   LCD_Write_Com(0x38); 
   DelayMs(5); 
   LCD_Write_Com(0x38);  
   LCD_Write_Com(0x08);    /*显示关闭*/ 
   LCD_Write_Com(0x01);    /*显示清屏*/ 
   LCD_Write_Com(0x06);    /*显示光标移动设置*/ 
   DelayMs(5); 
   LCD_Write_Com(0x0C);    /*显示开及光标设置*/
   }

void delay(unsigned int xms)	//延迟xms
{
    unsigned char i,j;
	for(i=xms;i>0;i--)
	  for(j=112;j>0;j--);
}

/*void display(unsigned char x,unsigned char y,uchar num)	   
{
    	LCD_Write_Char(x,y,num+0x30);
}	*/

void Transform10To2(unsigned int num){
	unsigned char e,x=0;
	unsigned long int n=2;
	while(1){					   //计算需要几个二进制位表示这个数字
		n*=2;
		x++;
		if(n>num) break;
	}

	 // LCD_Write_Char(14,1,x+0x30);
	while(x>=0){
	    e=num%2;
		LCD_Write_Char(x+2,1,e+0x30);
		num=num/2;
		x--;
		if(x==-1) break;
	}
}
void TransformTo10(unsigned long int num){
	  
	unsigned char e,x=0;
	unsigned long int n=10;
	while(1){					   //计算需要几个十进制位表示这个数字
		n*=10;
		x++;
		if(n>num) break;
	}

	 // LCD_Write_Char(14,1,x+0x30);
	while(x>=0){
	    e=num%10;
		LCD_Write_Char(x+2,1,e+0x30);
		num=num/10;
		x--;
		if(x==-1) break;
	}

}
void Transform10To8(unsigned long int num){
	unsigned char e,x=0;
	unsigned long int n=8;
	while(1){					   //计算需要几个八进制位表示这个数字
		n*=8;
		x++;
		if(n>num) break;
	}

	 // LCD_Write_Char(14,1,x+0x30);
	while(x>=0){
	    e=num%8;
		LCD_Write_Char(x+2,1,e+0x30);
		num=num/8;
		x--;
		if(x==-1) break;
}
}

char keyscan4x4()
{
    unsigned char temp,key; 
	///第一行扫描///
	P3=0xfe;//1111 1110 让P3.0口输出低
	temp=P3;
	temp=temp&0xf0;//1111 0000	位与操作 屏蔽后四位
	if(temp!=0xf0)
	{
	    delay(10);		 //消抖
		temp=P3;
		temp=temp&0xf0;
		if(temp!=0xf0)
		{
		    temp=P3;
			//i++;
			switch(temp)
			{
			  case 0xee:	   //1110 1110 S1被按下
			       key=7;
				   break;
			  case 0xde:		  //1101 1110  S2被按下
				   key=8;
				   break;
			  case 0xbe:		  //1011 1110  S3被按下
				   key=9;
				   break;
			}
			while(temp!=0xf0)
			{
			    temp=P3;
				temp=temp&0xf0;
			}
			
			//display(i-1,0,key);
			return key;
		}
	}
			///第二行扫描///
	P3=0xfd;//1111 1101 让P3.1口输出低
	temp=P3;
	temp=temp&0xf0;//1111 0000	位与操作 屏蔽后四位
	if(temp!=0xf0)
	{
	    delay(10);
		temp=P3;
		temp=temp&0xf0;
		if(temp!=0xf0)
		{
		    temp=P3;
			//i++;
			switch(temp)
			{
			  case 0xed:	   //1110 1101 S5被按下
			       key=4;
				   break;
			  case 0xdd:		  //1101 1101  S6被按下
				   key=5;
				   break;
			  case 0xbd:		  //1011 1101  S7被按下
				   key=6;
				   break;
			}
			while(temp!=0xf0)
			{
			    temp=P3;
				temp=temp&0xf0;
			}
			//display(i-1,0,key);
			return key;
		}
	 }
			///第三行扫描///
	P3=0xfb;//1111 1011 让P3.2口输出低
	temp=P3;
	temp=temp&0xf0;//1111 0000	位与操作 屏蔽后四位
	if(temp!=0xf0)
	{
	    delay(10);
		temp=P3;
		temp=temp&0xf0;
		if(temp!=0xf0)
		{
		    temp=P3;
			//i++;
			switch(temp)
			{
			  case 0xeb:	   //1110 1011 S9被按下
			       key=1;
				   break;
			  case 0xdb:		  //1101 1011  S10被按下
				   key=2;
				   break;
			  case 0xbb:		  //1011 1011  S11被按下
				   key=3;
				   break;
			}
			while(temp!=0xf0)
			{
			    temp=P3;
				temp=temp&0xf0;
			}
			//display(i-1,0,key);
			return key;
		  }
		}

			///第四行扫描///
	P3=0xf7;//1111 0111 让P3.0口输出低
	temp=P3;
	temp=temp&0xf0;//1111 0000	位与操作 屏蔽后四位
	if(temp!=0xf0)
	{
	    delay(10);
		temp=P3;
		temp=temp&0xf0;
		if(temp!=0xf0)
		{
		    temp=P3;
			//i++;
			switch(temp)
			{
			  case 0xd7:		  //1101 0111  S14被按下
				   key=0;
				   break;
			  case 0xb7:		  //1011 0111  S15被按下,功能选择
			  		key=11;
					break;				  
			  case 0x77:
			  		key=10;		  //0111 0111  S16被按下,确认转化
				   break;
			}
			while(temp!=0xf0)
			{
			    temp=P3;
				temp=temp&0xf0;
			}
			//display(i-1,0,key);
			return key;

		 }
	 }
	 return -1;


}

void main()
{	
    unsigned long int number;
	unsigned char key,i=0,count=0,g;
	cmg88();								//关数码管,点阵函数
	DelayMs(15);
	LCD_Init(); 
	LCD_Clear();							//清屏
	LCD_Write_String(0,0,"Select function");
		while(1)
		{  
			
	   		key=keyscan4x4();
			
			if(key==11){				   	//功能选择	
			g=count%6+1;   					//count++;
			}  
			switch(g){
				case 1:							  //十进制转二进制			
					//LCD_Write_String(0,0,"D:");
					//LCD_Write_String(0,1,"B:");
						if(i==0&&key!=-1&&key!=11){ 	
							LCD_Clear();
							LCD_Write_String(0,0,"D:");
							LCD_Write_String(0,1,"B:");
							}
	   					if(key!=-1&&key!=11){
						if(key==10){					  //按下确定按钮后
							//LCD_Write_Char(i,0,key+0x30);
							if(number>16383){				  //判断是否超过范围
								LCD_Write_String(2,1,"error!");
								number=0;
								i=0;
								continue;		//使输入确定键转化后不让10计算到number中
								}else{						//未超过范围则转化为二进制
								Transform10To2(number);
								number=0;
								//key=-1;
								i=0;					  
								continue;
								}
	   					}
						else{
								LCD_Write_Char(i+2,0,key+0x30);  //第一行显示输入的数字
								i++;						   //输入数字的位置
							}
	   	 				number=key+number*10;			   //将输入的数字字符转化为十进制
	   					}
						if(key==11){
						count++;
						LCD_Clear();
						LCD_Write_String(0,0,"D:");
						LCD_Write_String(0,1,"B:");
						//while(1);
						//key=-1;
						//break;
						}  
					//}
					break;
				case 2:							  //二进制转十进制
					//LCD_Write_String(0,0,"B:");
					//LCD_Write_String(0,1,"D:");
						if(i==0&&key<=1){ 	
							LCD_Clear();
							LCD_Write_String(0,0,"B:");
							LCD_Write_String(0,1,"D:");
							}
					if(key==0||key==1||key==10){
						switch(key){
							case 10:
								TransformTo10(number);
								number=0;
								i=0;
								break;
							default:
								LCD_Write_Char(i+2,0,key+0x30);
								i++;
								number=key+number*2;
						}
					}
					if(key==11){
						count++;
						LCD_Clear();
						LCD_Write_String(0,0,"B:");
						LCD_Write_String(0,1,"D:");
						break;
						}
					//}
					break;								  
				case 3:											  //八进制转二进制
					//LCD_Write_String(0,0,"O:");	  
				//	LCD_Write_String(0,1,"B:");
					if(i==0&&key>=0&&key<=7){ 	
							LCD_Clear();
							LCD_Write_String(0,0,"O:");	  
							LCD_Write_String(0,1,"B:");
							}
					if((key>=0&&key<=7)||key==10){
						switch(key){
							case 10:
								if(number>16383){				  //判断是否超过范围
								LCD_Write_String(2,1,"error!");
								number=0;
								i=0;
								continue;		
								}else{						//未超过范围则转化为二进制
								Transform10To2(number);
								number=0;
								i=0;					  
								continue;
								}
								break;
							default:
								LCD_Write_Char(i+2,0,key+0x30);
								i++;
								number=key+number*8;
						}
					}
					if(key==11){
						count++;
						LCD_Clear();
						LCD_Write_String(0,0,"O:");
						LCD_Write_String(0,1,"B:");
						break;
						}
								   
					break;
				case 4:							  //二进制转八进制
					//LCD_Write_String(0,0,"B:");	
					//LCD_Write_String(0,1,"O:");
					if(i==0&&key<=1){ 	
							LCD_Clear();
							LCD_Write_String(0,0,"B:");	
							LCD_Write_String(0,1,"O:");
							}
					if(key==0||key==1||key==10){
						switch(key){
							case 10:
								Transform10To8(number);
								number=0;
								i=0;
								break;
							default:
								LCD_Write_Char(i+2,0,key+0x30);
								i++;
								number=key+number*2;
						}
					}
					if(key==11){
						count++;
						LCD_Clear();
						LCD_Write_String(0,0,"B:");	
						LCD_Write_String(0,1,"O:");
						break;
						}	
					break;
				case 5:							//八进制转十进制
					//LCD_Write_String(0,0,"O:");	 
					//LCD_Write_String(0,1,"D:");
					if(i==0&&key<=7&&key>=0){ 	
							LCD_Clear();
							LCD_Write_String(0,0,"O:");	 
							LCD_Write_String(0,1,"D:");
							}
					if((key<=7&&key>=0)||key==10){
						switch(key){
							case 10:
								if(number>4294967290){				  //判断是否超过范围
								LCD_Write_String(2,1,"error!");
								number=0;
								i=0;
								continue;						 
								}else{
								TransformTo10(number);
								number=0;
								i=0;
								}
								break;
							default:
								LCD_Write_Char(i+2,0,key+0x30);
								i++;
								number=key+number*8;
						}
					}
					if(key==11){
						count++;
						LCD_Clear();
						LCD_Write_String(0,0,"O:");	 
						LCD_Write_String(0,1,"D:");
						break;
						}
					break;
				case 6:							//十进制转八进制		
					//LCD_Write_String(0,0,"D:");	 
					//LCD_Write_String(0,1,"O:");
					if(i==0&&key!=-1&&key!=11){ 	
						LCD_Clear();
						LCD_Write_String(0,0,"D:");	 
						LCD_Write_String(0,1,"O:");
						}
						if(key!=-1&&key!=11){
						switch(key){
							case 10:				 ;
								if(number>4294967290){				  //判断是否超过范围
								LCD_Write_String(2,1,"error!");
								number=0;
								i=0;
								continue;						  
								}else{							 
								Transform10To8(number);
								number=0;
								i=0;					  
								continue;
								}
								break;

							default:
								LCD_Write_Char(i+2,0,key+0x30);  //第一行显示输入的数字
								i++;
								number=key+number*10;
	   					}
						}
					if(key==11){
						count++;
						LCD_Clear();
						LCD_Write_String(0,0,"D:");	 
						LCD_Write_String(0,1,"O:");
						break;
						}
					break;
			}	
			
			
													   
			continue;	
			
			
	   }
	while(1);
	
	
	

}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值