51单片机制作进制转换器论文
四、设计总结
总结:刚开始做这个设计的时候我们都不知道怎么下手,脑子里只能想到一些零零散散的程序,不知道该如何拼接,使它们实现自己想要的功能。当时的想法很好,很快就想出了要做一个进制转换器,但一想到怎么开始就无从下手了。最后在我们的讨论中,渐渐理清思路,明白了该怎么拼接程序,知道了该怎么嵌套子程序,怎么将键盘扫描和数码管显示结合起来。经过讨论后,我们将程序基本写完,进行调试。
在调试过程中,出现了很多问题。烧录好程序后,在进行第一次模式选择时,可以进入进制转换,并显示,但我们发现如果想换一种进制模式时,按其他独立按键则无效,回到程序我们发现进入一个循环后,无法跳出,只能在里边循环,导致无法选择其他进制模式。我们思考后加入了再按一次原来的独立按键跳出循环的语句,便实现了可以选择其他模式的功能。解决了这一问题后,进制转换器便可以实现我们想要的功能了。
通过本次设计,使我们对已学过的数码管动态显示、矩阵键盘的扫描以及独立按键的应用等知识有了更深一步的了解,也让我们能够更熟练的运用这些知识,
锻炼和培养了自己利用已学知识来分析和解决实际问题的能力,通过本次设计对我们以后的学习有很大的帮助。
缺点:
1、在选择完一个进制转换模式后,不能直接切换到另一种进制转换模式,需先按下原来的进制模式按键才能退出原来的进制模式。
2、在上一个进制转换模式退出后不能对输入数字清零,进入下一模式后,会自动显示原来数字对应当前进制的数字。
五、附录
5.1元件清单
5.2 数码管
数码管动态显示介面是单片机中应用最为广泛的一种显示方式之一,动态驱动是将所有数码管的8个显示笔划"a,b,c,d,e,f,g,dp "的同名端连在一起,另外为每个数码管的公共极COM增加位元选通控制电路,位元选通由各自独立的I/O线控制,当单片机输出字形码时,所有数码管都接收到相同的字形码,但究竟是那个数码管会显示出字形,取决于单片机对位元选通COM端电路的控制,所以我们只要将需要显示的数码管的选通控制打开,该位元就显示出字形,没有选通的数码管就不会亮。
5.3 矩阵键盘
行扫描法又称为逐行(或列)扫描查询法,是一种最常用的按键识别方法。
1、判断键盘中有无键按下将全部行线Y0-Y3置低电平,然后检测列线的状态。只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。若所有列线均为高电平,则键盘中无键按下。
2、判断闭合键所在的位置在确认有键按下后,即可进入确定具体闭合键的过程。其方法是:依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。
5.4主程序
/******************************************************************* * 设计名 : 进制转换器
* 使用的IO : 数码管使用P0口段选,P2口位选,键盘使用P3.0、P3.1、P3.2、P3.3
* 实验效果 : 将0-15数字进行进制转换
********************************************************************/ #include
#define GPIO_DIG P0 //宏定义段选
#define GPIO_KEY P1 //宏定义键盘
sbit W1=P2^0; //位选
sbit W2=P2^1;
sbit W3=P2^2;
sbit W4=P2^3;
sbit K1=P3^0;
sbit K2=P3^1;
sbit K3=P3^2;
sbit K4=P3^3;
void delay(unsigned int ms) //延时函数
{
unsigned int i,j;
for (i=0;i for(j=0;j<100;j++); } unsigned char code DIG_CODE[16]= { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71 }; //十六个数字0123456789AbCdEF的显示码 unsigned char KeyValue;//用来存放读取到的键值 void KeyDown(); //检测按键函数 /******************************************************************** * 函数名 : main * 函数功能 : 主函数 ********************************************************************/ void main(void) { while(1) { int flag=1; if(K1==0) //进行二进制转换 { delay(10); if(K1==0) { while(K1!=0); //松手检测 while(flag==1) { KeyDown(); GPIO_DIG = DIG_CODE[KeyValue/8]; W1 = 0; delay(1); W1 = 1; GPIO_DIG = DIG_CODE[KeyValue%8/4]; W2 = 0; delay(1); W2 = 1; GPIO_DIG = DIG_CODE[KeyValue%8%4/2]; W3 = 0; delay(1); W3 = 1; GPIO_DIG = DIG_CODE[KeyValue%8%4%2]; W4 = 0; delay(1); W4 = 1; if(K1==0) { delay(10); if(K1==0) { while(K1!=0); flag=0; break; } } } } } else if(K2==0) //进行八进制转换 { delay(10); if(K2==0) { while(K2!=0); while(flag==1) { KeyDown(); GPIO_DIG = DIG_CODE[KeyValue/8]; W3 = 0; delay(1); W3 = 1; GPIO_DIG = DIG_CODE[KeyValue%8]; W4 = 0; delay(1); W4 = 1; if(K2==0) { delay(10); if(K2==0) { while(K2!=0); flag=0; break; } } } } } else if(K3==0) //进行十进制转换 { delay(10); if(K3==0) { while(K3!=0); while(flag==1) { KeyDown(); GPIO_DIG = DIG_CODE[KeyValue/10]; W3 = 0; delay(1); W3 = 1; GPIO_DIG = DIG_CODE[KeyValue%10]; W4 = 0; delay(1); W4 = 1; if(K3==0) { delay(10); if(K3==0) { while(K3!=0); flag=0; break; } } } } } else if(K4==0) //进行十六进制转换 { delay(10); if(K4==0) { while(K4!=0); while(flag==1) { KeyDown(); GPIO_DIG = DIG_CODE[KeyValue]; W4 = 0; delay(1); W4 = 1; if(K4==0) { delay(10); if(K4==0) { while(K4!=0); flag=0; break; } } } } } } } /******************************************************************** * 函数名 : KeyDown * 函数功能 : 检测有按键按下并读取键值 ********************************************************************/ void KeyDown(void) { char a=0; GPIO_KEY=0x0f; if(GPIO_KEY!=0x0f) //读取按键是否按下 { delay(10); //延时10ms进行消抖 if(GPIO_KEY!=0x0f) //再次检测键盘是否按下 { //测试列 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; } while((a<50)&&(GPIO_KEY!=0xf0)) //检测按键松手检测 { delay(10); a++; } } } }