|
怎么調(diào)試交互,自己頂一下,希望有人指點。貼出來我改過的代碼。
/************************************************************/
/*文件名稱:單片機模擬PS/2鼠標(biāo)程序 */
/*作 者:蔣毅 */
/*版 本:2008-6 */
/*說 明: */
/*修改記錄: */
/************************************************************/
#include <STC12C5410AD.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
/******************常用命令及參數(shù)定義************************/
//EEPROM
#define isp_read 1
#define isp_program 2
#define isp_erase 3
#define isp_con 0x80
#define ADDRESSH 0X10
#define ADDRESSL 0X00
//HOST-->MOUSE
#define DISABLE_SEND 0XF5 //disable data reprorting
#define ENABLE_SEND 0XF4 //enable data reprorting
#define RESET 0XFF //reset
#define GETID 0XF2 //get device id
#define SATATUS_REQUEST 0XE9 //datatus request
#define HMRESEND 0XFE //host ask mouse resend
#define ERROR 0X55 //receive eeror
//MOUSE-->HOST
#define ANSWERER 0XFA //answerer
#define ID 0X00 //device id
#define BAT 0XAA //bat
#define RESEND 0XFE //resend
#define SATATUS3 0X02 //satatus3
#define SATATUS4 0X64 //satatus4
#define LBUTTONDOWN 0X09 //left button down
#define LBUTTONUP 0X08 //left button up
#define DATABAG 0x08;
/***********************引腳定義*****************************/
sbit mouse_clk=P3^3;
sbit mouse_data=P3^5;
sbit ms1=P1^0;
//sbit ms2=P1^6;
//sbit ctls=P3^4;
/***********************全局變量*****************************/
uchar flag_send=0;//允許發(fā)送標(biāo)志位
uchar buffer=0;//命令緩沖單元
/***********************函數(shù)聲明*****************************/
void delay10us(void) //誤差 0us
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=1;a>0;a--);
}
void delay5us(void) //誤差 0us
{
_nop_(); //if Keil,require use intrins.h
}
void delay20us(void) //誤差 0us
{
unsigned char a,b;
for(b=3;b>0;b--)
for(a=1;a>0;a--);
}
void delay50us(void) //誤差 0us
{
unsigned char a,b;
for(b=9;b>0;b--)
for(a=1;a>0;a--);
}
//*********************讀EEPROM一字節(jié)************************/
uchar read_byte_eeprom(uchar addth,addtl)
{
uchar temp_data;
ISP_ADDRH=addth;
ISP_ADDRL=addtl;
EA=0;
ISP_CONTR=isp_con;
ISP_CMD=isp_read;
ISP_TRIG=0x46;
ISP_TRIG=0xB9;
temp_data=ISP_DATA;
EA=1;
return temp_data;
}
//*********************寫EEPROM一字節(jié)***********************/
void program_byte_eeprom(uchar temp_data, addth,addtl)
{
ISP_DATA=temp_data;
ISP_ADDRH=addth;
ISP_ADDRL=addtl;
EA=0;
ISP_CONTR=isp_con;
ISP_CMD=isp_program;
ISP_TRIG=0x46;
ISP_TRIG=0xB9;
EA=1;
}
//********************擦除EEPROM一扇區(qū)子函數(shù)*****************/
void erase_sector_eeprom(uchar addth,addtl)
{
ISP_ADDRH=addth;
ISP_ADDRL=addtl;
EA=0;
ISP_CONTR=isp_con;
ISP_CMD=isp_erase;
ISP_TRIG=0x46;
ISP_TRIG=0xB9;
EA=1;
}
/*******************ms級延時子函數(shù)***************************/
void delay50ms(void) //誤差 0us
{
unsigned char a,b;
for(b=165;b>0;b--)
for(a=150;a>0;a--);
}
void delay20ms(void) //誤差 0us
{
unsigned char a,b;
for(b=215;b>0;b--)
for(a=45;a>0;a--);
}
void delay500ms(void) //誤差 0us
{
unsigned char a,b,c;
for(c=205;c>0;c--)
for(b=116;b>0;b--)
for(a=9;a>0;a--);
}
/****************ps/2發(fā)送單個位到PC函數(shù)**********************/
void send_bit(bit senbit)
{
mouse_data=senbit; //設(shè)置/復(fù)位數(shù)據(jù)
delay20us(); //延遲20us
mouse_clk=0; //將時鐘拉低
delay20us();
delay20us(); //延遲40us
mouse_clk=1; //釋放時鐘
}
/***************ps/2發(fā)送單個字節(jié)到PC函數(shù)*********************/
void send_byte(uchar tmp)
{
uchar i;
uchar temp,check;
temp=0;
check=0;
while(!mouse_clk);//等待CLK為高
delay50us();//延時50us
if(mouse_clk)//判斷CLK是否為高,是:發(fā)送,否:放棄,轉(zhuǎn)到接收程序
{
delay20us();//延時20us
for(i=0;i<11;i++)
{
delay20us();//延時20us
if(i==0) send_bit(0);//發(fā)送起始位0
else
{
if(i>=1&&i<9)//發(fā)送數(shù)據(jù)位
{
temp=tmp;
temp>>=(i-1);
temp=temp&0x01;
if(temp==0x01){send_bit(1);check++;}
else send_bit(0);
}
else
{
if(i==9)//發(fā)送校驗位
{
check=check&0x01;
if(check==0x01) send_bit(0);//奇校驗
else send_bit(1);
}
else send_bit(1);//發(fā)送停止位
}
}
if(mouse_clk==1) continue;//判斷時鐘是否被主機拉低,是-放棄發(fā)送
else break;
}
delay20us();
delay10us();//延時30us
}
}
/********************ps/2接收PC單個位函數(shù)********************/
bit receive_bit()
{
bit tbit;
tbit=0;
delay20us(); //延遲20us
mouse_clk=0; //把時鐘線拉低
delay20us();
delay20us(); //延遲40us
mouse_clk=1; //釋放時鐘
delay20us(); //延遲20us
tbit=mouse_data; //讀取數(shù)據(jù)
return tbit; //返回數(shù)據(jù)
}
/**********************ps/2輸出應(yīng)答位函數(shù)********************/
void send_answerer()
{
delay10us();
delay5us();//延遲15us
mouse_data=0;//把數(shù)據(jù)線拉低
delay5us(); //延遲5us
mouse_clk=0; //把時鐘線拉低
delay20us();
delay20us();//延遲40us
mouse_clk=1; //釋放時鐘線
delay5us(); //延遲5us
mouse_data=1;//釋放數(shù)據(jù)線
}
/*******************ps/2接收PC單個字節(jié)函數(shù)*******************/
uchar receive_byte()
{
uchar i,temp,rdata,check;
bit tmp,check_bit;
tmp=0;
check_bit=0;
temp=0;
rdata=0;
check=0;
while(!mouse_clk);//等待時鐘為高
if(!mouse_data)//判斷數(shù)據(jù)線為低,是-接收,否-有錯誤發(fā)生,放棄
{
for(i=0;i<10;i++)//接收8個數(shù)據(jù)位,校驗位,停止位
{
if(i>=0&&i<8)//讀入8個數(shù)據(jù)位
{
tmp=receive_bit();
if(tmp==1) check++;
temp=(uchar)tmp;
temp<<=i;
rdata=rdata|temp;
}
else if(i==8)//讀入校驗位
check_bit=receive_bit();
else //讀入停止位
tmp=receive_bit();
if(mouse_clk==1) continue;//判斷時鐘是否被主機拉低,是-放棄接收
else return 0x55;
}
/*判斷停止位是否為1,否,產(chǎn)生一錯誤標(biāo)志*/
if(!mouse_data) //否
{
while(!mouse_data);
return 0x55;
}
else //停止位為1
{
send_answerer();//輸出應(yīng)答位
check=(check+(uchar)check_bit)&0x01;
if(check==0)//檢查校驗位
return 0x55;//校驗錯誤
else return rdata;//返回收到的命令
}
}
else return 0x55;
}
/***********************鍵盤掃描函數(shù)*************************/
void keyscan()
{
// uchar i;
if(flag_send)//判斷是否允許數(shù)據(jù)報告
{
if(ms1==0)//判斷是否有鍵按下
{
delay20ms();//延時消抖
if(ms1==0)
{
delay50ms();//延時50ms
send_byte(LBUTTONDOWN);
send_byte(ID);// 發(fā)送位移按鍵數(shù)據(jù)包
send_byte(ID);
}
}
else
{
delay20ms();//延時消抖
if(ms1==1)
{
delay50ms();//延時50ms
send_byte(LBUTTONUP);
send_byte(ID);// 發(fā)送位移按鍵數(shù)據(jù)包
send_byte(ID);
}
}
}
}
/***********************處理主機命令函數(shù)*********************/
void manage(uchar ljmp)
{
switch(ljmp)
{
case RESET: //主機通知MOUSE復(fù)位
send_byte(ANSWERER);
send_byte(BAT);
send_byte(ID);
buffer=ID;
break;
case GETID: //主機通知MOUSE獲得ID
send_byte(ANSWERER);
send_byte(ID);
buffer=ID;
break;
case ENABLE_SEND : //使能數(shù)據(jù)報告
send_byte(ANSWERER);
buffer=ANSWERER;
flag_send=1;
erase_sector_eeprom(ADDRESSH,ADDRESSL);
program_byte_eeprom(0X01,ADDRESSH,ADDRESSL);
break;
case DISABLE_SEND :
send_byte(ANSWERER);//禁止數(shù)據(jù)報告
buffer=ANSWERER;
flag_send=0;
erase_sector_eeprom(ADDRESSH,ADDRESSL);
break;
case SATATUS_REQUEST://主機通知MOUSE告訴狀態(tài)信息
send_byte(ANSWERER);
send_byte(ID);
send_byte(SATATUS3);
send_byte(SATATUS4);
buffer=SATATUS4;
break;
case ERROR: //MOUSE接收錯誤,通知主機重發(fā)
send_byte(RESEND);
buffer=RESEND;
break;
default: //其它命令,都用0XFA回應(yīng)
send_byte(ANSWERER);
buffer=ANSWERER;
break;
}
}
/*************************主函數(shù)*****************************/
void main()
{
uchar order;
delay500ms();//延時500ms
send_byte(BAT);
send_byte(ID);
flag_send=read_byte_eeprom(ADDRESSH,ADDRESSL);
WDT_CONTR=0X3E;//看門狗初始化
while(1)
{
keyscan();
if(!mouse_data)
{
order=receive_byte();
manage(order);
}
WDT_CONTR=0X3E;//喂狗
}
}
|
|