赞
踩
目录
(1)由独立按键的文章我们可以知道J5要接1、2,电路才会变成矩阵键盘电路
(2)如果学过矩阵的人应该都知道,矩阵中的位置是由行列标号决定,所以我们确定按下按键的行列就能确定按下哪个按键,这时候我们就要用到按键扫描
(3)按键扫描:我们的思路是,按键是连接行和列的桥梁,如果往某行或者某列输入低电平,其他行或列为高电平,我们只需要检测所有列或者行是否有低电平即可。
实现功能:用16个按键控制数码管第一个显示0-F
通过观察可以发现通过P30-P33有利于保存数据,所以我们往每列逐次输入低电平,检测行并记录数据。
- #ifndef _PUBLIC_H
- #define _PUBLIC_H
-
- #include "STC15F2K60S2.H"
-
- #define u8 unsigned char
- #define u16 unsigned int
-
- void Delay_1ms(u16 num);
- void Close_All(void);
- void Delay_10us(u16 num);
- #endif
- #include "Public.h"
- // 延时函数(最小约1ms@12MHz)
- void Delay_1ms(u16 num)
- {
- unsigned int i;
- while(num--)
- for(i=0; i<628; i++);
- }
-
-
- /*
- 输入变量:无
- 输出变量:无
- 功能:关闭蜂鸣器和继电器
- */
- void Close_All(void)
- {
- //关闭蜂鸣器和继电器
- P0 = 0x00;
- P2 = (P2 & 0x1f) | 0xA0;
- P2 &= 0x1f;
- //关闭LED灯
- P0 = 0xff;
- P2 = (P2 & 0x1F) | 0x80;
- P2 &= 0x1f;
- }
-
- void Delay_10us(u16 num)
- {
- u16 i;
- while(num--)
- for(i=0; i<3; i++);
- }
- // 使用程序前,将J13调整为IO模式(2-3脚短接)
- #include "Public.h"
-
- u8 M_Buttun();
-
- //定义一个数组存放从1-f对应的16进制数
- //code 关键字的作用是我定义的数据要存放到ROM区,写入后不可以被改变
- u8 code transistor_positive[]=
- {
- 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
- 0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e
- };
- //带小数点
- u8 code transistor_positive_point[]=
- {
- 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,
- 0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e
- };
-
- void Transistor_Show(u8 num,u16 PIS);
-
- // 主函数
- void main(void)
- {
- u8 temp;
- Close_All();
- while(1)
- {
- temp = M_Buttun();
- if(temp)
- {
- Transistor_Show(transistor_positive[temp-4],0x01);
- }
- }
- }
-
- /*
- 输入变量:无
- 输出变量:检测到的按键,如果返回0代表没有检测到任何按键按下
- 功能:矩阵键盘按键检测
- */
- u8 M_Buttun()
- {
- u16 temp=0;
- // u8 i,j;
- u8 i;
- u16 sign = 0x8000;
- //往每行中输入低电平
- //L1:P44 L2:P42 L1:P44 L3:P35 L4:P34
- P44=0;P42=1;P35=1;P34=1;//第一列
- temp = temp | (P3&0x0f);//只保存低四位数据
- P44=1;P42=0;P35=1;P34=1;//第二列
- temp = temp<<4 | (P3&0x0f);//只保存低四位数据
- P44=1;P42=1;P35=0;P34=1;//第三列
- temp = temp<<4 | (P3&0x0f);//只保存低四位数据
- P44=1;P42=1;P35=1;P34=0;//第四列
- temp = temp<<4 | (P3&0x0f);//只保存低四位数据
- for(i=0;i<16;i++)
- {
- if((~temp) == (sign>>i))//从最高位检测到最低位
- return i+4;
- }
- return 0;
- }
-
- /*
- 输入变量:num,显示数字;PIS,显示位置
- 输出变量:无
- 功能:操作138译码器,4-7分别对应Y4-Y7,其余都会使译码器不起作用
- 注意:需要把存放从1-f对应的16进制数数组也移植
- */
- void Transistor_Show(u8 num,u16 PIS)
- {
- //改变数据
- P0 = num;
- P2 = (P2 & 0x1f) | 0xE0;
- P2 &= 0x1f;
-
- //改变显示位置
- P0 = PIS;
- P2 = (P2 & 0x1f) | 0xC0;
- P2 &= 0x1f;
- }
更新:经过定时器的学习和小工程的尝试后,由于单线程的缺点,我们不得不利用定时器把不同的任务在不同时间完成,来实现多线程
- // 使用程序前,将J13调整为IO模式(2-3脚短接)
- #include "Public.h"
- #include "stdio.h"
-
- u8 SEG_COT[9];
- u8 SEG_Code[8];
- u8 temp1;
- u8 key_old,SEG_POS,key_delay,seg_delay;
-
- void Key_Proc();
- void Timer_0_Init(u16 time);
- void SEG_TSL(u8 *input,u8 *output);
- void SEG_Proc();
- // 主函数
- void main(void)
- {
- Close_All();
- Timer_0_Init(1000);//1ms
-
- while(1)
- {
- Key_Proc();
- SEG_Proc();
- }
- }
-
- /********************数码管********************************/
-
- /*
- 输入变量:input,输入字符数组;output:输出16进制数数组
- 输出变量:无
- 功能:将字符串转化为对应数码管显示的16进制数
- */
- void SEG_TSL(u8 *input,u8 *output)
- {
- //j一定要赋值
- u8 i=0,temp=0,j=0;
- for(i=0;i<8;i++,j++)
- {
- switch(input[j])
- {
- case '0': temp = 0xc0; break;
- case '1': temp = 0xf9; break;
- case '2': temp = 0xa4; break;
- case '3': temp = 0xb0; break;
- case '4': temp = 0x99; break;
- case '5': temp = 0x92; break;
- case '6': temp = 0x82; break;
- case '7': temp = 0xf8; break;
- case '8': temp = 0x80; break;
- case '9': temp = 0x90; break;
- case 'A': temp = 0x88; break;
- case 'B': temp = 0x83; break;
- case 'C': temp = 0xc6; break;
- case 'D': temp = 0xA1; break;
- case 'E': temp = 0x86; break;
- case 'F': temp = 0x8E; break;
- case 'H': temp = 0x89; break;
- case 'L': temp = 0xC7; break;
- case 'N': temp = 0xC8; break;
- case 'P': temp = 0x8c; break;
- case 'U': temp = 0xC1; break;
- case '-': temp = 0xbf; break;
- case ' ': temp = 0xff; break;
- default: temp = 0xff;
- }
- if(input[j+1] == ".")
- {
- temp &= 0x7f;
- j++;
- }
- output[i] = temp;
- }
- }
-
- /*
- 输入变量:num,要显示数据;PIS,显示位置,从左到右分别为0-7
- 输出变量:无
- 功能:操作138译码器,4-7分别对应Y4-Y7,其余都会使译码器不起作用
- 注意:需要把存放从1-f对应的16进制数数组也移植
- */
- void SEG_Show(u16 num,u16 PIS)
- {
- //消影
- P0 = 0xff;
- P2 = (P2 & 0x1f) | 0xE0;
- P2 &= 0x1f;
- //改变显示位置
- P0 = 0x01<<PIS;
- P2 = (P2 & 0x1f) | 0xC0;
- P2 &= 0x1f;
- //改变数据
- P0 = num;
- P2 = (P2 & 0x1f) | 0xE0;
- P2 &= 0x1f;
- }
-
- void SEG_Proc()
- {
- if(seg_delay) return;
- seg_delay = 1;
- sprintf(SEG_COT, "%02u",(u16)temp1);
- SEG_TSL(SEG_COT,SEG_Code);
- }
- /*****************按键*******************/
- /*
- 输入变量:无
- 输出变量:检测到的按键,如果返回0代表没有检测到任何按键按下
- 功能:矩阵键盘按键检测
- */
- u8 M_Buttun()
- {
- u16 temp = 0;
- u8 i = 0;
- u16 sign = 0x8000;
- //往每行中输入低电平
- //L1:P44 L2:P42 L1:P44 L3:P35 L4:P34
- P44=0;P42=1;P35=1;P34=1;//第一列
- temp = temp | (P3&0x0f);//只保存低四位数据
- P44=1;P42=0;P35=1;P34=1;//第二列
- temp = temp<<4 | (P3&0x0f);//只保存低四位数据
- P44=1;P42=1;P35=0;P34=1;//第三列
- temp = temp<<4 | (P3&0x0f);//只保存低四位数据
- P44=1;P42=1;P35=1;P34=0;//第四列
- temp = temp<<4 | (P3&0x0f);//只保存低四位数据
- for(i=0;i<16;i++)
- {
- if((~temp) & (sign>>i))//从最高位检测到最低位
- return i+4;
- }
- return 0;
- }
- void Key_Proc()
- {
- u8 key_now,key_down,key_up;
- //延时一段时间消抖,同时节省CPU资源
- if(key_delay) return;
- key_delay = 1;
- //读取按键按下的编号
- key_now = M_Buttun();
- //按键按下:通过判断按键状态是否发生变化,并且变化后状态是否为按下
- key_down = key_now & (key_old ^ key_now);
- //按键抬起
- key_up = ~key_now & (key_old ^ key_now);
- //记录当前状态为下一次检测做准备
- key_old = key_now;
- if(key_down)//按键按下
- {
- temp1 = key_now;
- }
- }
-
-
- /**************定时器**************************/
-
- /*
- 输入变量:定时时长___us
- 输出变量:无
- 功能:配置并开启定时器0
- */
- void Timer_0_Init(u16 time)
- {
- //12T模式
- AUXR &= 0x7f;
- //定时器0 模式0
- TMOD &= 0xf0;
- //设置初值
- TH0 = (65536-time)/256;
- TL0 = (65536-time)%256;
- //打开中断
- ET0 = 1;
- EA = 1;
- //开始计数
- TR0 = 1;
- }
-
- void Timer_0_IT(void) interrupt 1
- {
- //按键10ms检测一次
- if(++key_delay == 10) key_delay = 0;
- //数码管500ms检测一次
- if(++seg_delay == 500) seg_delay = 0;
-
- SEG_Show(SEG_Code[SEG_POS],SEG_POS);
- if(++SEG_POS == 8)SEG_POS = 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。