计算器 矩阵键盘+数码管

1.实验目的

熟练掌握矩阵键盘与数码管,并做出简单的计算器

 

2.实验流程图

 

 

 

矩阵键盘电路图

硬件连接

3.代码分析

(1)主函数

 

int main()
{
 u16 flag=0,temp=0xf0;
 int32_t dat=0,dat1=0;                                          //被处理数1 , 2
 u32 n1,n2;                                  
 GPIO_InitTypeDef GPIO_InitStructure;

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;                    // 段选
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(GPIOA, &GPIO_InitStructure);

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;                     //位选
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(GPIOE, &GPIO_InitStructure);
​

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);           //按键


 GPIO_SetBits(GPIOE,GPIO_Pin_All);
 while(1)
  
 {
 if(flag==0)
 {
  smgNum(dat);
  temp=KeyDown();
 if(temp!=0xf0)
  {
 if(KeyValue ==10||KeyValue ==11||KeyValue ==12||KeyValue ==13) //对应符号
  {
  flag=1;
  n1=KeyValue ;
  delay(1000000);                                             //防止按键连按
  
    }
 else if(KeyValue==15)                                        //清零
   {
  dat=0;
    }
 else if(KeyValue<10) 
  {
  dat=dat*10+KeyValue;delay(1000000);                         //被处理数 1 
   }
  
    }

   }

 if(flag==1)                                                //显示符号
 {
   smg(8,n1);
   temp=0xf0;
   temp=KeyDown();

 if(temp!=0xf0) 
 {
   flag=2;
   dat1=KeyValue;
  }

 }

 if(flag==2)                                                    
 {
  temp=0xf0;
  smgNum(dat1);
  temp=KeyDown();
 if(temp!=0xf0)
  {
  if(KeyValue==14)                                             //等于号
  {
   flag=3;delay(1000000); 
   }
 else   if(KeyValue==15)                                         //清零
 {
   dat1=0;
   }
 else
 {
   dat1=dat1*10+KeyValue;delay(1000000);                        //被处理数 2
 }

    }

    }

 if(flag==3)
 {
 switch(n1)                                                 //符号处理
 {
  case 10:n2=dat+dat1; break;
  case 11:n2=dat-dat1;  break;
  case 12:n2=dat*dat1;  break;
  case 13:n2=1.0*dat/dat1;  break;

   }
  temp=0xf0;
  smgNum(n2);                                              //结果处理
  temp=KeyDown();
 if(temp!=0xf0)
 {
  if(KeyValue==15)                                         //清零
  {
​
  dat=0;
  dat1=0;
  flag=0;
  n1=0;
    }
   }
​
  }

 }

}

(2)按键扫描函数

 

u8 KeyDown()                                                                  //按键扫描
 {
 char a=0;
 GPIO_InitTypeDef GPIO_InitStructure;
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE );
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3; //KEY0-KEY3 矩阵键盘的列
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 
 GPIO_Init(GPIOD, &GPIO_InitStructure);

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; //KEY4-KEY7 矩阵键盘的行     
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(GPIOD, &GPIO_InitStructure);
 GPIO_Write(GPIOD,0X0F);
 if((GPIO_ReadInputData(GPIOD)&0x0f)!=0x0f) //列扫描
 {
 delay(24000);
 if((GPIO_ReadInputData(GPIOD)&0x0f)!=0x0f)
   switch(GPIO_ReadInputData(GPIOD)&0x0f)
   {
    case(0X07): KeyValue=0;break;
    case(0X0b): KeyValue=1;break;
    case(0X0d): KeyValue=2;break;
    case(0X0e): KeyValue=3;break;
   }
                               
  }
​
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;//KEY0-KEY3 矩阵键盘的行   
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(GPIOD, &GPIO_InitStructure);
   
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;//KEY4-KEY7 矩阵键盘的列
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 
 GPIO_Init(GPIOD, &GPIO_InitStructure); 
    
 GPIO_Write(GPIOD,0XF0);
 if((GPIO_ReadInputData(GPIOD)&0xF0)!=0xF0) //行扫描
  { 
   delay(2400);
   if((GPIO_ReadInputData(GPIOD)&0xF0)!=0xF0)
     switch(GPIO_ReadInputData(GPIOD)&0xf0)
     {
      case(0X70):   KeyValue=KeyValue;      break;
      case(0Xb0):   KeyValue=KeyValue+4;    break;
      case(0Xd0): KeyValue=KeyValue+8;      break;
      case(0Xe0):   KeyValue=KeyValue+12;   break;
     }
   else
      return 0xf0;  //判断是否按下
   while((a<50)&&(GPIO_ReadInputData(GPIOD)!=0xf0)) //防连按
     {
      delay(24000);
      a++;
     }
     
  }
​
​
}

(3)数码管显示函数

 

u16 KeyValue=0;
 u8 a[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x8c,0xbf,0x89,0xb6,0xf6,0x7f}; //0~9 + - * / = .
 u8 wx[]={0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};    //位选
 void delay(u32 k)  //延时函数
 {                                                   
 for(;k>0;k--);
​
 }
 void smg(u8 wei,u8 num ) //数码管显示函数             
 {
      GPIO_SetBits(GPIOE,GPIO_Pin_All);
      GPIO_Write(GPIOE,wx[wei]);
      GPIO_Write(GPIOA,a[num]);                                       
      delay(1000);                         
      GPIO_SetBits(GPIOE,GPIO_Pin_0);    
   }
​
 void smgNum(int32_t num) //多位显示       
 {
  u8 wei,temp;
  if(num >=0)
  {
  for(wei = 8; wei > 0; wei--)
   {
    temp = num%10;
    num = num/10;
    smg(wei,temp);
    if(num == 0)
    break;
   }
  }

 else if(num < 0)   //负数情况
  {
  num = -num;
  for(wei = 8; wei > 0; wei--)
  {
   temp = num%10;
   num = num/10;
   smg(wei,temp);
   if(num == 0)
   break;
   }
  smg(wei-1,11);                     
   }
 }
​
​
​
​
​
 
  • 8
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

身在江湖的郭大侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值