这是我写的单片机发送数据让电脑显示程序,是通过PS2来通信的
这是我写的程序,我想显示一个a字,我先发a的通码给电脑,接着发0XFF和a的断码给电脑,为什么电脑不显示a,还有我一动一下鼠标就报警!请问为什么,是不是我的程序不对,请各位指教#include <avr/io.h>
#include <avr/delay.h>
#include <avr/signal.h>
#include <stdio.h>
unsigned char del_1,key_data,key_down;
//本程序想在电脑上显示a字符,发送流程是先发送A的通码,再发0XFF,接着发A的断码,请问我这样做对吗?PB0接CLKPB7接DATA
int main(void)
{
DDRB=0X00;
DDRC=0X00; //PCIN
PORTC=0XFF;
while(1)
{
while(1)
{
recheck:
DDRB=0X00;
while((PINB&0X01)!=0X00); //判断CLK是否为LOW
_delay_us(50);
if((PINB&0X01)!=0X01)//判断CLK是否为HIGH
gotorecheck;
while((PINB&0X80)!=0X80) gotorecheck; //判断DATA是否为HIGH
_delay_us(20); //0
DDRB=0X81;
PORTB&=~_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20);
DDRB=0X81;
PORTB&=~_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20);
DDRB=0X81;
PORTB&=~_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20);
DDRB=0X81;
PORTB&=~_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20); //1
DDRB=0X81;
PORTB|=_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20); //1
DDRB=0X81;
PORTB|=_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20); //1
DDRB=0X81;
PORTB|=_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20); //1
DDRB=0X81;
PORTB|=_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;//0
_delay_us(20);
DDRB=0X81;
PORTB&=~_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20); //1
DDRB=0X81;
PORTB|=_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20); //1
DDRB=0X81;
PORTB|=_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
_delay_ms(50);
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20); //1
DDRB=0X81;
PORTB|=_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20); //1
DDRB=0X81;
PORTB|=_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20); //1
DDRB=0X81;
PORTB|=_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20); //1
DDRB=0X81;
PORTB|=_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck; //判断DATA是否为HIGH
_delay_us(20); //0
DDRB=0X81;
PORTB&=~_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20);
DDRB=0X81;
PORTB&=~_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20);
DDRB=0X81;
PORTB&=~_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20);
DDRB=0X81;
PORTB&=~_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
_delay_us(50);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20); //1
DDRB=0X81;
PORTB|=_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck; //判断DATA是否为HIGH
_delay_us(20);
DDRB=0X81;
PORTB&=~_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20);
DDRB=0X81;
PORTB&=~_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20); //1
DDRB=0X81;
PORTB|=_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20); //1
DDRB=0X81;
PORTB|=_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
_delay_ms(50);
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20); //1
DDRB=0X81;
PORTB|=_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck; //判断DATA是否为HIGH
_delay_us(20); //1
DDRB=0X81;
PORTB|=_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck; //判断DATA是否为HIGH
_delay_us(20); //1
DDRB=0X81;
PORTB|=_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck; //判断DATA是否为HIGH
_delay_us(20); //1
DDRB=0X81;
PORTB|=_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck; //判断DATA是否为HIGH
_delay_us(20);
DDRB=0X81;
PORTB&=~_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck; //判断DATA是否为HIGH
_delay_us(20);
DDRB=0X81;
PORTB&=~_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB=0X00;
while((PINB&0X80)!=0X80) gotorecheck;
_delay_us(20); //1
DDRB=0X81;
PORTB|=_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
_delay_ms(1000);
}
}
} 希望哪位高手给点建议!好急啊! 为什么要发0xff? 搞错,是发0XF0,我不知道啊,我以为要发给电脑要发字符的通码后和0XF0加断码后电脑才能显示,请问怎样发才对呢?你有例子共享吗?谢谢 好急啊,自己顶一下! 很多人看到这样程序就不想去分析了,先把代码优化一下,可能解答的人就多些了。 是不是学汇编过来的呀。 我什么都不学好就过来啦!
因为之前没写过PS2这方面的,所以就用最笨的办法写的,希望大家给实在点的帮助!其他话少说点! 没时间仔细看程序,不过有几点请注意:
1. PS2的键盘发送程序是要有回应的。
接收程序比较好做,因为只需要接收相应的通断码,
发送程序做起来难,因为系统本身是一个SLAVE从机,要回应HOST主机的命令。
也就是说,刚上电时,如果没有对HOST主机的发问做正确的应答,就是没有握手成功,主机当从机为不存在,因此也拒绝接受任何通断码。
2. CLOCK 和 DATA两根线,连接主机时最好中间串入电阻(例如100欧),以防同时通信冲突,造成短路(特别对于AVR的推挽式输出I/O口)。 好多goto啊,想起以前用汇编的时候。 我的键盘是在电脑驱动了一个完好的键盘后,拔掉掉原先那个键盘,插入自己的键盘进行调试,这样可以吗?还有请问是不是接受了电脑发过来的数据后,键盘都反回0XFA给电脑就可以啦! 这是我现在整理后的程序,希望fhqmc 有空的话看看,看看我这样来读电脑发过来的数据对吗?我这样发送数据给电脑对吗?我自己做的键盘不是和电脑一起启动的,是电脑和另一个键盘启动后,我拔掉它插上去调试的,这样可以吗?
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/signal.h>
#include <stdio.h>
//#define 时钟线PB0
//#define 数据线PB7
unsigned char del_1,key_data,key_down,got,se_data,key,key_;
void send_0(void) //发送启事位
{
DDRB|=_BV(PB7);
DDRB|=_BV(PB0);
PORTB&=~_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB&=~_BV(PB7);
if((PINB&0x80)==0x00) //发完一个位后判断数据线是否为底,否--继续发送
got=1;
}
void send_1(void) //发送结束位
{
DDRB|=_BV(PB7);
DDRB|=_BV(PB0);
PORTB|=_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
DDRB&=~_BV(PB7);
if((PINB&0x80)==0x00) //发完一个位后判断数据线是否为底,否--继续发送
got=1;
}
void send(unsigned char dat_sent)
{
char fg_i;
for(fg_i=0;fg_i<8;fg_i++)
{
DDRB|=_BV(PB7);
DDRB|=_BV(PB0);
if(dat_sent&0x80)
PORTB|=_BV(PB7);
else
PORTB&=~_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
dat_sent<<=1;
DDRB&=~_BV(PB7);
if((PINB&0x80)==0x00) //发完一个位后判断数据线是否为底,否--继续发送
{
got=1;//发完一个位后判断数据线是否为低标志位
fg_i=9;
}
}
}
void on_of(unsigned char jiou) //发送奇偶位
{
unsigned char fh,fg;
for(fh=0;fh<8;fh++)
{
if(jiou&0x80)
fg++;
jiou<<=1;
}
if(fg%2==1)send_0();
else send_1();
}
void send_yda(unsigned char dat_fa) //应答电脑回复0xfa数
{
char fg_i;
for(fg_i=0;fg_i<8;fg_i++)
{
DDRB|=_BV(PB7);
DDRB|=_BV(PB0);
if(dat_fa&0x80)
PORTB|=_BV(PB7);
else
PORTB&=~_BV(PB7);
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
dat_fa<<=1;
DDRB&=~_BV(PB7);
if((PINB&0x80)==0x00) //发完一个位后判断数据线是否为低,否--继续发送
{
got=1; //发完一个位后判断数据线是否为低标志位
fg_i=9;
}
}
}
void read_data(void) //接收电脑发过来的数据,数据忽略
{
unsigned char ten;
for(ten=0;ten<10;ten++)
{
_delay_us(20);
DDRB|=_BV(PB0);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
}
}
SIGNAL(SIG_OVERFLOW0)
{
TCNT0=0X00;
if(((PINC&0x80)==0x00)&&(key_==0))
{
key_down=1;
key_=1;
se_data=0x1c;
}
if(((PINC&0x80)==0x80)&&(key_==1))
{
key_down=2;
key_=0;
}
if(((PINC&0x40)==0x00)&&(key_==0))
{
key_down=1;
key_=2;
se_data=0x32;
}
if(((PINC&0x40)==0x40)&&(key_==2))
{
key_down=2;
key_=0;
}
if(((PINC&0x20)==0x00)&&(key_==0))
{
key_down=1;
key_=3;
se_data=0x21;
}
if(((PINC&0x20)==0x20)&&(key_==3))
{
key_down=2;
key_=0;
}
if(((PINC&0x10)==0x00)&&(key_==0))
{
key_down=1;
key_=4;
se_data=0x23;
}
if(((PINC&0x10)==0x10)&&(key_==4))
{
key_down=2;
key_=0;
}
}
//本程序想在电脑上显示a字符,发送流程是先发送a的通码,再发0xff,接着发a的断码,请问我这样做对吗?PB0接clkPB7接data
int main(void)
{
DDRB=0x00;
PORTB=0XFF;
DDRC=0x00; //pcin
PORTC=0xff;
TIMSK=0x02;//允许溢出中断
TCNT0=0X00;//初值为0
TCCR0=2;//使用64分频
SREG=0x80;//开全中断
while(1)
{
while(1)
{
recheck:
if(key_down==1)
{
DDRB&=~_BV(PB0);
while((PINB&0x01)!=0x00); //判断clk是否为low
_delay_us(50);
while((PINB&0x01)!=0x01) //判断clk是否为high否--等待
gotorecheck;
DDRB&=~_BV(PB7);
if((PINB&0x80)!=0x80) goto read; //判断data是否为high
_delay_us(20); //0
send_0(); //启示位
if(got==1)
{
got=0;
gotoread;
}
// se_data=0x1c;
send(se_data);//发a字符
if(got==1)
{
got=0;
gotoread;
}
on_of(se_data);//奇偶位
if(got==1)
{
got=0;
gotoread;
}
send_1();//结束位
if(got==1)
{
got=0;
gotoread;
}
}
else if(key_down==2)
{
//se_data=0xf0;
_delay_ms(30);
recheck1:
DDRB&=~_BV(PB0);
while((PINB&0x01)!=0x00); //判断clk是否为low
_delay_us(50);
while((PINB&0x01)!=0x01)//判断clk是否为high否--等待
gotorecheck1;
DDRB&=~_BV(PB7);
if((PINB&0x80)!=0x80) goto read; //判断data是否为high
gotoread;
_delay_us(20); //0
send_0(); //启示位
if(got==1)
{
got=0;
gotoread;
}
send(0xf0);//发a字符
if(got==1)
{
got=0;
gotoread;
}
on_of(se_data);//奇偶位
if(got==1)
{
got=0;
gotoread;
}
send_1();//结束位
if(got==1)
{
got=0;
gotoread;
}
//se_data=0x1c; //发送A的断码
_delay_ms(30);
recheck2:
DDRB&=~_BV(PB0);
while((PINB&0x01)!=0x00); //判断clk是否为low
_delay_us(50);
while((PINB&0x01)!=0x01)
goto recheck2;
DDRB&=~_BV(PB7);
if((PINB&0x80)!=0x80) goto read; //判断data是否为high
gotoread;
_delay_us(20); //0
send_0(); //启示位
if(got==1)
{
got=0;
gotoread;
}
send(se_data);//发a字符
if(got==1)
{
got=0;
gotoread;
}
on_of(se_data);//奇偶位
if(got==1)
{
got=0;
gotoread;
}
send_1();//结束位
if(got==1)
{
got=0;
}
_delay_ms(30);
gotorecheck;
}
read: //键盘读数据
DDRB&=~_BV(PB0);
while((PINB&0x01)!=0x01);//判断clk是否为high否--等待
read_data(); //读十位数据
DDRB&=~_BV(PB7);
while((PINB&0x80)!=0x80)//判断数据线是否还为低,保持时钟信号
{
DDRB=0XFF;
_delay_us(20);
PORTB&=~_BV(PB0);
_delay_us(40);
PORTB|=_BV(PB0);
_delay_us(20);
}
DDRB&=~_BV(PB0);
while((PINB&0x01)!=0x00); //判断clk是否为low
_delay_us(50);
while((PINB&0x01)!=0x01);//判断clk是否为high 否--等待
DDRB&=~_BV(PB7);
if((PINB&0x80)!=0x80)
if(got==1)
{
got=0;
gotoread;
}
se_data=0xfa;
_delay_us(20); //0
send_0(); //启示位
if(got==1)
{
got=0;
gotoread;
}
send(se_data);//发a字符
if(got==1)
{
got=0;
gotoread;
}
on_of(se_data);//奇偶位
if(got==1)
{
got=0;
gotoread;
}
send_1();//结束位
if(got==1)
{
key=0;
gotorecheck;
}
}
}
} 我不太懂这个通讯协议,不过说点意见:如果是USB口键盘,什么时候插上都可以使用。但是PS2口的,如果开机时没有插上,或中途断电了,再插上,好象就不能使用了。楼主是不是注意下这个问题。 PS2接口原本并不支持热插拔。不过按网上流传的PS2中文资料来看,如果PS2设备拔下又插上,WINDOWS会主动尝试重连的。
建议换PS2-USB线进行初步调试,OK之后,再插电脑主板原生的PS2口。 代码有这么多么?看得眼睛都花了。我以前写过一个,好像就不到100行而已吧。
页:
[1]