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);
}
}