📄 use_photoelectricity_mouse_driver.c
字号:
/*****************************************************************
* 函数库名称:AVR硬件资源配置函数源文件 *
* 版本: v0.01 *
* 作者: I ROBOT *
* 创建日期: Copyright (C) 2008年10月14日 *
*----------------------------------------------------------------*
* [支持库] *
* 支持库名称:Hardware_Apply_Init.h(AVR硬件资源配置头文件) *
* 支持库版本:v0.01 *
* 支持库说明:与本文件相应的函数声明 *
*----------------------------------------------------------------*
* [版本更新] *
* 更新: I ROBOT *
* 更新日期: *
* 版本: *
*----------------------------------------------------------------*
* [版本历史] *
* v0.01 创建版本,配置AVR硬件资源 *
*----------------------------------------------------------------*
* [使用说明] *
* 1.配置使用的AVR硬件资源 *
*****************************************************************/
/********************
* 头 文 件 配 置 区 *
********************/
# include "USE_Photoelectricity_Mouse_Driver.h"
# include "USE_USART_Driver.h"
/********************
* 系 统 宏 定 义 *
********************/
/*------------------*
* 常 数 宏 定 义 *
*------------------*/
/*------------------*
* 动 作 宏 定 义 *
*------------------*/
/********************
* 模块结构体定义区 *
********************/
/********************
* 函 数 声 明 区 *
********************/
/*---------------------------------------------*
* 公 有 函 数 声 明 区 *
*---------------------------------------------*/
void Mouse_Hardware_Configure(void);
static void MCU_Register_Configure(void);
static void MCU_Port_Configure(void);
static UINT16 Group_Frame(UINT8 chData);
static void Translate_Frame_To_Mouse(UINT8 chData);
static UINT8 Reiceve_Mouse_Frame(void);
void Mouse_Init(void);
/*---------------------------------------------*
* 私 有 函 数 声 明 区 *
*---------------------------------------------*/
//TODO:在这里添加只使用端口配置的函数声明
# ifdef USE_ONLY_PIN_CONFIGURE
struct Mouse_Struct *Mouse_Data_Process(void);
# endif
//TODO:在这里添加使用端口和外中断配置的函数声明
# ifdef USE_PIN_AND_EINT_CONFIGURE
static void INT0_ISR_Mouse_Frame_Receive(void);
# endif
//TODO:在这里添加使用外中断和串口配置的函数声明
# ifdef USE_EINT_AND_USART_CONFIGURE
# endif
/********************
* 模块函数声明区 *
********************/
/********************
* 模块变量声明区 *
********************/
/********************
* 全局变量声明区 *
********************/
//TODO:在这里添加MOUSE接收缓存区
static BOOL g_s_Mouse_Init = FALSE;
/******************************************************************
* 函 数 定 义 区 *
******************************************************************/
/*---------------------------------------------*
* 公 有 函 数 定 义 区 *
*---------------------------------------------*/
/****************************************
* 函数说明: 鼠标硬件配置函数 *
* 输入 :无 *
* 输出 :无 *
* 调用函数: MCU_Port_Configure() *
* MCU_Register_Configure() *
* Mouse_Init() *
****************************************/
void Mouse_Hardware_Configure(void)
{
MCU_Port_Configure();
Mouse_Init();
}
/****************************************
* 函数说明: MCU寄存器配置函数 *
* 输入 :无 *
* 输出 :无 *
* 调用函数: 无 *
****************************************/
static void MCU_Register_Configure(void)
{
CLI(); //disable all interrupts
MCUCR = 0x02;
GICR = 0x40;
TIMSK = 0x00; //timer interrupt sources
SEI();
//使用外中断0
}
/****************************************
* 函数说明: MCU端口配置函数 *
* 输入 :无 *
* 输出 :无 *
* 调用函数: 无 *
****************************************/
static void MCU_Port_Configure(void)
{
DDRB |= BIT(PB0)|BIT(PB1);
PORTB |= BIT(PB0)|BIT(PB1);
DDRB |= BIT(PB2);
PORTB |= BIT(PB2);
}
/****************************************
* 函数说明: 数据帧打包函数 *
* 输入 :传输数据 *
* 输出 :数据包 *
* 调用函数: 无 *
****************************************/
static UINT16 Group_Frame(UINT8 chData)
{
//主机到鼠标的通信中,START是由主机单独发送的,所以
//数据包由|DATA0-DATA7|Parity|StopBit|ACK|组成的11位
//与鼠标到主机的通信的数据包格式略有不同
UINT8 chCounter = 0;
UINT16 chParity = ODD_PARITY;
UINT16 chStopBit = 1;
UINT16 chACK = 0;
UINT8 chData_Temp = chData;
//奇校验异或计算
for (chCounter = 0;chCounter < 8;chCounter++)
{
chParity ^= (chData_Temp&(0x01));
chData_Temp >>= 1;
}
chParity <<= 8; //校验位
chStopBit <<= 9;//停止位
chACK <<= 10; //应答位
return ((UINT16)(chACK|chStopBit|chParity|chData));
}
/****************************************
* 函数说明: 传输数据包给鼠标函数 *
* 输入 :传输数据 *
* 输出 :无 *
* 调用函数: Group_Frame() *
****************************************/
static void Translate_Frame_To_Mouse(UINT8 chData)
{
UINT16 wFrame = Group_Frame(chData); //数据打包成帧
CLK_FROM_AVR;
DATA_FROM_AVR;
MOUSE_CLK_LOW;
MOUSE_DATA_LOW; //设置数据流方向
{
UINT8 chCounter = 0;
for (chCounter = 0;chCounter < 100;chCounter++)
{
US_DELAY;
}
} //设置CLK = 0,DATA = 0,延时100US,使鼠标检测到
//主机到鼠标的通信请求并表示主机到MOUSE
//的起始位START
MOUSE_CLK_HIGH; //鼠标上升沿读取数据
CLK_FROM_MOUSE; //设置数据流方向
{ //发送数据包
UINT8 chCounter = 0;
for (chCounter = 0;chCounter < FRAME_LENGTH_11;chCounter++)
{
WAIT_MOUSE_CLK_LOW; //在CLK下降沿主机设置数据
if (wFrame&BIT(chCounter))
{
MOUSE_DATA_HIGH;
}
else
{
MOUSE_DATA_LOW;
}
WAIT_MOUSE_CLK_HIGH; //鼠标在CLK上升沿读取数据
}
}
}
/****************************************
* 函数说明: 接收鼠标数据包函数 *
* 输入 :无 *
* 输出 :接收的鼠标数据 *
* 调用函数: 无 *
****************************************/
static UINT8 Reiceve_Mouse_Frame(void)
{
UINT8 chCounter = 0;
UINT8 chMouse_Data = 0;
DATA_FROM_MOUSE; //设置数据流方向
for (chCounter = 0;chCounter < FRAME_LENGTH_11;chCounter++)
{
WAIT_MOUSE_CLK_LOW;
//移位读数
if (chCounter >= MOUSE_DA0_BIT && chCounter <= MOUSE_DA7_BIT)
{
chMouse_Data >>= 1;
chMouse_Data |= ((AVR_READ_MOUSE_DATA)? 0x80:0); //LSB先进
}
WAIT_MOUSE_CLK_HIGH;
}
return chMouse_Data;
}
/****************************************
* 函数说明: 鼠标初始化函数 *
* 输入 :无 *
* 输出 :无 *
* 调用函数: Translate_Frame_To_Mouse() *
* Reiceve_Mouse_Frame() *
****************************************/
void Mouse_Init(void)
{
UINT8 chMouse_ACK_1 = 0;
UINT8 chMouse_ACK_2 = 0;
UINT8 chMouse_ACK_3 = 0;
Translate_Frame_To_Mouse(MOUSE_RESET); //Mouse复位
chMouse_ACK_1 = Reiceve_Mouse_Frame(); //接收第一个ACK字节
chMouse_ACK_2 = Reiceve_Mouse_Frame(); //接收第二个ACK字节
chMouse_ACK_3 = Reiceve_Mouse_Frame(); //接收第三个ACK字节
if ((chMouse_ACK_1 == MOUSE_ACK_BYTE1)
|| (chMouse_ACK_2 == MOUSE_ACK_BYTE2)
|| (chMouse_ACK_3 == MOUSE_ACK_BYTE3))
{
UINT8 chMouse_Live_ACK = 0;
Translate_Frame_To_Mouse(MOUSE_LIVE); //鼠标激活模式
chMouse_Live_ACK = Reiceve_Mouse_Frame();
g_s_Mouse_Init = TRUE; //初始化完毕解锁
}
}
/*---------------------------------------------*
* 私 有 函 数 定 义 区 *
*---------------------------------------------*/
//TODO:在这里添加只使用端口配置的代码
# ifdef USE_ONLY_PIN_CONFIGURE
/****************************************
* 函数说明: 鼠标数据预处理函数 *
* 输入 :无 *
* 输出 :无 *
* 调用函数: Reiceve_Mouse_Frame() *
****************************************/
struct Mouse_Struct *Mouse_Data_Process(void)
{
if (g_s_Mouse_Init)
{
static UINT8 chMouse_Byte_Buffer[MOUSE_DATA_SIZE] = {0};
static struct Mouse_Struct Mouse = {0,0,FALSE,FALSE};
{
UINT8 chCounter = 0;
for (chCounter = 0;chCounter < MOUSE_DATA_SIZE;chCounter++)
{
chMouse_Byte_Buffer[chCounter] = Reiceve_Mouse_Frame();
}//接收一次鼠标动作的3个字节的数据
if (chMouse_Byte_Buffer[0]&BIT(MOUSE_X_SIGN))//计算X的偏移量
{
Mouse.x = -((INT16)chMouse_Byte_Buffer[1]);
Mouse.x = -(Mouse.x+MOUSE_DATA_MAX)%MOUSE_DATA_MAX;
}
else
{
Mouse.x = ((INT16)chMouse_Byte_Buffer[1]);
Mouse.x = (Mouse.x+MOUSE_DATA_MAX)%MOUSE_DATA_MAX;
}
if (chMouse_Byte_Buffer[0]&BIT(MOUSE_Y_SIGN))//计算Y的偏移量
{
Mouse.y = -((INT16)chMouse_Byte_Buffer[2]);
Mouse.y = -(Mouse.y+MOUSE_DATA_MAX)%MOUSE_DATA_MAX;
}
else
{
Mouse.y = ((INT16)chMouse_Byte_Buffer[2]);
Mouse.y = (Mouse.y+MOUSE_DATA_MAX)%MOUSE_DATA_MAX;
}
}
//鼠标数据的容错处理
Mouse.x = ((ABS(Mouse.x) > ERROR_DATA)? 0:Mouse.x);
Mouse.y = ((ABS(Mouse.y) > ERROR_DATA)? 0:Mouse.y);
//更新左右按键情况
Mouse.b_Left_Key_Down = ((chMouse_Byte_Buffer[0]&
BIT(MOUSE_LEFT_KEY))? TRUE:FALSE);
Mouse.b_Right_Key_Down = ((chMouse_Byte_Buffer[0]&
BIT(MOUSE_RIGHT_KEY))? TRUE:FALSE);
return &Mouse;
}
}
# endif
//TODO:在这里添加使用端口和外中断配置的代码
# ifdef USE_PIN_AND_EINT_CONFIGURE
//TODO:在这里配置外中断向量
#pragma interrupt_handler INT0_ISR_Mouse_Frame_Receive:iv_INT0
/*
static void INT0_ISR_Mouse_Frame_Receive(void)//附加考虑校验抛误帧的情况
{
static UINT8 chBit_Counter = 0;
static UINT8 chMouse_Data = 0;
static UINT8 chMouse_Byte[3] = {0}; //鼠标3个字节数据
if (!g_s_Mouse_Init)
{
return;
}
DATA_FROM_MOUSE; //设置数据流方向
if (chBit_Counter >= 1 && chBit_Counter <= 8) //移位获取数据
{
chMouse_Data >>= 1;
chMouse_Data |= ((AVR_READ_MOUSE_DATA)?0X80:0);
}
chBit_Counter++;
if (chBit_Counter == FRAME_LENGTH_11) //收完一帧
{
static UINT8 chByte_Counter = 0; //计数清零
chBit_Counter = 0;
chMouse_Byte[chByte_Counter++] = chMouse_Data;
chMouse_Data = 0;
if (chByte_Counter == MOUSE_DATA_SIZE) //收完三帧
{
chByte_Counter = 0; //计算鼠标位置(包含符号)
if (chMouse_Byte[0]&BIT(MOUSE_X_SIGN))
{
Mouse.x -= (INT16)(chMouse_Byte[1]);
}
else
{
Mouse.x += (INT16)(chMouse_Byte[1]);
}
if (chMouse_Byte[0]&BIT(MOUSE_Y_SIGN))
{
Mouse.y -= (INT16)(chMouse_Byte[2]);
}
else
{
Mouse.y += (INT16)(chMouse_Byte[2]);
}
/*
//调试部分
{
CHAR Str1[20] = {' '};
CHAR Str2[20] = {' '};
itoa(Str1,Mouse.x,10);
itoa(Str2,Mouse.y,10);
Str1[19] = ' ';
Str2[19] = '\n';
USART_Translate_Bytes(Str1,20);
USART_Translate_Bytes(Str2,20);
}
}
}
}
*/
# endif
//TODO:在这里添加使用外中断和串口配置的代码
# ifdef USE_EINT_AND_USART_CONFIGURE
# endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -