学习51单片机与PS2鼠程序+LCD1602显示坐.docx

上传人:牧羊曲112 文档编号:3417344 上传时间:2023-03-13 格式:DOCX 页数:10 大小:40.34KB
返回 下载 相关 举报
学习51单片机与PS2鼠程序+LCD1602显示坐.docx_第1页
第1页 / 共10页
学习51单片机与PS2鼠程序+LCD1602显示坐.docx_第2页
第2页 / 共10页
学习51单片机与PS2鼠程序+LCD1602显示坐.docx_第3页
第3页 / 共10页
学习51单片机与PS2鼠程序+LCD1602显示坐.docx_第4页
第4页 / 共10页
学习51单片机与PS2鼠程序+LCD1602显示坐.docx_第5页
第5页 / 共10页
亲,该文档总共10页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《学习51单片机与PS2鼠程序+LCD1602显示坐.docx》由会员分享,可在线阅读,更多相关《学习51单片机与PS2鼠程序+LCD1602显示坐.docx(10页珍藏版)》请在三一办公上搜索。

1、学习51单片机与PS2鼠程序+LCD1602显示坐学习51单片机与PS2鼠标程序 简介:PS2鼠标,LCD1602显示坐标,有LED指示灯,等等其实发现学起来也很简单。 第一步: PS/2接口和协议简介 1 PS/2接口和协议 1.1 接口的物理特性 PS/2接口用于许多现代的鼠标和键盘,由IBM最初开发和使用物理上的PS/2接口有两种类型的连接器:5脚的DIN和6脚的mini-DIN图1就是两种连接器的引脚定义使用中,主机提供+5V电源给鼠标,鼠标的地连接到主机电源地上 1.2 接口协议原理 PS/2鼠标接口采用一种双向同步串行协议即每在时钟线上发一个脉冲,就在数据线上发送一位数据在相互传输

2、中,主机拥有总线控制权,即它可以在任何时候抑制鼠标的发送方法是把时钟线一直拉低,鼠标就不能产生时钟信号和发送数据在两个方向的传输中,时钟信号都是由鼠标产生,即主机不产生通信时钟信号 如果主机要发送数据,它必须控制鼠标产生时钟信号方法如下:主机首先下拉时钟线至少100s抑制通信,然后再下拉数据线,最后释放时钟线通过这一时序控制鼠标产生时钟信号当鼠标检测到这个时序状态,会在10ms内产生时钟信号如图3中 A 时序段主机和鼠标之间,传输数据帧的时序如图2图3所示2.2 数据包结构在主机程序中,利用每个数据位的时钟脉冲触发中断,在中断例程中实现数据位的判断和接收在实验过程中,通过合适的编程,能够正确控

3、制并接收鼠标数据但该方案有一点不足,由于每个CLOCK都要产生一次中断,中断频繁,需要耗用大量的主机资源 2 PS/2鼠标的工作模式和协议数据包格式 2.1 PS/2鼠标的四种工作模式 PS/2鼠标的四种工作模式是:Reset模式,当鼠标上电或主机发复位命令 0xFF给它时进入这种模式;Stream模式鼠标的默认模式,当鼠标上电或复位完成后,自动进入此模式,鼠标基本上以此模式工作;Remote模式,只有在主机发送了模式设置命令 0xF0后,鼠标才进入这种模式;Wrap模式,这种模式只用于测试鼠标与主机连接是否正确 PS/2鼠标在工作过程中,会及时把它的状态数据发送给主机发送的数据包格式如表1所

4、示 Byte1中的Bit0Bit1Bit2分别表示左右中键的状态,状态值0表示释放,1表示按下Byte2和Byte3分别表示X轴和Y轴方向的移动计量值,是二进制补码值Byte4的低四位表示滚轮的移动计量值,也是二进制补码值,高四位作为扩展符号位这种数据包由带滚轮的三键三维鼠标产生若是不带滚轮的三键鼠标,产生的数据包没有Byte4 其余的相同 第二步: /* XXXX.C #include #includemouse.h #includeLCD1602_4.h #includeDELAY52.h sbit beep=P37; void main LCD1602_Init;/初始化液晶1602 I

5、nit_mouse; mouse_send_data(0xf4);/向鼠标发送0xF4命令发其开始工作 /mouse_send_data(0xc8); /mouse_send_data(0x64); /mouse_send_data(0x50); EX1=0;/关掉外部中断以避开鼠标发回的应答 delayms(100); EX1=1;/重开外部中断 while(1) led=1; CLEARSCREEN;/清屏 LCD1602_write_string(0,0,x:); num(0,2,move_x);/x坐标值 LCD1602_write_string(0,8,y:); num(0,10,m

6、ove_y);/y坐标值 / LCD1602_write_string(1,8,z:); / num(1,10,move_z);/y坐标值 if(mouse_data0&0x01)/如果点下左键 beep=0; LCD1602_write_string(1,0,left); else if(mouse_data0&0x02)/如果点下右键 beep=0; 部分*/ LCD1602_write_string(1,0,right); else if(mouse_data0&0x04)/如果点下中键 beep=0; LCD1602_write_string(1,0,middle); else bee

7、p=1; LCD1602_write_string(1,0,nothing); delayms(50); /*XXX.H文件部分*/ #ifndef MOUSE_H #define MOUSE_H #includeDELAY52.h /Set sample rate 200; /Set sample rate 200; /Set sample rate 80; sbit mouse_SDA=P34;/数据线P3_5 sbit mouse_CLK=P33;/时钟线P3_3 sbit led=P36; /sbit led1=P13; uchar bdata mouse_byte; /接收字节 bd

8、ata-可寻址的片内RAM sbit mouse_byte_bit0=mouse_byte0;/mouse_byte第0位 sbit mouse_byte_bit1=mouse_byte1;/mouse_byte第1位 sbit mouse_byte_bit2=mouse_byte2;/mouse_byte第2位 sbit mouse_byte_bit3=mouse_byte3;/mouse_byte第3位 sbit mouse_byte_bit4=mouse_byte4;/mouse_byte第4位 sbit mouse_byte_bit5=mouse_byte5;/mouse_byte第5

9、位 sbit mouse_byte_bit6=mouse_byte6;/mouse_byte第6位 sbit mouse_byte_bit7=mouse_byte7;/mouse_byte第7位 uchar bdata mouse_fuction;/功能信息字节 uchar mouse_buffer11;/接收位数据缓冲区 uchar mouse_buffer_bit=0;/mouse_buffermouse_buffer_bit uchar mouse_data3;/接收鼠标数据缓冲区,分别存放:功能信息字节,x位移量,y位移量 uchar mouse_data_bit=0;/mouse_d

10、atamouse_data_bit uint move_x=10000;/存放横坐标 uint move_y=10000;/存放纵坐标 void Init_mouse(void) TCON=0x00; / /中断触发方式0 EA=1; /开放中断 EX1=1;/允许外部中断1 ET0=0x01;/允许全局中断,允许设定时器/计数器0溢出中断 开定时器中断0 PX1=1;/设置中断优先级 设外部中断1为最高优先级别 /* 发送数据 */ void mouse_send_data(uchar dat) uchar i; EX1=0; /*关闭外部中断1*/ ACC=dat; /*将要发送的数据放入

11、A寄存器*/ mouse_CLK=0; /*拉低时钟线*/ delay10us(200); /*延时100us以上*/ mouse_SDA=0; /*拉低数据线*/ delay10us(40); mouse_CLK=1; /*释放时钟线*/ for(i=0;ii)&0x01; /*发送数据位*/ while(mouse_CLK=0); /*等待设备释放时钟线*/ while(mouse_CLK=1); mouse_SDA=P; /*发送校验位,奇校验*/ while(mouse_CLK=0); while(mouse_CLK=1); mouse_SDA=1; /*发送停止位*/ while(m

12、ouse_CLK=0); while(mouse_CLK=1); /*应答位*/ while(mouse_CLK=0); EX1=1; /*打开外部中断1*/ /* 奇校检 */ uchar Checkout(void) ACC=mouse_byte; if(P=mouse_buffer9) return 1; else return 0; /* 数据分析及处理 */ void data_analyse(void) /将收到的11位信号中截取8位数据放进mouse_byte mouse_byte_bit0=mouse_buffer1; mouse_byte_bit1=mouse_buffer2

13、; mouse_byte_bit2=mouse_buffer3; mouse_byte_bit3=mouse_buffer4; mouse_byte_bit4=mouse_buffer5; mouse_byte_bit5=mouse_buffer6; mouse_byte_bit6=mouse_buffer7; mouse_byte_bit7=mouse_buffer8; if(Checkout)/如果校验正确 if(mouse_data_bit3) mouse_datamouse_data_bit+=mouse_byte; if(mouse_data_bit=3) mouse_data_bi

14、t=0; if(mouse_data0&0x10)/如果X sign bit为1,表示鼠标向左移 move_x-=(256-mouse_data1);/x坐标减 else move_x+=mouse_data1;/x坐标加 if(mouse_data0&0x20) move_y-=(256-mouse_data2);/y坐标减 else move_y+=mouse_data2;/y坐标加 /* 外部中断1 */ void ReceiveData(void) interrupt 2 led=0; if(mouse_buffer_bit=10) while(mouse_CLK=0);/等待设备拉高

15、时钟线 mouse_buffermouse_buffer_bit+=mouse_SDA;/接收数据 if(mouse_buffer_bit=10) data_analyse;/数据分析及处理 mouse_buffer_bit=0; #endif /*XXX.H文件部分*/ #ifndef LCD1602_4_H #define LCD1602_4_H #include #includeDELAY52.h #define LCD1602_DATA P0 #define CLEARSCREEN LCD1602_write_cmd(0x01) sbit LCD1602_RS=P25; sbit LC

16、D1602_RW=P26; sbit LCD1602_EN=P27; /* void LCD1602_Init(void); /液晶初始化 void LCD1602_write_cmd(uchar command); /写命令 void LCD1602_write_data(uchar temp); /写数据 void LCD1602_set_xy(uchar x, uchar y); /设置坐标 void LCD1602_write_char(uchar x,uchar y,uchar dat); /写一个字符到第x行y列 void LCD1602_write_string(uchar x,

17、uchar y,uchar *s);/写字符串到第x行y列 void LCD1602_Read_BF(void); /读忙信号 void num(uchar x,uchar y,uint n); /在第x行,第y列显示整型数字n /* void LCD1602_Init(void) LCD1602_write_cmd(0x28); LCD1602_write_cmd(0x28); LCD1602_write_cmd(0x28);/设置4位数据传输模式 LCD1602_write_cmd(0x0C); LCD1602_write_cmd(0x80); CLEARSCREEN; void LCD1

18、602_Read_BF(void) LCD1602_RW=1; /RW 1 LCD1602_RS=0; /RS 0 LCD1602_EN=1; /EN 1 Read BF LCD1602_DATA=LCD1602_DATA&0x0F|0xf0; while(LCD1602_DATA&0x80); LCD1602_EN=0; void LCD_en_write(void) /EN端产生一个高电平脉冲,写LCD LCD1602_EN=1; _nop_; LCD1602_EN=0; /* void LCD1602_write_cmd(uchar command) LCD1602_Read_BF; L

19、CD1602_RS=0; /RS 0 LCD1602_RW=0; /RW 0 LCD1602_DATA&=0x0F; LCD1602_DATA=command&0xf0 | LCD1602_DATA&0x0f; LCD_en_write; command=command4; LCD1602_DATA&=0x0F; LCD1602_DATA=command&0xf0 | LCD1602_DATA&0x0f; LCD_en_write; /* void LCD1602_write_data(uchar dat) LCD1602_Read_BF; LCD1602_RS=1; /RS 1 LCD160

20、2_RW=0; /RW 0 LCD1602_DATA &=0x0F; LCD1602_DATA=dat&0xf0 | LCD1602_DATA&0x0f; LCD_en_write; dat=dat4; LCD1602_DATA &=0x0F; LCD1602_DATA=dat&0xf0 | LCD1602_DATA&0x0f; LCD_en_write; /* void LCD1602_set_xy(uchar x,uchar y) uchar address; y&=0x0f; if(!x) address=0x80+y; else address=0xc0+y; LCD1602_writ

21、e_cmd(address); /* void LCD1602_write_char(uchar x,uchar y,uchar dat) LCD1602_set_xy(x,y); LCD1602_write_data(dat); /* void LCD1602_write_string(uchar x,uchar y,uchar *s) LCD1602_set_xy(x,y); while(*s) LCD1602_write_data(*s); s+; void num(uchar x,uchar y,uint n) uchar i,length,a6=0,0,0,0,0,0; uint n

22、x=n; if(n=0)LCD1602_write_char(x,y,0);return; for(i=0;i=1)length+; nx/=10; nx=n; for(;length0;length-) alength-1=nx%10+48; nx/=10; LCD1602_write_string(x,y,a); #endif /*XXX.H文件部分*/ #ifndef DELAY52_H #define DELAY52_H #define uchar unsigned char #define uint unsigned int #include /起始值delayus(1)=27us,间隔9.9us void delay10us(uint t) while(t-); void delayms(uint t) uint i; uchar j; for(i=0;it;i+) for(j=0;j125;j+); #endif 先按上面接口连接,然后即可编译下载,测试然后在修改成自己的代码。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号