📄 r&t.c
字号:
#include <iom16v.h>
#include <macros.h>
#define BAUD 9600
#define BARR (7372800/(16*BAUD)-1)
#define Getdata() (PIND&0X10)
volatile unsigned char ps0revdata=0,ps0revdata0=0;
volatile unsigned char bitcount=0;
volatile char flag=0;
void PORT_init(void){
DDRD=0xe7;
PORTD=0x98;
}
//UART初始化函数
void UART_init( void )
{
UBRRH = (unsigned char)(BARR>>8);
UBRRL = (unsigned char)BARR;
UCSRB = (1<<RXCIE)|(1<<TXEN)|(1<<RXEN);//使能接收中断,使能接收,使能发送
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);//设置侦格式,异步,8位数据,一个停止位,无倍速
}
//UART发送数据
void uart_transmit(unsigned char data)
{
while(!(UCSRA&(1<<UDRE)));//等待发送缓冲器为空
UDR = data;
//while(!(UCSRA&0x40));//等待TXC置位
//UCSRA|=0x40; //写1清零
}
//外部中断1的中断服务程序,用于获得ps2设备扫描码
#pragma interrupt_handler int1_scr:3
void int1_scr(void)
{
bitcount++;
if(bitcount==1)
{
if(Getdata()==1)
{
bitcount = 0;
}
}
else if((bitcount>=2)&&(bitcount<=9))
{
ps0revdata>>=1;
if(Getdata()==0)
{
ps0revdata|=0x00;
}
else
{
ps0revdata|=0x80;
}
}
else if(bitcount == 11)
{
bitcount = 0;
if(flag==1) flag=0;
else uart_transmit(ps0revdata);
ps0revdata=0;
}
}
void pulldown_clk(void)//拉低时钟线
{
GICR&=~(1<<7);
GIFR&=~(1<<7);
DDRD|=(1<<3);
PORTD&=~(1<<3);
}
void pulldown_data(void){//拉低数据线
DDRD|=(1<<4);
PORTD&=~(1<<4);
}
void Release_clk(void)//释放时钟线
{
CLI();
//MCUCR = 0x00;
GICR|=(1<<7);
GIFR|=(1<<7);
DDRD&=~(1<<3);
SEI();
}
void Release_data(void)//释放数据线
{
DDRD&=0xef;
PORTD=0xef;
}
void delay_1us(void)//延时程序
{
}
void delay_nus(unsigned char n)
{
unsigned int i=0;
for(i=0;i<n;i++)
delay_1us();
}
//向ps2设备发送数据
void send_ps2data(unsigned char sendps2data)
{
unsigned char sendbit_cnt= 0x00;
unsigned char paritysum = 0x00;
unsigned char data=0x00;
unsigned char temp=0x00;
unsigned char ack;
flag = 1;
temp=sendps2data;
pulldown_clk();//将时钟线拉低并保持100 us
delay_nus(150);
pulldown_data();//拉低数据线
Release_clk();//释放时钟线
//CLI(); //disable all interrupts
//发送数据
for(sendbit_cnt=0;sendbit_cnt<8;sendbit_cnt++)
{
data=temp&0x01;
while(((PIND>>3)&0x01)) ; //等待时钟线变低
if(data==1)
PORTD|=(1<<4);
else
PORTD&=~(1<<4);
while(!((PIND>>3)&0x01)) ;//等待时钟线变高
paritysum+=data;//计算校验位
temp>>=1;//待发数据右移一位
}
//发送校验位
while((PIND>>3)&0x01) ;//等待时钟线变低
if(paritysum==1)
PORTD&=~(1<<4);
else
PORTD|=(1<<4);
while(!(PIND>>3)&0x01) ;//等待时钟线变高
//发送停止位
while((PIND>>3)&0x01) ;//等待时钟线变低
PORTD|=(1<<4);
while(!(PIND>>3)&0x01) ;//等待时钟线变高*/
//接收ACK
Release_data();
while((PIND>>3)&0x01) ;//等待时钟线变低
ack=Getdata();
while(!(PIND>>3)&0x01) ;//等待时钟线变高
//SEI() ;
}
//UART接收数据中断
#pragma interrupt_handler USART_RXC:12
void USART_RXC(void)
{
unsigned char temp;
temp=UDR;
send_ps2data(temp);
temp=0;
}
void main()
{ unsigned char i;
CLI();
PORT_init();
UART_init();
MCUCR = 0x08;
GICR = 0x80;
SEI();
for(i=0;i<2000;i++)//延时
;
while(1){
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -