⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keydisplay.c

📁 该程序应用轮换查询的方式实现了键盘的扫描
💻 C
字号:
//ICC-AVR application builder : 2007-6-29 下午 09:31:04
// Target : M16
// Crystal: 1.0000Mhz
//maker:diyixiaozhu
//jianpanshaomiaofangshi:xunhuanshaomiao循环扫描且可以实现显示小数点
                                           //并可加入其他功能
#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint  unsigned int
#define clk0 PORTB|=0x02//时钟宏定义port2接clk
#define clk1 PORTB&=~0x02
#define data1 PORTB|=0x01//数字宏定义port1接data
#define data0 PORTB&=~0x01


uchar table[10]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09};//数字编码
uchar table1[10]={0x02,0x9e,0x24,0x0c,0x98,0x48,0x40,0x1e,0x00,0x08};//带点编码
uchar pata[4]={0,0,0,0};//显存
uchar pata1[4]={0,0,0,0};//存储前面已显示过的数据加上带显示的数据以
uchar pata2[4]={0,0,0,0};//测试用存储up函数处理国的数据    //送该显示函数显示

void port_init(void)//端口初始化
{
 PORTA = 0x00;
 DDRA  = 0x00;
 PORTB = 0x00;
 DDRB  = 0x00;
 PORTC = 0x00; //m103 output only
 DDRC  = 0x00;
 PORTD = 0x00;
 DDRD  = 0x00;
}

/*//call this routine to initialize all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up//此处留作中断用
 CLI(); //disable all interrupts
 port_init();

 MCUCR = 0x00;
 GICR  = 0x00;
 TIMSK = 0x00; //timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
}*/

void delay(uint n)//ms延时函数
{uint i,j;
 for(i=0;i<n;i++)
  {
   for(j=0;j<1000;j++){;}
  }
}
 


uint keypressed(void)
{  uchar t;
   DDRA=0x0f;// 输出模式
   PORTA=0xf0;//第四位对应行线,高四位对应列
   //DDRA=0x00;//设置为输入
   PINA=PINA&0xf0;
    if(PINA!=0xf0)
        {
		 return 1;
		
		}
    else 
         return 0;
}

uint keyscan(void)
{ 
    uchar a1,a2,a;
	uint j=0;
	
    if(keypressed()==1)//如有键按下,查询键值
       {
     
		 PORTA=0xf0;//扫描第一次,取列输入
		 DDRA=0x0f;
		 a1=PINA;
		 a1=PINA;
		 a1=a1&0xf0;
		 PORTA=0x0f;//扫描第一次,取行输入
		 DDRA=0xf0;
		 a2=PINA;
		 a2=PINA;
		 a2=a2&0x0f;
		 a=a1|a2;
		 }
    			
     switch(a)//译码
          {
             case 0xee:j=0;break;//根据返回值确定按键编码安高四位为列
             case 0xde:j=1;break;
             case 0xbe:j=2;break;
             case 0x7e:j=10;break;//up jian
             case 0xed:j=3;break;
             case 0xdd:j=4;break;
             case 0xbd:j=5;break;
           //  case 0x7d:j=8;break;//down jian
             case 0xeb:j=6;break;
             case 0xdb:j=7;break;
             case 0xbb:j=8;break;
           //  case 0x7b:j=12;break;//setup jian
             case 0xe7:j=9;break;
             case 0xd7:j=14;break;//xiaoshudian jian
             case 0xb7:j=15;break;//cancel jian
             case 0x77:j=16;break;//enter jian
             default:break;
          }
	   return j;
 }

uint hex_to_int(uchar data)//此函数实现反查十六进制数编码对应的十进制数
 {
  uint n;
  switch(data)
   {
    case 0x03:n=0;break;
	case 0x9f:n=1;break;
    case 0x25:n=2;break;
    case 0x0d:n=3;break;
	case 0x99:n=4;break;
	case 0x49:n=5;break;
	case 0x41:n=6;break;
	case 0x1f:n=7;break;
	case 0x01:n=8;break;
	case 0x09:n=9;break;
	case 0xff:n=0;break;//高位未显示,已经复位0xff,guyinggaizhuanweiling 
	default:break;
   }
 return n;
}

void up(uchar data[]) //此函数实现按键up的功能这里站设为加一
                    //但是不能够对含小数的数进行操作
 {
  uint i,j;
/*  if(data[0]&0x01==0)//若前面含有小数点则不可以操作
     ;
  else
   {*/
	j=hex_to_int(data[0]);//取其代表的十进制数
    if(j<9)//第一位数小于十
     data[0]=table[j+1];//加一显示
	else//大于十进位
	 {
	  data[0]=table[0];//低位清零
	  j=hex_to_int(data[1]);//在判断高位
	  if(j<9)
        data[1]=table[j+1];
	  else
	   {
	    data[1]=table[0];
		j=hex_to_int(data[2]);
		if(j<9)
		 data[2]=table[j+1];
		else
		 {
		  data[2]=table[0];
		  j=hex_to_int(data[3]);
		  if(j<9)
		   data[3]=table[j+1];
		  else
		   ;//已无法再向上进位
		  }
		}
	  }
  // }
} 	   
 
 void neirong1(uint n)//此法优于上面的列表法
{
   uint ge,shi,bai,qian;
   ge=n%10;//取n的各位个位
   shi=n/10%10;//十位
   bai=n/100%10;//百位
   qian=n/1000;//千位 
   pata[0]=table[ge];//数字查表为该字符编码
   pata[1]=table[shi];
   pata[2]=table[bai];
   pata[3]=table[qian];
}
 
 void display(uchar p[]) //数字显示程序...不含显示小数点且不累集
{
 uint i,j;
 for(j=0;j<4;j++)
     {for(i=0;i<8;i++)//八位全部显示完毕
	  {
		  if(p[j]&0x01)
		    data1;
		  else
		    data0;
	     clk0;//产生时钟脉冲
		    clk1;
		p[j]=p[j]>>1;//右移以便取下一位
	  }
     }
}


//*该函数实现输入数据缓存*//
void shujuhuancun(uint key0,uint key2)//key2为前一键值,key1为按键编码
  {
     uchar i,j;
     uint key1,n=0,k,temp;//n为现实前面是否有小数点
	// temp2=temp1;
	 key1=key0;//取键值
     if(key1!=14)//若不是小数点
		  {
	   if(key1==0||key1==1||key1==2||key1==3||key1==4||key1==5||key1==6||key1==7
	            ||key1==8||key1==9)
			                                    //若是数字0-9则移位
		   {
		     for(j=3;j>0;j--)
			  
			    pata1[j]=pata1[j-1];//循环右移
		        pata1[0]=table[key1];//按键编码付给pata1[0]
		   }
	   else
			  ;//此处可以添加除0-9以外的其他按键实现功能
		  }
	else
	{ 
	// if(temp2)
		//;
	 //else	 
	 for(k=3;k>0;)//此循环实现判断前面是否已经有超过一个的小书点
	 {
	   temp=pata1[k]&0x01;
	  if(temp==0)
	  { 
	  n=1; break;
	  }
	  else
	   
	   {
	    n=0;
	   k--;
	   }
	  } 
	   if(n==0)
		    {
			if((pata1[0]&0x01)==0)//若前一个数有小数点则无效
			                      //h位是低电平有效
			    ;
		     else
			    pata1[0]=table1[key2];//按键编码付给pata1[0]且键值变为带小数点.
				                       //也解决了如果按下的键不是小数点但前一键
									   //值示小数点 
		     }
	   else
	     ;
		 
	 }
		 for(j=3;j>=0;j--)//此循环功能很重要,他将高位的不带点零元素质1而不显示
		  {
		    if(pata1[j]|0x00!=0)
			   break ;//高位有非零数即可停止检查
			else
			  pata1[j]=0xff;//否则置位为不显示
		  }
		for(j=0;j<4;j++)
		 {
		   pata[j]=pata1[j];}
		   
	} 
	
	
//此函数实现统计pata1中的非零元数的个数		 
uint tongji(uchar t[])	
{
  uint geshu=0,i;
  for(i=0;i<4;)
    {
		  if((t[i]|0x00)!=0)//证明非零
		   { geshu++;i++;}
		  else
		    i++;
    }
   return geshu;
}


uint  panduan(uchar t[])//此函数判断高三位是否已经含有小数点
 {
  uint n,r;
   for(r=1;r<4;)
    {

	 if(t[r]&0x01==0)
	  {
	  n=1; break;
	  }
	 else
	   {
	    r++;n=0;
	   }
    }
  return n;
 }

void qingling(uchar data[])//清除前一次寄存值
{
  uint i;
  for(i=0;i<4;i++)
    data[i]=0xff;
}

void zhuanyi(uchar data[])//测试用   
{ uint i;
 for(i=0;i<4;i++)
  {
   pata2[i]=data[i];
  }
}

void main()
{
 static uint key3=0;static uint key=0;
 uchar t;//t为测试用   
 uint n=0;//n为pata1中有的非零元数个数
 port_init();
 DDRB=0xff;
 PORTB=0xff;
 PORTB=0x00;
 neirong1(key);
 display(pata);
 while(1)
   {
    key3=key;//key2记录前一编码即键值以便于查找加点编码
	 if(keypressed()==1)//有键按下
      { 
	    key=keyscan();//开始扫描
	    delay(25);//键盘去抖
		    if(key==14)
		       {            //则显示小数点但不存入pata1
			  shujuhuancun(key,key3);
			  display(pata);
			   }
		   else
		    if(key==15)//若是cancel 键则清除屏幕
			 {
			  neirong1(0);//
			  display(pata);//显示零
			  qingling(pata1);//消除前一次寄存值,也可以说只要调用
			                   //pata1就可以显示前面操作过的数据
			 }
			else
			  if(key==10)//ruoshi anjian up
			    {
				up(pata1);
				zhuanyi(pata1);//测试用
				display(pata2);//原为pata1
				}
			  else
			   //留作其他按键功能扩展
		    {
			  shujuhuancun(key,key3);
			  display(pata);
	         }
       }
  else
		   ;//此处留作函数实现其他功能的接口
    }
}


 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -