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

📄 keymatrix3.c

📁 C51写的单片机串口通信程序,用于键盘测试和USB接口测试!
💻 C
📖 第 1 页 / 共 2 页
字号:

//******************************************************************************
#include "At89x52.h"
#include "Intrins.h"
//******************************************************************************


//******************************************************************************
#define uchar unsigned char

//******************************************************************************
/* Bit Address Assignment*/
/*
sbit LedIn1=P0^0;       //LED光感应输入
sbit LedIn2=P0^1;
sbit LedIn3=P0^2;
sbit LedIn4=P0^3;
sbit LedIn5=P0^4;
sbit LedIn6=P0^5;
sbit LedIn7=P0^6;
sbit LedIn8=P0^7;
sbit LedIn9=P2^0;
sbit LedIn10=P2^1;
*/
sbit Mc14Inh1=P1^3; //P2^2;  //4-16译码器禁止位

sbit Mc14Inh2=P2^3;

sbit FixUpLeft=P2^4;  //P2^4;
sbit FixUpRight=P2^5;
sbit FixDownLeft=P3^2;
sbit FixDownRight=P3^3;

sbit latch1=P2^2;
sbit latch2=P2^3;

sbit EncoderA=P2^6;    //译码信号输出
sbit EncoderB=P2^7;

sbit BoardPower1=P3^4;
sbit BoardPower2=P3^5;
sbit BoardPower3=P3^6;
sbit BoardPower4=P3^7;


//******************************************************************************
volatile uchar MsgOk=0x00;
volatile uchar Rs232State=0x00;
volatile uchar Rs232Timer=0;		//单位:100ms

uchar ReceiveBuffer[2];
uchar SendBuffer[13];

bit w25msf;	//2.5ms标志

volatile uchar Timer1s=0;
volatile uchar Timer100ms=0;
volatile uchar Timer2500us=0;


//******************************************************************************
void Send(len)
//功能:发送一帧消息,消息格式参见设计说明
//入口:len=正文信息长度
{
  uchar *p;
  uchar CheckSum=0;
 // uchar code MSG_VER[]="200402200005";

  //发送用查询方式,关闭串口中断
  ES=0;

  //发送2字节起始同符0xA5,0x5A
 // SBUF=0xA5;while(!TI);TI=0;
 // SBUF=0x5A;while(!TI);TI=0;

  //发送长度字节
 // SBUF=12+len;while(!TI);TI=0;
  //SBUF=len;while(!TI);TI=0;
  //发送版本信息
/*  p=MSG_VER;
  while(*p)
  {
    SBUF=*p;
    CheckSum+=*p++;
    while(!TI);TI=0;
  }   */

  //发送正文信息
  p=SendBuffer;
  do
  {
    SBUF=*p;
    CheckSum+=*p++;
    while(!TI);TI=0;
  }while(--len);

  //发送检测和字节
  //SBUF=CheckSum;
 // while(!TI);
 // TI=0;

  //恢复串口中断
  ES=1;
}
//******************************************************************************


//******************************************************************************
void Init()
{
  uchar i,j;

  //中断配置:本系统仅使用串口中断(高优先级)和定时中断0(低优先级),
  //BIT 7  6   5  4   3   2   1   0
  //IE: EA – ET2 ES ET1 EX1 ET0 EX0
  //    0  0   0  1   0   0   1   0
  IE=0x12;
  IP=0x10;

  //delay some time for stable
  for(i=0;i<200;i++) for(j=0;j<250;j++);

  //I/O端口初始化
  P0=0xFF;	//P0为给MPPC的/RESET和/REQ信号,正常状态无效置高
  P1=0xFF;	//P1为从MPPC输入经过74HC244缓冲的的输入信号,要求置高才能读
  P2=0xFF;	//P20,P21为给译码器74HC139地址信号A0和A1,其它未用置高
  P3=0xFF;	//P30,P31分别为串口信号RXD和TXD,

  //设定串口模式为:8位波特率可鹿编程单机模式,即模式1,置接收使能
  SCON=0x50;

  //T0用作2.5mm定时器,T1用作9600bps的波特率发生器
  TMOD=0x21;	//T1为8位自动重载,T0为16位软件重载定时
  TH0=0xF7;	//2.5ms=0.0025=Tosc*12*(0x10000-T0)==>T0=0x10000-0.0025*Fosc/12=0xF700
  TL0=0x00;
  PCON=0x00;	//SMOD=0
  TH1=TL1=0xFD;	//TH1=256-Fosc/{[2^(1-SMOD)]*16*12*9600bps}=0xFD
  TCON=0x50;	//0101 0000 (TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0)

  //定时器2未用,设为缺省值
  T2CON=T2MOD=0x00;
  RCAP2L=RCAP2H=0x00;
  TL2=TH2=0x00;

  EA=1;
}
//******************************************************************************


//******************************************************************************
void Recieve()interrupt 4 using 3 	//command recieve
//0xA5,0x5A,len,msg,cs
{
  static uchar i;	//len,  //定义len和i为静态存贮变量,即在程序运行期间,固定分配物理空间。
//  static uchar CheckSum;

  if(RI&&(MsgOk!=0x55))
  {
    switch(Rs232State)
    {
 /*     case 0:
      {
        if(SBUF==0xA5)
        {
          ++Rs232State;
          Rs232Timer=20;	//设定超时值100ms*20=2S!
        }
        break;
      }
      case 1:
      {
        if(SBUF==0x5A) ++Rs232State;
        else Rs232State=0;
        break;
      }
      case 2:
      {
        len=SBUF;
        if( (len==1) || (len==2) )
        {
          ++Rs232State;
          CheckSum=0;
          i=0;
        }
        else Rs232State=0;
        break;
      }		      */
      case 0:
      { i=0;
        ReceiveBuffer[i]=SBUF;
		++i;
		++Rs232State;
   //     CheckSum+=ReceiveBuffer[i];
   //     if(++i==len) Rs232State=4;
        break;
      }
      case 1:
      { ReceiveBuffer[i]=SBUF;
	    if (++i==2) Rs232State=0; MsgOk=0x55;
    //    uchar tmp=SBUF;
    //    if(CheckSum==tmp) MsgOk=0x55;
    //    Rs232State=0;
        break;
      }
      default:Rs232State=0;break;
    }
  }
  RI=TI=0;
}
//******************************************************************************


//******************************************************************************
void Timer0(void)interrupt 1 using 2
//2.5ms一次中断
{
  static uchar i=40;	//定义j和i为静态存贮变量,即在程序运行期间,固定分配物理空间。而不是需要才分配。
  static uchar j=10;

  TR0=0;TH0=0xf7;TL0=0x00;TR0=1;

  w25msf=1;

  if(Timer2500us) Timer2500us--;

  if(--i==0)
  {
    i=40;
    if(Timer100ms) Timer100ms--;
    if(Rs232Timer) Rs232Timer--;
    if(Rs232Timer==0) Rs232State=0;
    if(--j==0)
    {
      j=10;
      if(Timer1s) Timer1s--;
    }
  }
}
//******************************************************************************


//******************************************************************************
void main()
{   
    uchar ScanL1;
    uchar ScanH1;
    uchar LedInL1;
    uchar LedInH1;
    uchar DelayTime;

	uchar PowerCount1;
	uchar PowerCount2;
	uchar OffCount1;
	uchar OffCount2;
	uchar HubCount1;
	uchar HubCount2;
  Init();
  PowerCount1=0;
  PowerCount2=0;
  OffCount1=0;
  OffCount2=0;
  HubCount1=0;
  HubCount2=0;
  while(1)
  { latch2=0;              //关闭译码器二
	latch1=0;			   //关闭译码器一
    if(MsgOk==0x55)   //收到PC机命令
    { 
	  if (FixDownLeft&&FixDownRight) {SendBuffer[0]=0xA5;SendBuffer[1]=0x00;Send(2);}
	    else if(!(FixDownLeft||FixDownRight)) {SendBuffer[0]=0xA5;SendBuffer[1]=0x01;Send(2);}
		 else if (!FixDownLeft)
	   	   {
             switch(ReceiveBuffer[0])
              {
               case 0xA0:		//收到启动命令消息
                {
                 switch (ReceiveBuffer[1])
                  {case 0x01:
		            if (PowerCount1==0)
		  	          { ++PowerCount1;
			            BoardPower1=0;		   //BOARD1电源开
			     Timer2500us=200;
           	     while(Timer2500us);  //延时500ms	   
		   	     SendBuffer[0]=0xA0;
           	     SendBuffer[1]=0x31;
           	     Send(2);}
			else if (PowerCount1==1)
			   {PowerCount1=0;
			     BoardPower2=0;		   //BOARD2电源开
			     Timer2500us=200;
           	     while(Timer2500us);  //延时500ms	   
		   	     SendBuffer[0]=0xA0;
           	     SendBuffer[1]=0x31;
           	     Send(2);}
					
		   break;
		   case 0x00:
		    if (OffCount1==0)
			{++OffCount1;
			BoardPower1=1;		   //BOARD1电源关
		    Timer2500us=200;
           	while(Timer2500us);     //延时500ms
			SendBuffer[0]=0xA0;
            SendBuffer[1]=0x30;			   
          	Send(2);}
		   else if (OffCount1==1)
			{OffCount1=0;
			BoardPower2=1;		   //BOARD1电源关
		/*	FixUpLeft=0;
		    Timer2500us=200;
           	while(Timer2500us);     //延时500ms
			FixUpLeft=1;	*/
			SendBuffer[0]=0xA0;
            SendBuffer[1]=0x30;			   
          	Send(2);}
		   break;
		   default:
		   break;
		  }	
          break;
        }

        case 0xA1:	//收到结束命令
        { switch (ReceiveBuffer[1])
          {case 0x01:
		  	Timer2500us=25;
           	while(Timer2500us);     //延时500ms
		  	LedInL1=P0;
			LedInH1=P2;
			//LedInH1=LedInH1&&0x03;
			SendBuffer[0]=0xA1;
          	SendBuffer[1]=LedInH1;
			SendBuffer[2]=LedInL1;
			Send(3);
		   break;

		   case 0x00: //收到测试LED OFF命令
          	Timer2500us=25;
           	while(Timer2500us);     //延时500ms
		  	LedInL1=P0;
			LedInH1=P2;
			SendBuffer[0]=0xA1;
          	SendBuffer[1]=LedInH1;
			SendBuffer[2]=LedInL1;
			Send(3);
		   break;
		   default:
		   break;
		  }
         
          break;
        }
		case 0xA2:
		{ switch (ReceiveBuffer[1])
          {case 0x01:
		  	Timer2500us=25;
           	while(Timer2500us);     //延时500ms
			latch2=0;              //关闭译码器二
		  	latch1=1;			   //打开译码器一
		     for (ScanL1=0;ScanL1<=16;ScanL1++) 
		      	{P1=ScanL1; 
		       	Timer2500us=DelayTime;
               	while(Timer2500us);
			  	}
	           	latch1=0;		  //关闭译码器一
		       	latch2=1;		  //打开译码器二
			 for (ScanH1=0;ScanH1<=11;ScanH1++)
	          	{P1=(ScanH1<<4); 
			   	Timer2500us=DelayTime;
               	while(Timer2500us);
			  	}
	           	latch2=0;		 //关闭译码器二

			  	SendBuffer[0]=0xA2;
          	    SendBuffer[1]=0x30;
          		Send(2);
		   break;
		   case 0x00:
          	 Timer2500us=25;
               	while(Timer2500us);
			latch1=0;		  //关闭译码器一
		  	latch2=0;         //关闭译码器二
		   break;
		   default:
		   break;
		  }

		 break;
		}
		case 0xA3:
		{
         switch (ReceiveBuffer[1])
          {case 0x01:
		  	Timer2500us=10;
			while(Timer2500us);
			EncoderB=1;
			Timer2500us=2;
			while(Timer2500us);
		    EncoderA=1;
			Timer2500us=6;
			while(Timer2500us);
			EncoderB=0;
			Timer2500us=2;
			while(Timer2500us);
			EncoderA=0;
			Timer2500us=6;
			while(Timer2500us);
			EncoderB=1;
			Timer2500us=2;
			while(Timer2500us);
		    EncoderA=1;
		    Timer2500us=6;
			while(Timer2500us);
			EncoderB=0;
			Timer2500us=2;
			while(Timer2500us);
			EncoderA=0;
			SendBuffer[0]=0xA3;
          	SendBuffer[1]=0x30;
          	Send(2);
		   	break;
		   	case 0x00:
          	Timer2500us=10;
			while(Timer2500us);
			EncoderA=1;
			Timer2500us=2;
			while(Timer2500us);
		    EncoderB=1;
			Timer2500us=6;
			while(Timer2500us);
			EncoderA=0;
			Timer2500us=2;
			while(Timer2500us);
			EncoderB=0;
			Timer2500us=6;
			while(Timer2500us);
			EncoderA=1;
			Timer2500us=2;
			while(Timer2500us);
		    EncoderB=1;
			Timer2500us=6;
			while(Timer2500us);
			EncoderA=0;
			Timer2500us=2;
			while(Timer2500us);
			EncoderB=0;
			SendBuffer[0]=0xA3;
          	SendBuffer[1]=0x30;
          	Send(2);
		   	break;
		   	default:
		   	break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -