mfc编写鼠标键盘_计算机自制操作系统(十九):中断---鼠标驱动

本文详细介绍了在自定义操作系统中编写鼠标键盘驱动的过程,包括硬件设置、中断服务程序注册、鼠标数据接收。重点讲解了鼠标数据的异步通信方式,以及如何处理鼠标点击和坐标位移。同时,提到了关键数据结构如BOOTINFO、FIFO8缓冲区的使用,以及相关源文件的作用。
摘要由CSDN通过智能技术生成

46b43db7b038b9a5a8ce11d66b5993c6.png

一、准备工作

(一)硬件设置

计算机中鼠标的中断硬件组成,在前面的章节已经做了介绍:

903350bd6ead5c2f336d56c53eb03d07.png

从图中可以明显看到,鼠标是接在从片的4号端口上的,而从片又是接在主片的2号端口上的,因此我们第一步就是需要打开这两个端口的中断:

        io_out8(PIC0_IMR, 0xf9); /* 开启键盘和鼠标中断主芯片设置:(11111001) */
	io_out8(PIC1_IMR, 0xef); /* 从芯片设置:(11101111) */

之前,我们对键盘和鼠标中断号已经做了定义,分别是0X21和0X2C。那我们鼠标驱动的主要任务其实就是编写0X2C号中断的中断服务程序。另外,我们需要将中断号0X2C的中断服务程序注册到IDT表中,这个方法和键盘中断没有差异。

鼠标电路硬件上其实是从属于键盘电路的,因此我们还需要从硬件上做两个事情:

1.启用鼠标电路,程序中用init_keyboard()函数实现。

2.启动鼠标设备,程序中用 enable_mouse(&mdec)函数实现。

(二)鼠标数据接收

鼠标与CPU数据交互上和键盘不相同,因为鼠标的数据量远远大于键盘,键盘无非就是一个按键和释放,而鼠标有5种数据:点击左键、点击右键、滑动中间键、X坐标位移和Y坐标位移。所以鼠标和CPU是采用一种异步通信的方式:一次鼠标操作分3次握手完成传递,每次传递一个字节,第1个字节表示的是鼠标点击数据、第2个字节和第3个字节表示的是X坐标位移和Y坐标位移。那么第1个字节就很关键,它的定义是最低3位分别表示点击左中右键。我们需要在中断服务程序里用逻辑来区分这3个阶段,以保证能收到的数据不乱序。方法一般是:首先判断鼠标送来的数据知否在正常范围内来判断是否是第一个字节,因为超出合理范围就肯定不是第一字节。具体方法这个可以看书上的教程:

eb410982a7c0239e4b220ccaba0a6b4b.png

711896c6931019c0456575244413adfb.png

二、运行效果

fd23d5ad8b75e6dd42f2cb66f73bf696.png
桌面实时显示键盘输入和鼠标位置坐标

三、程序代码

1.Main.c

void Main(void)
{
 
	sysinit();     /*操作系统运行准备*/
  
        intservice();  /*外设中断服务准备(键盘鼠标)*/

        desktop();     /*桌面显示*/
        

	while(1) 
        {
	;
	}
}

2.Desktop.c

关键点:

(1)struct BOOTINFO *binfo:这个数据结构是整个操作系统的基础信息,其作用就是从内存固定物理地址0x7000处开始读出分辨率、键盘按键状态、显卡内存地址等在前面汇编程序部分写进去的基础信息。

#define BOOTBASE                0x7000
struct BOOTINFO {
	char cyls, leds, vmode, reserve;
	short scrnx, scrny;
	char *vram;
        int  asmlen;
};

(2)extern struct FIFO8 keyfifo; extern struct FIFO8 mousefifo; keyfifo和mousefifo分别为32字节的键盘数据输入缓冲区和128字节的鼠标数据输入缓冲区。必须用关键词extern来定义变量,是因为这两个缓冲区是在Keryboard.c和Mouse.c中定义的,那么这里引用的作用显然是只管从缓冲区读出数据!FIFO8实际上只是一个缓冲区的信息描述符,它用来指向真正的数据缓冲区并做读写控制,真正的数据缓冲区是存放在char keybuf[32],mousebuf[128]这两个数组里面的。

(3)专门定义了一个数据结构struct MOUSE_DEC mdec,用来解析和存储鼠标每次送来的3个字节数据。

#include "Jiangos.h"

#include <stdio.h>


void desktop(void)
{
 
        struct BOOTINFO *binfo = (struct BOOTINFO *) BOOTBASE;
	init_palette();
	init_screen(binfo->vram, binfo->scrnx, binfo->scrny);
        static char c=7;	

        /*---显示字符串---*/
	
        putfont_Jiang(binfo->vram,binfo->scrnx, 10,10, COL8_FFFFFF);
        putfonts8_asc(binfo->vram, binfo->scrnx,10,40, COL8_FFFFFF, "Jiang OS 13572468");
        line(binfo->vram,binfo->scrnx,60,c); 
        

        /*---显示变量---*/	
        char s[40];                            
        sprintf(s, "VRAMX=%d", binfo->scrnx);
	putfonts8_asc(binfo->vram, binfo->scrnx, 16, 64, COL8_FFFFFF, s);
        sprintf(s, "VRAMY=%d", binfo->scrny);
	putfonts8_asc(binfo->vram, binfo->scrnx, 100, 64, COL8_FFFFFF, s);
        sprintf(s, "VRAMAddr=0X %X", binfo->vram);
	putfonts8_asc(binfo->vram, binfo->scrnx, 184, 64, COL
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值