51单片机教程:单片机键盘接口程序设计

合集下载

51单片机汇编语言教程:25课单片机键盘接口程序设计

51单片机汇编语言教程:25课单片机键盘接口程序设计

51单片机汇编语言教程:第25课-单片机键盘接口程序设计关S未被按下时,P1。

0输入为高电平,S闭合后,P1。

0输入为低电平。

由于按钮是机械触点,当机械触点断开、闭合时,会有抖动动,P1。

0输入端的波形如图2所示。

这种抖动对于人来说是感觉不到的,但对计算机来说,则是完全能感应到的,因为计算机处理的速度是在微秒级,而机械抖动的时间至少是毫秒级,对计算机而言,这已是一个“漫长”的时间了。

前面我们讲到中断时曾有个问题,就是说按钮有时灵,有时不灵,其实就是这个原因,你只按了一次按钮,可是计算机却已执行了多次中断的过程,如果执行的次数正好是奇数次,那么结果正如你所料,如果执行的次数是偶数次,那就不对了。

为使CPU能正确地读出P1口的状态,对每一次按钮只作一次响应,就必须考虑如何去除抖动,常用的去抖动的办法有两种:硬件办法和软件办法。

单片机中常用软件法,因此,对于硬件办法我们不介绍。

软件法其实很简单,就是在单片机获得P1。

0口为低的信息后,不是立即认定S1已被按下,而是延时10毫秒或更长一些时间后再次检测P1。

0口,如果仍为低,说明S1的确按下了,这实际上是避开了按钮按下时的抖动时间。

而在检测到按钮释放后(P1。

0为高)再延时5-10个毫秒,消除后沿的抖动,然后再对键值处理。

不过一般情况下,我们常常不对按钮释放的后沿进行处理,实践证明,也能满足一定的要求。

当然,实际应用中,对按钮的要求也是千差万别,要根据不一样的需要来编制处理程序,但以上是消除键抖动的原则。

键盘与单片机的连接<键盘连接>图3<单片机与键盘接口图>图41、通过1/0口连接。

将每个按钮的一端接到单片机的I/O 口,另一端接地,这是最简单的办法,如图3所示是实验板上按钮的接法,四个按钮分别接到P3.2、P3.3、P3.4和P3.5。

对于这种键各程序能采用持续查询的办法,功能就是:检测是否有键闭合,如有键闭合,则去除键抖动,判断键号并转入对应的键处理。

基于51单片机的USB键盘设计与实现

基于51单片机的USB键盘设计与实现

基于51单片机的USB键盘设计与实现
一、背景介绍
USB键盘是近些年来随着计算机科技发展而出现的一种新型输入设备。

它采用USB接口,是电脑设备接口标准由PS/2接口更换而来的,可以满
足现代电脑日益增长的输入需要。

现代联想主板,微星主板都采用了USB
接口出现,同时USB接口也可以有效投放鼠标、USB外置设备等。

是一种
非常有效的替代方案。

本文的主要目的是基于51单片机的USB键盘设计与实现,在此基础上,可以得出一个具有良好性能的USB键盘,它将成为计算机用户所不可
或缺的输入设备之一
二、功能要求
B键盘的硬件部分,采用51单片机作为核心,屏幕模块和按键
模块作为主要的输入设备。

2.支持USB1.1/2.0标准,能够兼容主流的主板及不同接口的设备,
实现多种输入功能并支持多种操作系统。

3.按键部分及其他硬件设计,需考虑到键盘的灵敏度、机械结构的耐
用性、按键的设计及密度等多方面因素,以提高使用者的操作方便性。

4.软件设计,在51单片机上实现USB键盘的驱动程序,在根据不同
接口的主板及设备对应的协议、功能及数据格式等配置相应的控制程序,
以保证其能够实现对应的输入功能。

三、硬件设计
1.主控:采用51单片机作为主控。

单片机按键程序设计

单片机按键程序设计

单片机按键程序设计单片机按键的基本原理其实并不复杂。

通常,按键就是一个简单的开关,当按键按下时,电路接通,对应的引脚电平发生变化;当按键松开时,电路断开,引脚电平恢复到初始状态。

在程序设计中,我们需要不断检测引脚的电平变化,从而判断按键是否被按下。

在实际的按键程序设计中,有多种方式可以实现按键检测。

其中一种常见的方法是查询法。

这种方法是通过不断地读取按键对应的引脚状态来判断按键是否被按下。

以下是一个简单的查询法示例代码:```cinclude <reg51h> //包含 51 单片机的头文件sbit key = P1^0; //定义按键连接的引脚void main(){while(1) //无限循环{if(key == 0) //如果按键按下,引脚为低电平{//执行按键按下的操作//比如点亮一个 LED 灯P2 = 0xfe;while(key == 0);//等待按键松开}}}```上述代码中,我们首先定义了按键连接的引脚`key`,然后在主函数的无限循环中不断检测按键引脚的状态。

当检测到按键按下时,执行相应的操作,并通过`while(key == 0)`等待按键松开。

除了查询法,还有中断法可以用于按键检测。

中断法的优点是能够及时响应按键动作,不会因为程序的其他操作而导致按键响应延迟。

```cinclude <reg51h> //包含 51 单片机的头文件sbit key = P1^0; //定义按键连接的引脚void int0_init()//中断初始化函数{IT0 = 1; //下降沿触发中断EX0 = 1; //使能外部中断 0EA = 1; //开总中断}void int0() interrupt 0 //外部中断 0 服务函数{//执行按键按下的操作//比如点亮一个 LED 灯P2 = 0xfe;}void main(){int0_init();//初始化中断while(1);//无限循环,保持程序运行}```在上述代码中,我们首先在`int0_init` 函数中对中断进行了初始化设置,然后在`int0` 函数中编写了按键按下时的处理代码。

1-单片机键盘与显示电路设计

1-单片机键盘与显示电路设计

独立式按键 单片机控制系统中,往往只需要几个 功能键,此时,可采用独立式按键结构。 1.独立式按键结构 独立式按键是直接用I/O口线构成的单 个按键电路,其特点是每个按键单独占 用一根I/O口线,每个按键的工作不会影 响其它I/O口线的状态。独立式按键的典 型应用如图9-3所示。
V CC
P 1.0 P 1.1 P 1.2 P 1.3 P 1.4 P 1.5 P 1.6 P 1.7
P1口某位结构

P1口电路中包含有一个数据输出锁存器、一个三态数据输入缓冲器 、一个数据输出的驱动电路。 P1口的功能和驱动能力

P1口只可以作为通用的I/O口使用;
P1可以驱动4个标准的TTL负载电路; 注意在P1口作为通用的I/O口使用时,在从I/O端口读入数据时,应 该首先向相应的I/O口内部锁存器写“1”。 举例:从P1口的低四位输入数据 MOV MOV P1,#00001111b ;;先给P1口底四位写1 A,P1 ;;再读P1口的底四位
依此规律循环,即可使各位数码管显 示将要显示的字符。虽然这些字符是在不 同的时刻分别显示,但由于人眼存在视觉 暂留效应,只要每位显示间隔足够短就可 以给人以同时显示的感觉。 采用动态显示方式比较节省I/O口,硬 件电路也较静态显示方式简单,但其亮度 不如静态显示方式,而且在显示位数较多 时,CPU要依次扫描,占用CPU较多的时 间。
矩阵式按键 单片机系统中,若使用按键较多时,通 常采用矩阵式(也称行列式)键盘 1.矩阵式键盘的结构及原理 矩阵式键盘由行线和列线组成,按键位 于行、列线的交叉点上,其结构如下图9-4 所示。
+5 V 0 4 8 12 0 1 5 9 13 1 2 6 10 14 2 3 7 11 15 3 0 1 2 3

基于C51单片机的键盘及LCD显示

基于C51单片机的键盘及LCD显示
}
}
}
}
1.实验报告格式:
一.实验名称
二.实验目的
三.实验内容
四.设计思想
五.硬件设计
六.程序代码
七.参考文献
2.硬件电路原理图用PROTEL等软件画出。
附录:程序源代码:
附录1
#include "reg51.h"
#include "intrins.h"
#define THCO 0xee
#define TLCO 0x0
i_data&=0xf0;
for(i=0;i<8;i++)
{
SID=(bit)(i_data&0x80);
SCLK=0;
SCLK=1;
i_data=i_data<<1;
}
CS=0;
}
void InitLCD() //液晶初始化
{
send_command(0x30); //功能设置:一次送8位数据,基本指令集
2)ST7920控制器系列中文图形液晶模块资料手册
三、设计指标
利用实验板上提供的键盘电路,LCD显示电路,设计一人机界面,能实现以下功能:
1.LCD上显示“重庆科技学院”
2.按键至少包括0-9的数字键
3.LCD显示按键值
4.电子钟显示:时,分,秒(选作)
四、实验要求
1.以单片机为核心,设计4*4非编码键盘及LCD的硬件电路,画出电路原理图。
{
unsigned char hi=0;//汉字显示
if(x==0) send_command(0x80+y);//
else if(x==1) send_command(0x90+y);

4.3 单片机键盘接口电路设计

4.3 单片机键盘接口电路设计
}
//函数功能:键盘扫描 //检测到有键按下 //延时10ms再去检测 //按键k1被按下 //按键k2被按下 //按键k3被按下 //按键k4被按下
▲▲▲
独立式键盘接口设计案例
void forward(void) { P3=0xfe; led_delay(); P3=0xfd; led_delay(); P3=0xfb; led_delay(); P3=0xf7; led_delay(); P3=0xef; led_delay(); P3=0xdf; led_delay(); P3=0xbf; led_delay(); P3=0x7f; led_delay(); }
break;
}
}
}
▲▲▲
独立式键盘接口设计案例
void key_scan(void) { P1=0xff; if((P1&0x0f )!=0x0f ) { delay10ms(); if(S1==0) keyval=1; if(S2==0) keyval=2; if(S3==0) keyval=3; if(S4==0) keyval=4; }
//处理按下的k1键,“……”为处理程序 //跳出switch语句 //处理按下的k2键 //跳出switch语句 //处理按下的k3键 //跳出switch语句 //处理按下的k4键 //跳出switch语句 //处理按下的k5键 //跳出switch语句
独立式键盘接口设计案例
1.独立式键盘的查询工作方式
{
case 1:forward(); //键值为1,调用正向流水点亮函数
break;
case 2:backward(); //键值为2,调用反向流水点亮函数
break;
case 3:Alter(); //键值为3,调用高、低4位交替点亮函数

计算机接口技术课件 第三章 MCS-51单片机汇编语言与程序设计基础

计算机接口技术课件 第三章 MCS-51单片机汇编语言与程序设计基础

例2:编制一段程序,要求在端口线 :编制一段程序,要求在端口线P1.0,P1.1上分别产生周期为 , 上分别产生周期为 200us和400us的方波.设单片机的外接频率为 的方波. 和 的方波 设单片机的外接频率为12MHz. . 分析:利用定时器产生方波,将定时器设置成为工作方式 , 分析:利用定时器产生方波,将定时器设置成为工作方式3,将寄 存器T0定时 定时100us,T1定时 定时200us,达到定时时间后引起中断,在中 存器 定时 , 定时 ,达到定时时间后引起中断, 断服务程序中各自将P1.0和P1.1引脚取反. 引脚取反. 断服务程序中各自将 和 引脚取反 定时器预设值的设置: 定时器预设值的设置: 单片机的晶体振荡频率为12MHz,计时器的计时频率为1MHz,机 单片机的晶体振荡频率为 ,计时器的计时频率为 , 器周期为1us. 定时 定时100us,因此寄存器 需要计数 需要计数100次 器周期为 . T0定时 ,因此寄存器T0需要计数 次 ,其预 置值为64H+1=9CH. T1定时 定时200us,因此寄存器 需要计数 需要计数200次 置值为 . 定时 ,因此寄存器T1需要计数 次 其预置值为C8H+1=38H. ,其预置值为 . 定时器T0,T1的工作方式设置: 的工作方式设置: 定时器 的工作方式设置 T0采用工作方式 ,因此 采用工作方式3,因此TMOD寄存器的值设置为 寄存器的值设置为#22H. 采用工作方式 寄存器的值设置为 . 定时器T0,T1的控制设置: 的控制设置: 定时器 的控制设置 打开T0, ;要求TCON寄存器的值设置为 寄存器的值设置为#50H. 打开 ,T1;要求 寄存器的值设置为 .
定义存储区域的大小. 6. DS —定义存储区域的大小. 定义存储区域的大小 例: ORG 0350H DS 3

51单片机使用状态机的键盘程序

51单片机使用状态机的键盘程序
break;
}
default://其它
{
step = _Key1_up;//单键抬起消抖
#define Key_Down 0x3D //下箭头
#define Key_Add 0x3B //加
#define Key_Sub 0x37 //减
#define Key_Enter 0x2F //回车
传入参数:无
返回参数:无
设 计:莫汉伟 amo73@
修改日期:2007-10-12
备 注:详细功能和处理算法请参照本文件相关的流程图和文档
**************************************************************************/
#define KeyBuffLen 8 //定义键值环形缓冲区长度为8(缓冲区大小可自由定义,只要大于0即可)
//定义一个键盘缓冲区结构体
struct Struct_KeyBoardBuff
{
u8 buff[KeyBuffLen];//键值环形缓冲区
u8 in; //写键值指示(定时器中断写)
u8 Read_Key(void)
{
u8 Value;
if(Key.out != Key.in)
{
Value=Key.buff[Key.out++];//"读"还没有追上"写",缓冲区有键值,读之
if(Key.out >= KeyBuffLen) //如果"读"跑到了队列尾部,则重新跳回原点
u8 out; //读键值指示(用户读)

第5章 MCS–51单片机的接口与应用 99页 5.8M

第5章  MCS–51单片机的接口与应用 99页 5.8M

(1) 用键盘连接的I/O线的二进制组合表示键码。例如用4行、
4列线构成的16个键的键盘,可使用一个8位I/O口线的高、低4 位口线的二进制数的组合表示16个键的编码,如图5.4(a)所示。 各键相应的键值为88H、84H、82H、81H、48H、44H、42H、 41H、28H、24H、22H、21H、18H、14H、12H、11H。这种键 值编码软件较为简单直观,但离散性大,不便安排散转程序的 入口地址。
第5章 MCS–51单片机的接口与应用 JNB ACC.2,K2 JNB ACC.3,K3 JNB ACC.4,K4 JNB ACC.5,K5 JNB ACC.6,K6 ;检测2号键是否按下,按下转 ;检测3号键是否按下,按下转 ;检测4号键是否按下,按下转 ;检测5号键是否按下,按下转 ;检测6号键是否按下,按下转
;0号键功能程序
;0号键功能程序执行完返回 ;0号键功能程序
JMP START
……………………… PROM7: ……………………… JMP START …
;1号键功能程序执行完返回
;7号键功能程序 ;7号键功能程序执行完返回
第5章 MCS–51单片机的接口与应用
5.1.4 行列式键盘
行列式键盘又叫矩阵式键盘。用I/O口线组成行、列结构, 按键设置在行列的交点上。例如4×4的行列结构可组成16个键 的键盘。因此,在按键数量较多时,可以节省I/O口线。 1.行列式键盘的接口 行列式键盘的接口方法有许多,例如直接接口于单片机的 I/O口上;利用扩展的并行I/O接口;用串行口扩展并行I/O口接 口;利用一种可编程的键盘、显示接口芯片8279进行接口等。 其中,利用扩展的并行I/O接口方法方便灵活,在单片机应用系
MOVX @DPTR,A

单片机原理及接口技术(C51编程)单片机各种应用设计

单片机原理及接口技术(C51编程)单片机各种应用设计

unsigned long freq;
//定义频率
unsigned char code table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,
0x7d,
0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71};
//共阴数码管段码表
void delay_1ms(unsigned int z) { //函数功能:延时约1ms
#define out P2
sbit pos=P0^0;
//定义检测正转控制位P0.0
sbit neg=P0^1;
//定义检测反转控制位P0.1
void delayms(uint);
uchar code
turn[]={0x02,0x06,0x04,0x0c,0x08,0x09,0x01,0x03};
步进电机是将脉冲信号转变为角位移或线位移的开环控 制元件。
非超载的情况下,电机转速、停止位置只取决于脉冲信 号的频率和脉冲数,而不受负载变化的影响,给电机加一脉 冲信号,电机则转过一个步距角。因而步进电机只有周期性 误差而无累积误差,在速度、位置等控制领域有较为广泛的 应用。
12.1 单片机控制步进电机的设计
12.2 单片机控制直流电机
2. 电路设计与编程
当P3.6=1时,P3.7发送PWM波,直流电机正转。且 可通过“INC”和“DEC”两个按键来增大和减少直流电机 转速。反之,P3.6=0时,P3.7发送PWM信号,直流电机反 转。
因此,增大和减小电机转速,实际上是通过按下 “INC”或“DEC”按键来改变输出PWM信号占空比,控 制直流电机转速。图12-4中驱动电路使用了NPN低频、低 噪声小功率达林顿管 2SC2547。

单片机原理及接口技术(C51编程)单片机的开关检测、键盘输入 与显示的接口设计

单片机原理及接口技术(C51编程)单片机的开关检测、键盘输入 与显示的接口设计

5.2.1 开关检测案例1
图5-3 开关、LED发光二极管与P1口的连接
5.2.1 开关检测案例1
参考程序如下: #include <reg51.h> #define uchar unsigned char void delay( ) {
uchar i,j; for(i=0; i<255; i++) for(j=0; j<255; j++); }
5.1.2 I/O端口的编程举例
03 用循环左、右移位函数实现
OPTION
使用C51提供的库函数,即循环左移n位函数和循环右
移n位函数,控制发光二极管点亮。参考程序:
#include <reg51.h> #include <intrins.h> 函数的头文件 #define uchar unsigned char void delay( ) {
5.1.2 I/O端口的编程举例
#include <reg51.h> #define uchar unsigned char uchar tab[ ]={ 0xfe , 0xfd , 0xfb , 0xf7 , 0xef , 0xdf , 0xbf , 0x7f , 0x7f , 0xbf , 0xdf , 0xef , 0xf7 , 0xfb , 0xfd , 0xfe }; /*前8个数据为左移点亮 数据,后8个为右移点亮数据*/ void delay( ) {
// P1口为输入 // 读入P1口的状态,送入state // 屏蔽P1口的高6位
5.2.2 开关检测案例2
switch (state) {
// 判P1口低2位开关状态

用51单片机制作ps2接口的工业小键盘

用51单片机制作ps2接口的工业小键盘

用51单片机制作ps2接口的工业小键盘经过我的验证,是完全可行的。

#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define SEM_FULL 1#define SEM_EMPTY 0uchar bdata ps2char;uchar bdata keystatus;uchar bdata parity_buf;uchar bdata s_buf,r_buf;uchar data last_s;sbit date=P3^0;sbit clock=P3^2;sbit key0=P2^0;sbit key1=P2^1;sbit key2=P2^2;sbit key3=P2^3;sbit key4=P2^4;sbit key5=P2^5;sbit key6=P2^6;sbit key7=P2^7;sbit s_buf0=s_buf^0;sbit r_buf7=r_buf^7;sbit parity_buf0=parity_buf^0;bit ps2_tx_sem=SEM_EMPTY;bit ps2_sendbyte(uchar c);void delayus(uchar us){while(--us);}void delayms(uchar ms){uchar i;while(ms--){for(i=0;i<120;i++);}}bit parity(){bit PARITY=1;uchar i;for(i=0;i<8;i++){PARITY^=parity_buf0;parity_buf=parity_buf>>1;}return PARITY;}void ps2_tx_sem_take(){ps2_tx_sem0:EA=0;if(ps2_tx_sem==SEM_FULL){EA=1;delayus(30);delayus(30);goto ps2_tx_sem0;}ps2_tx_sem=SEM_FULL;EA=1;return;}void ps2_tx_sem_give(){EA=0;ps2_tx_sem=SEM_EMPTY;EA=1;return;}void ps2_clk_check(){ps_tx_sem:EA=0;if(clock==0) // if PS2_CLK low, wait for 50us {EA=1;delayus(30);goto ps_tx_sem;}EA=1;return;}void ps2_send(uchar dat){ps2_tx_sem_take();ps2_clk_check();if(date==1)ps2_sendbyte(dat);ps2_tx_sem_give();}uchar ps2_recbyte() // Return receice data,Error return 0{uchar i;bit PARITY;r_buf=0;while(!clock); // Wait KBCLK Highdelayus(10);if(date) // KBDA TA shoud be low,mean received start bit{ps2_send(0xfe); // if KBDATA is High, return and send error status date(0xfe)return 0;}delayus(30);clock=0; // Device control the KBCLK signalfor(i=0;i<8;i++) // Rising edge of KBCLK, write data into r_buf7{delayus(30);clock=1;delayus(10);if(!clock) return 0; // if KBCLK pull down, mean Host cancelled this sendingr_buf7=date;if(i!=7)r_buf=r_buf>>1;delayus(10);clock=0;}delayus(30);clock=1;delayus(10);if(!clock) return 0; // if KBCLK pull down, mean Host cancelled this sendingPARITY=date; // Receive odd parity bitdelayus(10);clock=0;delayus(30);clock=1;delayus(10); // Receive Stop bit, should be highif(!date) // Otherwise,send error status date(0xfe){ps2_send(0xfe);return 0;}date=0; // Send ACK bit, mean have receive data done delayus(10);clock=0;delayus(30);clock=1; // Set KBCLK and KBDATA highdelayus(10);date=1;delayus(10);parity_buf=r_buf;if(PARITY==parity()) // Check Odd parity{return r_buf;}else{ps2_send(0xfe);return 0;}delayus(30);}bit ps2_sendbyte(uchar c) // Success return 1,Fail return 0{uchar i;bit PARITY;clock=1;if(!clock) // Host prevent Keyboard sending datareturn 0;parity_buf=c;PARITY=parity(); // Calculate value about sending data odd paritylast_s=c; // Save last sending datas_buf=c;if(!clock) // Host prevent Keyboard sending datareturn 0;if(!date) // Host prepared sending command data to keyboard return 0;date=0; // Falling edge of KBCLK send data, start bit 0 delayus(10);clock=0;for(i=0;i<8;i++) // First send LSB{delayus(10);clock=1;delayus(10);if(!clock) // if KBCLK is low,mean Hos prevent Keyboard sending datareturn 0;date=s_buf0;s_buf=s_buf>>1;delayus(10);clock=0;}delayus(10);clock=1;delayus(10);if(!clock) // if KBCLK is low,mean Hos prevent Keyboard sending datareturn 0;date=PARITY; // Sending odd parity bitdelayus(10);clock=0;delayus(10);clock=1;delayus(10);date=1; // Sending stop bitdelayus(10);clock=0;delayus(30);clock=1;delayus(30);delayus(10);return 1;}bit bat(){if(P2!=0xff)return 1;elsereturn 0;}void re_send ( ){ps2_send(last_s);}void reset(){date=1;while(!clock||!date); // Wait KBCLK and KBDATA highif(bat())ps2_send(0xfc); // Self-Check failedelseps2_send(0xaa); // Self-Check successed}bit Check_command ( ) // Keyboard receive host command,return 1 { clock=1;date=1;if(!clock&!date)return 1;elsereturn 0;}void receive_process(){uchar command;if(!Check_command()) return;command=ps2_recbyte();if(!command) return;switch(command){case 0xff: // reset commandps2_send(0xfa);reset();break;case 0xfe: // re-send commandps2_send(0xfa);re_send();break;case 0xf3: // Set Typematic Rate/Delayps2_send (0xfa);break;case 0xf2: // Read IDps2_send(0xfa);ps2_send(0xAB);ps2_send(0x83);break;case 0xee: // respond commandps2_send(0xee);case 0x00:ps2_send(0xfe);default:ps2_send(0xfa); // other command, just send a response of 0xFA break;}}void main(){P2=0xff;if(bat())ps2_send(0xfc);elseps2_send(0xaa);while(1){ if(Check_command())receive_process();key4=0;while(!key4){if(!key0){delayms(5);if(!key0){ps2_sendbyte(0x1C);delayms(5);ps2_sendbyte(0xF0);delayms(1);ps2_sendbyte(0X1C);while(!key0);}}else if(!key1){delayms(5);if(!key1){ps2_sendbyte(0x32);delayms(5);ps2_sendbyte(0xF0);delayms(1);ps2_sendbyte(0X32);while(!key1);}}else if(!key2){delayms(5);if(!key2){ps2_sendbyte(0x21);delayms(5);ps2_sendbyte(0xF0);delayms(1);ps2_sendbyte(0X21);while(!key2);}}else if(!key3){delayms(5);if(!key3){ps2_sendbyte(0x23);delayms(5);ps2_sendbyte(0xF0);delayms(1);ps2_sendbyte(0X23);while(!key3);}}else key4=1;}key5=0;while(!key5){if(!key0){delayms(5);if(!key0){ps2_sendbyte(0x24);delayms(5);ps2_sendbyte(0xF0);delayms(1);ps2_sendbyte(0X24);while(!key0);}}else if(!key1){delayms(5);if(!key1){ps2_sendbyte(0x2B);delayms(5);ps2_sendbyte(0xF0);delayms(1);ps2_sendbyte(0X2B);while(!key1);}}else if(!key2){delayms(5);if(!key2){ps2_sendbyte(0x34);delayms(5);ps2_sendbyte(0xF0);delayms(1);ps2_sendbyte(0X34);while(!key2);}}else if(!key3){delayms(5);if(!key3){ps2_sendbyte(0x33);delayms(5);ps2_sendbyte(0xF0);delayms(1);ps2_sendbyte(0X33);while(!key3);}}else key5=1;}key6=0;while(!key6){if(!key0){delayms(5);if(!key0){ps2_sendbyte(0x43);delayms(5);ps2_sendbyte(0xF0);delayms(1);ps2_sendbyte(0X43);while(!key0);}}else if(!key1){delayms(5);if(!key1){ps2_sendbyte(0x3B);delayms(5);ps2_sendbyte(0xF0);delayms(1);ps2_sendbyte(0X3B);while(!key1);}}else if(!key2){delayms(5);if(!key2){ps2_sendbyte(0x42);delayms(5);ps2_sendbyte(0xF0);delayms(1);ps2_sendbyte(0X42);while(!key2);}}else if(!key3){delayms(5);if(!key3){ps2_sendbyte(0x4B);delayms(5);ps2_sendbyte(0xF0);delayms(1);ps2_sendbyte(0X4B);while(!key3);}}else key6=1;}key7=0;while(!key7){if(!key0){delayms(5);if(!key0){ps2_sendbyte(0x3A);delayms(5);ps2_sendbyte(0xF0);delayms(1);ps2_sendbyte(0X3A);while(!key0);}}else if(!key1){delayms(5);if(!key1){ps2_sendbyte(0x31);delayms(5);ps2_sendbyte(0xF0);delayms(1);ps2_sendbyte(0X31);while(!key1);}}else if(!key2){delayms(5);if(!key2){ps2_sendbyte(0x44);delayms(5);ps2_sendbyte(0xF0);delayms(1);ps2_sendbyte(0X44);while(!key2);}}else if(!key3){delayms(5);if(!key3){ps2_sendbyte(0x4D);delayms(5);ps2_sendbyte(0xF0);delayms(1);ps2_sendbyte(0X4D);while(!key3);}}else key7=1;}}}。

在51单片机上使用PC机ps2键盘

在51单片机上使用PC机ps2键盘

在51单片机上使用PC机ps/2键盘(附源码)本人弄了几天,终于在今天晚上,也就是刚才实验成功,心情特佳,特写出来以享大家。

单片机上应用非编码键盘,各书上均有介绍。

作为实验用,我想到了用PC机的ps/2键盘。

PC机键盘内部有单片机电路来完成编码和去抖动,它按照ps/2协议来发送扫描码。

因此在应用中,我们需要做的只是将扫描码与字符对应起来,大部分事情都由键盘自己完成了。

首先介绍一下键盘的接口,典型的几种接口如下图:其中第一种用于老式键盘(我原来的键盘就是),第二种便是现在的PS/2键盘,第三个不用去管它。

我的实验是按照最常用的PS/2(即第二种)来做的。

再略微介绍一下PS/2协议的相关内容。

PS/2的一个数据帧为11位,时序如下:PS/2帧的第一位是起始位,为0,然后是8位数据位,发送键盘扫描码的一个字节(扫描码为1-4个字节),然后是奇偶校验位,最后是停止位,为1。

这些是在数据线(即1号引脚线)上发送的。

无键按下时,数据线和始终线都保持为1。

当有键按下时,时钟线CLOCK 送出脉冲,同时数据线送出数据。

主机(此处是89c51 MCU)在始终脉冲的下降沿对数据线采样获得数据。

键盘扫描码包括通码和断码,当键按下时发送通码,抬起时发送断码。

更详细的内容可参考所附的《PS/2技术参考》。

根据上述原理,我这样设计了实验:将键盘的脉冲线接至89c51的外部中断输入口(INT0或INT1),当键按下和抬起时有脉冲产生,此脉冲引发MCU中断。

将键盘的DATA线连至89c51的输入口(如P1.0)。

在中断处理程序中,从输入口读入数据,然后通过循环移位对读进的数据位进行处理,1(起始位)、10(奇偶校验)、11(停止位)可抛弃,如不嫌麻烦也可将奇偶校验位加以应用。

当一个数据帧收完后,将处理后剩下的2-9位(即扫描码)通过串口发至PC机,通过PC机的串口监视软件(如“串口调试助手”)来查看。

硬件连线和源码如下:源码:ORG 0000HAJMP MAIN;转入主程序ORG 0003H ;外部中断P3.2脚INT0入口地址AJMP INT ;转入外部中断服务子程序;以下为主程序进行CPU中断方式设置MAIN:MOV SCON,#50H;设置成串口1方式MOV TMOD,#20H;波特率发生器T1工作在模式2上MOV PCON,#80H;波特率翻倍为2400x2=4800BPSMOV TH1,#0F3H;预置初值(按照波特率2400BPS预置初值)MOV TL1,#0F3H;预置初值(按照波特率2400BPS预置初值)SETB EA ;打开CPU总中断请求SETB IT0 ;设定INT0的触发方式为脉冲负边沿触发SETB EX0 ;打开INT0中断请求SJMP $INT: CLR EA ;暂时关闭CPU的所有中断请求CJNE R0,#0,L1L3: INC R0SJMP L5L1: CJNE R0,#9,L2SJMP L3L2: CJNE R0,#10,L4SETB TR1;启动定时器T1MOV SBUF,AMOV R0,#0L5: SETB EA ;允许中断RETI ;退出子程序L4: MOV C,P1.0RRC ASJMP L3END搞定后,当按下和释放键时,会在PC机上显示其扫描码。

51单片机编程

51单片机编程

《单片机C51程序设计》课程标准一、课程性质课程名称:单片机C51程序设计课程代码:109025学时数:84其中课内实验学时数:34学分数:6适用专业:应用电子技术、电子信息工程技术二、课程教学目标1、课程知识目标掌握单片机基本原理,熟悉KEILL软件的使用,熟悉基于proteus软件的单片机的仿真方法,熟悉MCS-51的结构与应用设计方法,掌握C51结构与基本的程序设计方法,通过应用实例熟悉单片机C语言的在单片机应用设计中的用法。

2、课程技能目标通过本课程的教学,要求学生初步具有用C语言进行单片机系统设计的能力。

3、职业能力目标掌握电子产品设计的基本方法,能够以单片机作为核心进行电子产品的设计与开发。

三、课程内容本课程由理论教学模块、实验教学模块两大模块组成。

其中理论教学模块50学时、占60%,实践(含实验和实训)教学模块34学时,占40%。

各教学模块如下:1、理论教学模块2、实验教学模块四、学生学习指南模块一keil软件与proteus软件的使用Keil软件是目前最流行开发MCS-51系列单片机的软件,这从近年来各仿真机厂商纷纷宣布全面支持Keil即可看出。

Keil提供了包括C编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(uVision)将这些部份组合在一起。

掌握这一软件的使用对于使用51系列单片机的爱好者来说是十分必要的,如果你使用C语言编程,那么Keil几乎就是你的不二之选。

Proteus ISIS是一款Labcenter 出品的电路分析实物仿真系统,可仿真各种电路和IC,并支持单片机,元件库齐全,使用方便,是不可多得的专业的单片机软件仿真系统。

该软件的特点:①全部满足我们提出的单片机软件仿真系统的标准,并在同类产品中具有明显的优势。

②具有模拟电路仿真、数字电路仿真、单片机及其外围电路组成的系统的仿真、RS-232动态仿真、C调试器、SPI调试器、键盘和LCD系统仿真的功能;有各种虚拟仪器,如示波器、逻辑分析仪、信号发生器等。

实例制作一个51单片机连接PS2键盘

实例制作一个51单片机连接PS2键盘

实例制作的是用一个AT89C51单片机连接PS/2键盘接口和一个16x2的液晶显示屏,当敲击键盘时,字母可以显示在液晶显示屏上。

这个实例能启发你如何利用单片机来实现对PS/2接口的控制。

实例中提供的源代码修改后可以用到其他PS/2键盘制作项目中。

实例中提供的16x2字符型的液晶显示屏的驱动函数也可以其他项目。

电路原理主电路板中的AT89C51单片机(可以用AT89C52/S51/S52直接替换,如用AT89C2051/4051则需要改程序)组成了51最小化系统。

液晶显示屏于嗯了SMC1602A. 键盘通过PS/2六孔插座和主电路板。

PS/2设备的连接器使用mini-DIN连接器,正有6个引线,其中2个保留为用。

DATA和CLK是可双向通信的I/O线,也就是说通过这两根线,既可以把主机的数据发送到PS/2设备,有可以把设备的数据发向主机。

在无键按下是,DATA 和CLK一直处于高电平状态。

但有键按下时,键盘先检查CLK,看它是否处于高电平,如果是处在低电平,说明主机无空闲接收数据,这是键盘将会把数据放在自己的缓冲区(16Bytes).直到CLK重新被拉高。

键盘获得总线权,这是键盘产生始终信号在CLK上输出。

同时每一个时钟周期在DATA 线上输出一位数据。

第1位是起始位为0,第2-9位为一个八位二进制数据由地位到高位依次输出,第10位为奇偶校验位下面是电路原理图PS/2设备接口用于许多现代的鼠标和键盘,PS/2连接器上有四个管脚:电源地、+5V、数据和时钟。

Host(计算机)提供+5V并且键盘/鼠标的地连接到host的电源地上,数据和时钟都是集电极开路的这就意味着它们通常保持高电平而且很容易下拉到地(逻辑0)。

任何你连接到PS/2鼠标、键盘或host 的设备,在时钟和数据线上要有一个大的上拉电阻。

置“0”就把线拉低,置“1”就让线上浮成高。

从键盘/鼠标发送到主机的数据在时钟信号的下降沿(当时钟从高变到低的时候)被读取;从主机发送到键盘/鼠标的数据在上升沿(当时钟从低变到高的时候)被读取。

单片机C语言-第3章51单片机P0-P3口的C51编程3

单片机C语言-第3章51单片机P0-P3口的C51编程3
(3)键值表:用户在设计键盘程序时,将所有按 键的键值,按照一定的顺利,在code区建立一 个表格,该表格称为键值表。
3.3.3 多个按钮型开关—键盘
2.独立式键盘接口技术
当按键的数量比较少(≤8)时,可采用独立式按键硬 件结构。独立式按键是指直接采用一根 I/O口线构成的 单个按键电路。每个独立式按键单独占用一根I/O口线, 每根I/O口线上的按键的工作状态不会影响其他I/O口线 的工作状态。
• 分析:
• 相当于S1为一个控制开关,控制着 灯的亮、灭闪烁;
• 与例题3-8不同。定义一个位单元, 按键每动作一次,该位单元取反:该单 元为0时,灯全亮,该单元为1时,灯闪 烁。
• include<reg51.h> • #define uchar unsigned char • #define uint unsigned int • sbit S1=P3^2; • bit key=0; //定义一个位,存储按键的动作(偶、奇) • void dlxms( uint xms) • { uint t1, t2; • for( t1=0; t1<xms; t1++) • for( t2=0; t2<110; t2++); •}
• #define uint unsigned int
• uchar data keycode=8;
//键值的初值设为8
• uchar data dir_buf;
//显示缓冲区
• code uchar dirtab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0xbf};//显 示的代码表
• sbit K2=P1^6;
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

51单片机教程:单片机键盘接口程序设计
键盘是由若干按钮组成的开关矩阵,它是单片机系统中最常用的输入设备,用户能通过键盘向计算机输入指令、地址和数据。

一般单片机系统中采和非编码键盘,非编码键盘是由软件来识别键盘上的闭合键,它具有结构简单,使用灵活等特点,因此被广泛应用于单片机系统。

按钮开关的抖动问题
组成键盘的按钮有触点式和非触点式两种,单片机中应用的一般是由机械触点组成的。

在下图中,当开
键盘结构图
|图1
图2
关S未被按下时,P1。

0输入为高电平,S闭合后,P1。

0输入为低电平。

由于按钮是机械触点,当机械触点断开、闭合时,会有抖动动,P1。

0输入端的波形如图2所示。

这种抖动对于人来说是感觉不到的,但对计算机来说,则是完全能感应到的,因为计算机处理的速度是在微秒级,而机械抖动的时间至少是毫秒级,对计算机而言,这已是一个漫长的时间了。

前面我们讲到中断时曾有个问题,就是说按钮有时灵,有时不灵,其实就是这个原因,你只按了一次按钮,可是计算机却已执行了多次中断的过程,如果执行的次数正好是奇数次,那么结果正如你所料,如果执行的次数是偶数次,那就不对了。

为使CPU能正确地读出P1口的状态,对每一次按钮只作一次响应,就必须考虑如何去除抖动,常用的去抖动的办法有两种:硬件办法和软件办法。

单片机中常用软件法,因此,对于硬件办法我们不介绍。

软件法其实很简单,就是在单片机获得P1。

0口为低的信息后,不是立即认定S1已被按下,而是延时。

相关文档
最新文档