day07&8_鼠标动起来

键盘控制器原理

自己去看
鼠标控制也属于键盘控制器的一部分

硬件图

在这里插入图片描述
代码

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

keymouse.h中的宏定义,函数声明,结构体声明

#ifndef __KEYMOUSE_H__
#define __KEYMOUSE_H__

struct MOUSE_DEC
{
    unsigned char MouseStatusBuf[3];//存放鼠标发送过来的三个字节
    int MousePhase;//设置鼠标处于哪个周期
    int nX, nY, nButton;
};



#define PORT_KEYDAT				0x0060 //端口60数据
#define PORT_KEYSTA				0x0064//获取键盘控制器状态
#define PORT_KEYCMD				0x0064//端口64 命令
#define KEYSTA_SEND_NOTREADY	0x02//键盘控制器没有准备好
//向端口64发送此命令 代表要向端口60发送数据了
#define KEYCMD_WRITE_MODE		0x60
//开启鼠标 键盘中断 并且使能
#define KBC_MODE				0x47
//鼠标应答
#define MOUSE_ACK               0xfa

//要使能鼠标
#define KEYCMD_SENDTO_MOUSE		0xd4
#define MOUSECMD_ENABLE			0xf4

void WaitKeyBoardCtrlReady(void);//等待键盘控制器准备完毕
void InitKeyBoard(void);//初始化 键盘控制器
void EnableMouse(struct MOUSE_DEC * pMouse);//激活鼠标

int MouseDecode(struct MOUSE_DEC * pMouse, unsigned char ucData);//把数据放入结构体




#endif

初始化键盘控制器

void WaitKeyBoardCtrlReady(void)//等待键盘控制器准备完毕
{
    while(1)
    {
        if(0 == (io_in8(PORT_KEYSTA) & KEYSTA_SEND_NOTREADY) )
        {
            break;
        }
    }

    return;
}
void InitKeyBoard(void)//初始化 键盘控制器
{
    WaitKeyBoardCtrlReady();
    //向0x64端口发送命令 下一个送入端口0x60的数据 要写入控制寄存器
    io_out8(PORT_KEYCMD, KEYCMD_WRITE_MODE);
    WaitKeyBoardCtrlReady();
    //设置控制寄存器的模式
    io_out8(PORT_KEYDAT, KBC_MODE);
    return;
}

初始化鼠标

void EnableMouse(struct MOUSE_DEC * pMouse)//激活鼠标
{
    WaitKeyBoardCtrlReady();

    io_out8(PORT_KEYCMD, KEYCMD_SENDTO_MOUSE);
    WaitKeyBoardCtrlReady();

    io_out8(PORT_KEYDAT, MOUSECMD_ENABLE);
    pMouse->MousePhase = 0;

    return;
}

初始化键盘,鼠标的缓冲区

	struct  FIFO g_FifoKeyBoardBuf;
	struct  FIFO g_FifoMouseBuf;

	unsigned char KeyBoardBuffer[32];//键盘的缓冲区
	unsigned char MouseBuffer[256];//鼠标的缓冲区
	
	InitFifo(&g_FifoKeyBoardBuf, 32, KeyBoardBuffer);
	InitFifo(&g_FifoMouseBuf, 256, MouseBuffer);

fifo.h中的内容

#ifndef __FIFO_H__
#define __FIFO_H__

#define FLAGES_OVERRUN 0x0001 //记录是否缓冲区溢出
#define BUFFER_VOERFLOW -1
#define BUFFER_EMPTY -2

//记录缓冲区的结构体
struct  FIFO
{
    unsigned char *pAdd;//缓冲区的起始地址

    int nHead;//队列头
    int nTail;//队列尾
    int nFree;//空闲的数量
    int nSize;//缓冲区总共大小
    int nFlag;//记录标志
};

//初始化缓冲区
void InitFifo(struct FIFO *pTemp, int Size, unsigned char *pBuf);
//向缓冲区写入数据
int FifoSaveData(struct FIFO *pTemp, unsigned char Data);
//从缓冲区中读出数据
int FifoReadData(struct FIFO *pTemp);
//获取缓冲区的状态
int FifoStatus(struct FIFO *pTemp);



#endif

fifo.c中的内容

void InitFifo(struct FIFO *pTemp, int Size, unsigned char *pBuf)
{
    pTemp->pAdd = pBuf;
    pTemp->nSize = Size;
    pTemp->nFlag = 0;
    pTemp->nFree = Size;
    pTemp->nHead = 0;
    pTemp->nTail = 0;

    return ;
}
int FifoSaveData(struct FIFO *pTemp, unsigned char Data)
{
    if(0 == pTemp->nFree)//如果没有空闲区
    {
        pTemp->nFlag |= FLAGES_OVERRUN;

        return BUFFER_VOERFLOW;
    }

    //有空闲区 向尾部写入数据
    pTemp->pAdd[pTemp->nTail] = Data;
    pTemp->nTail++;

    if(pTemp->nSize == pTemp->nTail)
    {
        pTemp->nTail = 0;
    }

    pTemp->nFree--;//空闲区减1

    return 0;
}
int  FifoReadData(struct FIFO *pTemp)
{
    int nData;

    //如果缓冲区是空的
    if(pTemp->nFree == pTemp->nSize)
    {
        return BUFFER_EMPTY;
    }

    //取出数据
    nData = pTemp->pAdd[pTemp->nHead];
    pTemp->nHead++;

    if(pTemp->nSize == pTemp->nHead)
    {
        pTemp->nHead = 0;
    }

    pTemp->nFree++;

    return nData;
}
int FifoStatus(struct FIFO *pTemp)//缓冲区内的字符个数
{
    return (pTemp->nSize) - (pTemp->nFree);
}

键盘和鼠标的中断处理函数

void IntHandler21(int *pEsp);//键盘是IRQ1
void IntHandler2C(int *pEsp);//鼠标是IRQ12
void IntHandler21(int *pEsp)
{
	unsigned char ucData;
	
	io_out8(PIC0_OCW2, 0x61);//通知PIC"IRQ-01已经处理完毕 可以继续中断"
	ucData = io_in8(PORT_KEYBOARD_DATA);

	//sprintf(szBuf, "%02x",ucData);

	FifoSaveData(&g_FifoKeyBoardBuf,ucData);


	return	;
}

void IntHandler2C(int *pEsp)
{
	unsigned char ucData;

	//通知PIC1 IRQ-12
	io_out8(PIC1_OCW2, 0x64);
	//通知PIC0 IRQ-02
	io_out8(PIC0_OCW2, 0x62);

	//从鼠标接受一个数据
	ucData = io_in8(PORT_KEYDAT);

	FifoSaveData(&g_FifoMouseBuf, ucData);

	return;
}

获取鼠标状态

int MouseDecode(struct MOUSE_DEC * pMouse, unsigned char ucData)
{
    if(0 == pMouse->MousePhase)
    {
        if(MOUSE_ACK == ucData)
        {
            pMouse->MousePhase = 1;
            return 0;
        }
    }
    else if(1 == pMouse->MousePhase)
    {
        if(0x08 == (ucData & 0xc8))//即X Y没有溢出
        {
            pMouse->MouseStatusBuf[0] = ucData;
            pMouse->MousePhase = 2;
        }

        return 0;
    }
    else if(2 == pMouse->MousePhase)
    {
        pMouse->MouseStatusBuf[1] = ucData;
        pMouse->MousePhase = 3;
        return 0;
    }
    else if(3 == pMouse->MousePhase)
    {
        pMouse->MouseStatusBuf[2] = ucData;
        pMouse->MousePhase = 1;
        
        pMouse->nButton = pMouse->MouseStatusBuf[0] & 0x07;
        //判断哪个键被按下了
        pMouse->nX = pMouse->MouseStatusBuf[1];
        pMouse->nY = pMouse->MouseStatusBuf[2];

        if(0 != (pMouse->MouseStatusBuf[0] & 0x10) )
        //即X方向发生了移动
        {
            pMouse->nX |= 0xffffff00;
        } 

        if(0 != (pMouse->MouseStatusBuf[0] & 0x20) )
        //即Y方向发生了移动
        {
            pMouse->nY |= 0xffffff00;
        } 

        pMouse->nY = -pMouse->nY;

        return 1;
    }

}

总结

①首先要先开启键盘鼠标的中断
②初始化各自的缓冲区
③初始化键盘控制器,激活鼠标
④键盘,鼠标中断处理函数每次从 端口接受到一个字节放入到各自的缓冲区中
⑤调用鼠标解析函数来进行处理每次发来的三个字节,更改坐标,描绘鼠标

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值