⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 r&t.c

📁 avr单片机实现ps2的时序仿真
💻 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 + -