IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 51单片机矩阵键盘控制LCD屏幕 -> 正文阅读

[嵌入式]51单片机矩阵键盘控制LCD屏幕

课程资源

B站矩阵键盘课程

实现代码

Delay.c

void Delay(unsigned int xms)		
{	//延迟x毫秒
	while(xms--)
	{
		unsigned char i, j;

		i = 12;
		j = 169;
		do
		{
			while (--j);
		} while (--i);
	}
}

MatrixKey.c

#include <REGX52.H>
#include "Delay.h"
#define KEY_SCAN P1

void MatrixKey(unsigned char* keyValue)
{
	KEY_SCAN = 0X0F;
	if(KEY_SCAN!=0X0F)
	{	//判断是否按下
		Delay(10);	//消除抖动
		
		KEY_SCAN = 0X0F;	//列扫描
		switch(KEY_SCAN)
		{
			case 0X07:*keyValue = 0;break;
			case 0X0B:*keyValue = 1;break;
			case 0X0D:*keyValue = 2;break;
			case 0X0E:*keyValue = 3;break;
		}
		
		KEY_SCAN = 0XF0; //行扫描
		switch(KEY_SCAN)
		{
			case 0X70:*keyValue = *keyValue;break;
			case 0XB0:*keyValue += 4;break;
			case 0XD0:*keyValue += 8;break;
			case 0XE0:*keyValue += 12;break;
		}
		while(KEY_SCAN!=0XF0)
		{	//检测按键是否松开,松开时返回键值
			Delay(10);
		}
	}	
}

LCD1602.C

#include <REGX52.H>

//引脚配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0

//函数定义:
/**
  * @brief  LCD1602延时函数,12MHz调用可延时1ms
  * @param  无
  * @retval 无
  */
void LCD_Delay()
{
	unsigned char i, j;

	i = 2;
	j = 239;
	do
	{
		while (--j);
	} while (--i);
}

/**
  * @brief  LCD1602写命令
  * @param  Command 要写入的命令
  * @retval 无
  */
void LCD_WriteCommand(unsigned char Command)
{
	LCD_RS=0;	//选择操作控制字
	LCD_RW=0;	//写操作
	LCD_DataPort=Command;	//输入写入控制字的数据
	LCD_EN=1;	//使能信号,LCD选中
	LCD_Delay();	
	LCD_EN=0;
	LCD_Delay();
}

/**
  * @brief  LCD1602写数据
  * @param  Data 要写入的数据
  * @retval 无
  */
void LCD_WriteData(unsigned char Data)
{
	LCD_RS=1;	//选择数据寄存器
	LCD_RW=0;	//写操作
	LCD_DataPort=Data;	//需要写入的数据
	LCD_EN=1;	
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}

/**
  * @brief  LCD1602设置光标位置
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @retval 无
  */
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
	if(Line==1)
	{
		LCD_WriteCommand(0x80|(Column-1));
	}
	else if(Line==2)
	{
		LCD_WriteCommand(0x80|(Column-1+0x40));
	}
}

/**
  * @brief  LCD1602初始化函数
  * @param  无
  * @retval 无
  */
void LCD_Init()
{
	LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
	LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
	LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
	LCD_WriteCommand(0x01);//光标复位,清屏
}

/**
  * @brief  在LCD1602指定位置上显示一个字符
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @param  Char 要显示的字符
  * @retval 无
  */
void LCD_ShowChar(unsigned char Line,unsigned char Column,unsigned char Char)
{
	LCD_SetCursor(Line,Column);
	LCD_WriteData(Char);
}

main.c

#include <REGX52.H>
#include "LCD1602.h"
#include "Delay.h"
#include "MatrixKey.h"
//从左到右从上到下4x4矩阵按键对应字符
unsigned char KeyValueTbl[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
unsigned char value;	//按键键值

void main()
{
	LCD_Init();	//初始化LCD1602屏幕
	LCD_ShowString(1,5,"Welcome!");	//在第1行第5列开始显示字符串
	while(1)
	{	//检测矩阵键盘
		MatrixKey(&value);	//返回键值给value
		LCD_ShowChar(2,8,KeyValueTbl[value]);	//在LCD屏幕的2行8列位置输出对应按键字符
	}
}

出现的错误

MatrixKey函数与main函数之间逻辑关系错误
错误代码——MatrixKey()

unsigned char MatrixKey(void)
{
	unsigned char keyValue = 0;
	KEY_SCAN = 0X0F;
	if(KEY_SCAN!=0X0F)
	{
		Delay(10);
		
		KEY_SCAN = 0X0F;	//?ì2aáD
		switch(KEY_SCAN)
		{
			case 0X07:*keyValue = 0;break;
			case 0X0B:*keyValue = 1;break;
			case 0X0D:*keyValue = 2;break;
			case 0X0E:*keyValue = 3;break;
		}
		
		KEY_SCAN = 0XF0; //?ì2aDD
		switch(KEY_SCAN)
		{
			case 0X70:*keyValue = *keyValue;break;
			case 0XB0:*keyValue += 4;break;
			case 0XD0:*keyValue += 8;break;
			case 0XE0:*keyValue += 12;break;
		}
		while(KEY_SCAN!=0XF0)
		{
			Delay(10);
		}
	}	
	
	return keyValue;
}

错误原因:

  1. 当按下按键松手后,返回keyValue值给value,然后接着将value值对应KeyValueTbl中的值在LCD输出
  2. 很快,再一次进入MatrixKey(),keyValue值重新赋值为0,此时没有按键按下,keyValue值返回值0赋值给value,将0在LCD屏幕输出
  3. 因为51单片机频率为12KHZ,运行程序速度很快,前两步骤间时间间隔很短,所以肉眼看上去屏幕输出永远为0(没有键值输入的情况)
  4. 所以,最根本的原因是给LCD屏幕输入的值没有保持到下一次按下按键就清零处理了,导致无法观察到每个按键的键值

改进方案

  1. 在main.c文件中设置全局变量value
  2. unsigned char MatrixKey(void)改为void MatrixKey(unsigned char* keyValue)
  3. main函数中调用MatrixKey(&value);使每次keyValue的值能返回到value中,有按键时输出按键值;没有按键时输出上一次按键值

注意

void MatrixKey(unsigned char keyValue){...}

//main.c中
int main()
{
	...
	MatrixKey(value);
}

这种修改方式并不能使keyValue的值返回到value中,因为实际参数(value)只是把值复制给了形式参数(keyValue),在函数中对于形式参数的修改都不会影响到实际参数,即返回后value的值始终为0

小结

单片机编程过程中,while(1){…}循环体内的逻辑结构要考虑到单片机执行速度带来的问题,要充分考虑一次while循环对下一次循环带来的影响

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-03-30 18:41:35  更:2022-03-30 18:44:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:32:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码