51单片机学习笔记

您所在的位置:网站首页 单片机按键输入程序 51单片机学习笔记

51单片机学习笔记

2023-10-28 05:23| 来源: 网络整理| 查看: 265

文中绝大数代码来自普51开发板实验例程

文章目录 实验基本内容仿真扩展功能,实现编辑框扩展仿真完整代码

实验基本内容

LCD1602的使用已经在实验22:LCD1602液晶作了介绍,矩阵键盘也在实验7:矩阵按键中作了介绍,所以本文就不讲它们的用法和代码实现了。

本实验核心功能是将矩阵键盘按键的值读出,然后显示在LCD1602上。 代码实现上,先定义了一个数组,里面存放了0-F共16个字符,当检测到矩阵键盘有按键按下,则将读到的键值显示在LCD1602上。 以下是核心代码(完整代码见文末)

unsigned char KeyValue; //用来存放读取到的键值 unsigned char KeyState; //用来存放按键状态 unsigned char dat[]="0123456789ABCDEF"; unsigned char test[]="51_Learing_day4"; void Delay10ms(); void KeyDown(); //检测按键函数 /******************************************************************************* * 函 数 名 : main * 函数功能 : 主函数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void main(void) { unsigned char i; LcdInit(); KeyState=0; //按键状态复位 for(i=0;i KeyDown(); //检测按键 if(KeyState) //检测到有按键按下 { KeyState=0; //状态复位 LcdWriteCom(0x80+0x40); //设置数据指针起点为第二行,默认为第一行 LcdWriteData(dat[KeyValue]); //显示数据(按键值)到LCD } } } 仿真

请添加图片描述

扩展功能,实现编辑框

原实验只实现了显示单个按键值,这里做一个简单的加强,当多次按下按键时,键值在LCD上以字符串形式呈现,实现类似编辑框的效果。 代码改动也不大,以下是main函数代码,其他代码同原实验。(由于第一次玩LCD1602,所以只是瞎写了一些功能,比如下面的模拟光标闪烁,听说LCD1602自动硬件光标闪烁?以后再了解吧)

unsigned char KeyValue; //用来存放读取到的键值 unsigned char KeyState; //用来存放按键状态 unsigned char dat[]="0123456789ABCDEF"; unsigned char test[]="51_Learing_day4"; void Delay10ms(); void KeyDown(); //检测按键函数 /******************************************************************************* * 函 数 名 : main * 函数功能 : 主函数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void main(void) { unsigned char i; unsigned char cursor = '_'; //模拟光标 unsigned int cnt = 0; //光标计数 unsigned char len = 0; //编辑框现有字符数 LcdInit(); KeyState=0; //按键状态复位 for(i=0;i KeyDown(); //检测按键 if(KeyState) //检测到有按键按下 { if(len LcdWriteCom(0x80+0x40 + len); //光标在当前字符后面显示 LcdWriteData(cursor); //显示光标 } else if(cnt == 5000) { cnt = 0; LcdWriteCom(0x80+0x40 + len); //不显示光标,闪烁一次 LcdWriteData(' '); } } } 扩展仿真

请添加图片描述

完整代码

以下是普中51中级实验源代码(未改动),上面两个main函数是我修改过的

main.c

/******************************************************************************* 注意事项: 根据自己使用的LCD1602是否带有转接板,如果带有转接板的即为4位,需在LCD.H头文件中 将宏#define LCD1602_4PINS打开,我们这里使用的LCD1602是8位,所以默认将该宏注释。 单片机与矩阵键盘模块接线说明: 矩阵按键接线参考矩阵按键实验接线图 实验操作: S1-S4:0-3 S5-S8:4-7 S9-S12:8-B S13-S16:C-F。 *******************************************************************************/ #include #include"lcd.h" #define GPIO_KEY P1 unsigned char KeyValue; //用来存放读取到的键值 unsigned char KeyState; //用来存放按键状态 unsigned char PuZh[]=" Pechin Science "; unsigned char dat[]="0123456789ABCDEF"; void Delay10ms(); //延时50us void KeyDown(); //检测按键函数 /******************************************************************************* * 函 数 名 : main * 函数功能 : 主函数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void main(void) { unsigned char i; LcdInit(); KeyState=0; for(i=0;i KeyDown(); if(KeyState) { KeyState=0; LcdWriteCom(0x80+0x40); LcdWriteData(dat[KeyValue]); } } } /******************************************************************************* * 函 数 名 : KeyDown * 函数功能 : 检测有按键按下并读取键值 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void KeyDown(void) { char a; GPIO_KEY=0x0f; if(GPIO_KEY!=0x0f) { Delay10ms(); if(GPIO_KEY!=0x0f) { KeyState=1; //测试列 GPIO_KEY=0X0F; // Delay10ms(); switch(GPIO_KEY) { case(0X07): KeyValue=0;break; case(0X0b): KeyValue=1;break; case(0X0d): KeyValue=2;break; case(0X0e): KeyValue=3;break; // default: KeyValue=17; //检测出错回复17意思是把数码管全灭掉。 } //测试行 GPIO_KEY=0XF0; Delay10ms(); switch(GPIO_KEY) { case(0X70): KeyValue=KeyValue;break; case(0Xb0): KeyValue=KeyValue+4;break; case(0Xd0): KeyValue=KeyValue+8;break; case(0Xe0): KeyValue=KeyValue+12;break; // default: KeyValue=17; } while((a unsigned char a,b,c; for(c=1;c>0;c--) for(b=38;b>0;b--) for(a=130;a>0;a--); }

lcd.c

#include"lcd.h" /******************************************************************************* * 函 数 名 : Lcd1602_Delay1ms * 函数功能 : 延时函数,延时1ms * 输 入 : c * 输 出 : 无 * 说 名 : 该函数是在12MHZ晶振下,12分频单片机的延时。 *******************************************************************************/ void Lcd1602_Delay1ms(uint c) //误差 0us { uchar a,b; for (; c>0; c--) { for (b=199;b>0;b--) { for(a=1;a>0;a--); } } } /******************************************************************************* * 函 数 名 : LcdWriteCom * 函数功能 : 向LCD写入一个字节的命令 * 输 入 : com * 输 出 : 无 *******************************************************************************/ #ifndef LCD1602_4PINS //当没有定义这个LCD1602_4PINS时 void LcdWriteCom(uchar com) //写入命令 { LCD1602_E = 0; //使能 LCD1602_RS = 0; //选择发送命令 LCD1602_RW = 0; //选择写入 LCD1602_DATAPINS = com; //放入命令 Lcd1602_Delay1ms(1); //等待数据稳定 LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); //保持时间 LCD1602_E = 0; } #else void LcdWriteCom(uchar com) //写入命令 { LCD1602_E = 0; //使能清零 LCD1602_RS = 0; //选择写入命令 LCD1602_RW = 0; //选择写入 LCD1602_DATAPINS = com; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改 Lcd1602_Delay1ms(1); LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); LCD1602_E = 0; // Lcd1602_Delay1ms(1); LCD1602_DATAPINS = com LCD1602_E = 0; //使能清零 LCD1602_RS = 1; //选择写入数据 LCD1602_RW = 0; //选择写入 LCD1602_DATAPINS = dat; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改 Lcd1602_Delay1ms(1); LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); LCD1602_E = 0; LCD1602_DATAPINS = dat LcdWriteCom(0x32); //将8位总线转为4位总线 LcdWriteCom(0x28); //在四位线下的初始化 LcdWriteCom(0x0c); //开显示不显示光标 LcdWriteCom(0x06); //写一个指针加1 LcdWriteCom(0x01); //清屏 LcdWriteCom(0x80); //设置数据指针起点 } #endif

lcd.h

#ifndef __LCD_H_ #define __LCD_H_ /********************************** 当使用的是4位数据传输的时候定义, 使用8位取消这个定义 **********************************/ //#define LCD1602_4PINS /********************************** 包含头文件 **********************************/ #include //---重定义关键词---// #ifndef uchar #define uchar unsigned char #endif #ifndef uint #define uint unsigned int #endif /********************************** PIN口定义 **********************************/ #define LCD1602_DATAPINS P0 sbit LCD1602_E=P2^7; sbit LCD1602_RW=P2^5; sbit LCD1602_RS=P2^6; /********************************** 函数声明 **********************************/ /*在51单片机12MHZ时钟下的延时函数*/ void Lcd1602_Delay1ms(uint c); //误差 0us /*LCD1602写入8位命令子函数*/ void LcdWriteCom(uchar com); /*LCD1602写入8位数据子函数*/ void LcdWriteData(uchar dat) ; /*LCD1602初始化子程序*/ void LcdInit(); #endif


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3