I/O口综合实践项目
1)矩阵键盘键盘的每一个按键,进行编码键值码(1~16);
2)单片将对应的键值码转换为数码管编码;
3)数码管持续显示键值码(0~15);
4)按下按键,释放按键后,持续持续显示键值码,直到下一次按键被按下为止。
软件系统框图如下:
功能需求分析:
按下按键,释放按键后,持续持续显示键值码,直到下一次按键被按下为止。当按键被按下,才会产生键值码,当手释放后,键值码为0。如果需要按下按键后释放,还有显示,需要将数据保存起来。
由于键值码最多只有两位数,因此建立以下的一维数组进行数组储存键值码。
uchar table2[]={0,0};
新增inputNum函数对按键的键值,进行存储
/*******************************************************
*
* Function name :inputNum
* Description : 将键值码保存在一维数组
* Parameter :
*
* Return :None
**********************************************************/
void inputNum()
{
uchar num,i;
i=0;
//调用KeyDown函数,返回键值码;
num = keyDown();
//当键值码>1时,按键被拿下
if(num>0){
num--;
//将上一次的数据进行清零
for(i;i<2;i++){
table2[i]=0;
}
//保存键值码
if(num<10){
table2[0]=num;
}
else{
//保存个位数
table2[0]=num%10;
//保存十位数
table2[1]=num/10;
}
}
}
main函数
系统初始化,然后扫描键盘与显示
/*******************************************************
*
* Function name :main
* Description :扫描键盘与显示
* Parameter :None
* Return :None
**********************************************************/
void main() {
sysinit();
while(1) {
//扫描键盘将键值码保存到一维数组
inputNum();
//显示数组
showsmg(0,table2[0]);
delay(5); //添加延时函数,防止会有显示乱码,必须加
if(table2[1]==1){
showsmg(1,table2[1]);
delay(5); //添加延时函数,防止会有显示乱码,必须加
}
}
}
项目详细实现代码:
/********************************************************************************
* @File name: main.c
* @Author: adamChen
* @Version: 1.1
* @Date: 2020-08-17
* @Description: LED display
* @contact:975805363@qq.com
********************************************************************************/
#include "reg52.h"
typedef unsigned char uchar;
typedef unsigned int uint;
uchar code table[]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x80};
uchar table2[]={0,0};
sbit smg2 = P2^4;
sbit smg1 = P2^3;
sbit smg0 = P2^2;
sbit driver_key1 = P1^7;
sbit driver_key2 = P1^6;
sbit driver_key3 = P1^5;
sbit driver_key4 = P1^4;
sbit snesor_key1 = P1^3;
sbit snesor_key2 = P1^2;
sbit snesor_key3 = P1^1;
sbit snesor_key4 = P1^0;
void sysinit();
void delay(uint ms);
uchar keyDown();
void showsmg(uchar selSmg,uchar dat);
void inputNum();
/*******************************************************
*
* Function name :main
* Description :扫描键盘与显示
* Parameter :None
* Return :None
**********************************************************/
void main() {
sysinit();
while(1) {
//扫描键盘将键值码保存到一维数组
inputNum();
//显示数组
showsmg(0,table2[0]);
delay(5); //添加延时函数,防止会有显示乱码,必须加
if(table2[1]==1){
showsmg(1,table2[1]);
delay(5); //添加延时函数,防止会有显示乱码,必须加
}
}
}
/*******************************************************
*
* Function name :sysinit
* Description : 系统初始化
* Parameter :
*
* Return :None
**********************************************************/
void sysinit() // ms代表需要延时的毫秒数
{
showsmg(0,0);
}
/*******************************************************
*
* Function name :inputNum
* Description : 将键值码保存在一维数组
* Parameter :
*
* Return :None
**********************************************************/
void inputNum()
{
uchar num,i;
i=0;
//调用KeyDown函数,返回键值码;
num = keyDown();
//当键值码>1时,按键被拿下
if(num>0){
num--;
//将上一次的数据进行清零
for(i;i<2;i++){
table2[i]=0;
}
//保存键值码
if(num<10){
table2[0]=num;
}
else{
//保存个位数
table2[0]=num%10;
//保存十位数
table2[1]=num/10;
}
}
}
/*******************************************************
*
* Function name :delay
* Description : 延时函数
* Parameter :
@ms millisecond(毫秒)
*
* Return :None
**********************************************************/
void delay(unsigned int ms) // ms代表需要延时的毫秒数
{
uint x,y;
for(x=ms; x>0; x--)
for(y=110; y>0; y--);
}
/*******************************************************
*
* Function name :KeyDown
* Description : 扫描按键
* Parameter :
@selsmg 选择数码管第几个
@num 显示数值
*
* Return :KeyNum
**********************************************************/
uchar keyDown() {
uchar num=0;
driver_key1 = 0;
if(snesor_key1==0)
{
delay(10);
if(snesor_key1==0)
num = 1;
}
if(snesor_key2==0)
{
delay(10);
if(snesor_key2==0)
num = 2;
}
if(snesor_key3==0)
{
delay(10);
if(snesor_key3==0)
num = 3;
}
if(snesor_key4==0)
{
delay(10);
if(snesor_key4==0)
num = 4;
}
driver_key1 = 1;
driver_key2 = 0;
if(snesor_key1==0)
{
delay(10);
if(snesor_key1==0)
num = 5;
}
if(snesor_key2==0)
{
delay(10);
if(snesor_key2==0)
num = 6;
}
if(snesor_key3==0)
{
delay(10);
if(snesor_key3==0)
num = 7;
}
if(snesor_key4==0)
{
delay(10);
if(snesor_key4==0)
num = 8;
}
driver_key2 = 1;
driver_key3 = 0;
if(snesor_key1==0)
{
delay(10);
if(snesor_key1==0)
num = 9;
}
if(snesor_key2==0)
{
delay(10);
if(snesor_key2==0)
num = 10;
}
if(snesor_key3==0)
{
delay(20);
if(snesor_key3==0)
num = 11;
}
if(snesor_key4==0)
{
delay(10);
if(snesor_key4==0)
num = 12;
}
driver_key3 = 1;
driver_key4 = 0;
if(snesor_key1==0)
{
delay(10);
if(snesor_key1==0)
num = 13;
}
if(snesor_key2==0)
{
delay(10);
if(snesor_key2==0)
num = 14;
}
if(snesor_key3==0)
{
delay(10);
if(snesor_key3==0)
num = 15;
}
if(snesor_key4==0)
{
delay(10);
if(snesor_key4==0)
num = 16;
}
driver_key4 = 1;
return num;
}
/*******************************************************
*
* Function name :showsmg
* Description : 数码管显示
* Parameter :
@selsmg 选择数码管第几个
@num 显示数值
*
* Return :None
**********************************************************/
void showsmg(uchar selSmg,uchar dat) {
//选择显示数码管第几个,拆解为38译码器对应编码
smg0 = selSmg&0x01;
smg1 = (bit)((selSmg>>1)&0x01);
smg2 = (bit)((selSmg>>2)&0x01);
//将数码管编码(一维数组)赋值给P0口,显示对用数字
P0 = table[dat];
}
---------------------------------------------------------
如果觉得文章还不错,那就扫码关注吧!