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

📄 my89c52.c

📁 我编写的一个单片机串口通讯加接收遥控的代码,接收完的遥控代码可通过串口传到计算机上,可做为一个测码程序
💻 C
字号:
/****************************************************************************************************************
* 本程序完成前面板的LED显示及接收遥控器,通过串行口与主cpu通讯
*
* 2002/12/12   修改定时器1中断与外部中断,指定寄存器数组以减少指令
               遥控器的循环左移改用_crol_函数以减少指令
			   LED显示函数的循环右移改为_cror函数,而不是用语句<<
*2003/03/20 修改程序以适合大显前面板
*2006/06/16 修改遥控器放在中断1 的放口上,串口输出的码改为10个字节
****************************************************************************************************************/
#include <reg52.h>    //跟据型号自己改 PHILIPS
#include <intrins.h>

unsigned char data  int_timer=0, INT_TIMES=0 ; //中断时间间隔与中断次数
unsigned char data LED_TIMES=0;
unsigned char data Remote_data[4];  //含客户码1,客户码2,遥控码1,遥控码2
unsigned char data  CUSTOM_CODE, POWER_KEY;

unsigned char data Repeate_key=0;
unsigned char data repeate_time=0; //计算repeate与head间的时间间隔

unsigned char bdata  Remote_flag=0 ;
sbit Head_ok=Remote_flag^7; //遥控器头部是否正确,1----正确,0----不正确
sbit Remote_OK= Remote_flag^6; //遥控器是否完成的判断
sbit Temp_data=Remote_flag^0;  //临时存放一位数据
//sbit Stand_by=Remote_flag^5; //Sdand_by状态标志位
sbit Close_Clock=Remote_flag^4 ; //0---显示过时间,1---第一次显示时间
sbit  outbuf_flag=Remote_flag^3;     //输出缓冲区非空标志   有=1              
sbit  inbuf_flag=Remote_flag^2;      //接收缓冲区非空标志   有=1
sbit Boot_flag=Remote_flag^1; //启动标志
//sbit RepT_over=Remote_flag^4 ; //repeate_time溢出标志

unsigned char data uart_tx_data[10];
unsigned char data uart_rx_data[8];
unsigned char uart_tx_p=0;
unsigned char uart_rx_p=0;

void send_remote(void);
void remote_wrong(void);
unsigned char mrab1(unsigned char *init);  //取1---15间的随机数
void timer_init();
void serial_init ();
void send_key(unsigned char kye_board);
void Keyboard_deay(void);
void head_wait(void);
void send_repeat(void);

void main(void) 
{
  //unsigned char  i;
 
  Boot_flag=0; //表示正地启动
  outbuf_flag=0;
  
  timer_init();
  serial_init ();
  
  //EX0=1;    //允许外部中断
  //IT0=1;   //中断0为低电平 
  EX1=1;    //允许外部中断
  IT1=1;   //中断1为低电平 
  ES=1;     //允许串口中断
  EA=1; 

  P0=0x00;
  P0=0xFF;   
  while(Boot_flag)  
 {

/* 向5518发送一个查询客户码的命令,同时也告知5518自己准备好了*/
   uart_tx_data[0]=0x5A;
   uart_tx_data[1]=0x5A;   
   uart_tx_data[2]=0x08;    //四号命令  
   uart_tx_data[3]=0x00;
   uart_tx_data[4]=0x00;
   uart_tx_data[5]=0x00;
   uart_tx_data[6]=0x00;
   uart_tx_data[7]=0x00;
   uart_tx_data[8]=0x00;
   uart_tx_data[9]=0x00; 

    uart_tx_p=0;
   //uart_tx_data[7]=mrab1(&RAB_INIT);
   // for(i=0;i<7;i++) uart_tx_data[i]=uart_tx_data[i]^led_table[uart_tx_data[7]];  
   
   SBUF= uart_tx_data[uart_tx_p];
   uart_tx_p++;
//   if(uart_tx_p>7) uart_tx_p=0;
   Keyboard_deay();
 }
  
  while(1)
  {   
#if 0
	 switch(P2)
   	 {
	   	  case 0xDF:  //right
   	  	    Keyboard_deay();
   	  	    if(P2==0xDF) send_key(0xDF);    //send_key(0xDF);
	   	  	break;
	   	  case 0xEF: //left
   	  	    Keyboard_deay();
   	  	    if(P2==0xEF) send_key(0xEF);    //send_key(0xEF);
	   	  	break;
	   	  case 0xF7: //up
   	  	    Keyboard_deay();
   	  	    if(P2==0xF7) send_key(0xF7);   //send_key(0xF7);
	   	  	break;
	   	  case 0xFB: //down
   	  	    Keyboard_deay();
   	  	    if(P2==0xFB) send_key(0xFB);  //send_key(0xFB);
	   	  	break;   	   
	   	  case 0xFD: //menu
   	  	    Keyboard_deay();
   	  	    if(P2==0xFD) send_key(0xFD);  //send_key(0xFD);
	   	  	break;   
	   	  case 0xFE:  //OK
   	  	    Keyboard_deay();
   	  	    if(P2==0xFE) send_key(0xFE);  //send_key(0xFE);
	   	  	break;   	   	   	  		   
	 } 
#endif
  }
}


void Keyboard_deay(void)
{
  unsigned short i=0;
  for(i=0;i<0xCFFF;i++){}
}
void timer_init()
{
  TMOD = 0x12;    /* 定时器0工作在模式1---0001,16位的定时器,定时器工作在方式2*/
 /* 定时器0,0.1mS中断一次,这里单片机晶体振荡频率为27MHZ*/
  TH0=0x1E;    //0xE9;
  TL0=0x1E;    // 0xE9;
 /* 定时器1, 4mS中断一次,这里单片机晶体振荡频率为27MH*/
 TH1=0xDC;     /* (65536-TH1TL1)*12/27MHz  */
 TL1=0xD7;
/* 定时器2, 用做串行口的婆特率发生器,9600*/
//  T2CON=0x30;
//  RCAP2H=0xFF;
//  RCAP2L=0x7A;

  ET0=1;         //定时器0中断允许
  //TR0=1;         //定时器0开始工作   
  ET1=1;         //定时器1中断允许
  TR1=1;         //定时器1禁止开始工作     
//  ET2=1;         //定时器2中断允许
//  TR2=1;         //定时器2开始工作     
}


void timer1(void) interrupt 3 using 2  //定时器1 中断程序
{
    LED_TIMES++;  // 4ms
    repeate_time++; // 4ms
    if(LED_TIMES==250)
     {
  	  // seconde++;   // 1秒钟 
  	  if(outbuf_flag)
	  	{
	  	  outbuf_flag=0;
	  	  P0=0xFF;
  	  	}
	  else{
	  	  outbuf_flag=1;
	  	  P0=0x00;
	  	}
	  
  	  LED_TIMES=0;
  	}    
  TH1=0xDC;
  TL1=0xD7;
  TF1=0;       //清除定时器中断标志  
}
void timer0(void) interrupt 1   //定时器0 TH 中断程序
{
  TF0=0;       //清除定时器中断标志
 /* 定时器1, 0.1mS中断一次,这里单片机晶体振荡频率为27MHZ */
  int_timer++;   // 0.1ms, 100uS  
}

void Remote(void) interrupt 2 using 1  //遥控接收程序
{
  INT_TIMES++;     //中断次数加一次,以控制数据的位数
  if(Head_ok)       //判断9mS的头码是否通过?通过则解码
  {
     if(INT_TIMES>=33)  send_remote();  //一个遥控中断总数为34次完成
     else{
        if(int_timer<=4) remote_wrong();
     	  if((int_timer>4)&&(int_timer<13)) Temp_data=0;
     	  if((int_timer>=13)&&(int_timer<=20)) remote_wrong();
     	  if((int_timer>20)&&(int_timer<24)) Temp_data=1;
     	  if(int_timer>=24) remote_wrong();
         if((int_timer>118)&&(int_timer<=138)) head_wait();

     Remote_data[(INT_TIMES-1)/8]=_crol_(Remote_data[(INT_TIMES-1)/8],1);
     if(Temp_data) Remote_data[(INT_TIMES-1)/8]=Remote_data[(INT_TIMES-1)/8]|Temp_data;
         int_timer=0;              
    }
  }
  else{   //判断头码
      if((int_timer>100)&&(int_timer<=112))
     {
        if(Repeate_key==0)
       {
         if((repeate_time>24)&&(repeate_time<30))       
         {
            Repeate_key++;           
          }
        }
        if(Repeate_key>0)
        {
           if((repeate_time>24)&&(repeate_time<32))
          	{
          	   Repeate_key++;
          	   if(Repeate_key==3) //重复5次算一次
               	{
               	  send_repeat();  //11.2mS, reapter
               	  Repeate_key=0;
               	} 
          	}          	
  	   }
        repeate_time=0;
       }
          if((int_timer>118)&&(int_timer<=138))  //9ms+4.5ms=13.5mS
           	{
                 Remote_data[0]=0x00;
                 Remote_data[1]=0x00;
                 Remote_data[2]=0x00;
                 Remote_data[3]=0x00;                 
           	   Head_ok=1;
           	   int_timer=0;
               INT_TIMES=0;
               repeate_time=0; 
           	}
          if(int_timer<89) //  next interrupt
          {
             int_timer=0;
             INT_TIMES=0;
             //Repeate_key=0;
             TR0=1;            
           }
           else remote_wrong();           
   }
}

void remote_wrong(void)
{
    int_timer=0;
    INT_TIMES=0;
    Head_ok=0;
}

void head_wait(void)
{
    int_timer=0;
    INT_TIMES=0;
    Head_ok=1;
    repeate_time=0; 
    Repeate_key=0;
}

void send_repeat(void)
{
   Head_ok=0;
   repeate_time=0; 
   int_timer=0;
   
   uart_tx_data[0]=0xA5;
   uart_tx_data[1]=0x08;   
   uart_tx_data[2]=Remote_data[0];
   uart_tx_data[3]=Remote_data[1];
   uart_tx_data[4]=Remote_data[2];
   uart_tx_data[5]=Remote_data[3];
   uart_tx_data[6]=0x00;
   uart_tx_data[7]=0x00;
   uart_tx_data[8]=0x00;
   uart_tx_data[9]=0x00; 
   uart_tx_p=0;
   SBUF= uart_tx_data[uart_tx_p];
   uart_tx_p++;

    INT_TIMES=0;
   TR0=0;
}

void send_remote(void)
{
  //unsigned char i;
   Head_ok=0;
   repeate_time=0; 
   Repeate_key=0;

      	
	   uart_tx_data[0]=0xA5;
	   uart_tx_data[1]=0x08;   
	   uart_tx_data[2]=Remote_data[0];
	   uart_tx_data[3]=Remote_data[1];
	   uart_tx_data[4]=Remote_data[2];
	   uart_tx_data[5]=Remote_data[3];
	   uart_tx_data[6]=0x00;
       uart_tx_data[7]=0x00;
       uart_tx_data[8]=0x00;
       uart_tx_data[9]=0x00;                   
	  // uart_tx_data[7]=mrab1(&RAB_INIT);
	  // for(i=0;i<7;i++) uart_tx_data[i]=uart_tx_data[i]^led_table[uart_tx_data[7]];  

	   uart_tx_p=0;
	   SBUF= uart_tx_data[uart_tx_p];
	   uart_tx_p++;

    INT_TIMES=0;
   int_timer=0;
   TR0=0;
}

/**************************************************************************************************************************************************************************
** 2002.12.02用此设置计算机接收到9600的数据
**************************************************************************************************************************************************************************/
void serial_init ()     //串口初始化   0xfd=19200,0xfa=9600,0xf4=4800,0xe8=2400,0xd0=1200
{
  SCON  = 0x50;                      /* mode 1: 8-bit UART, enable receiver   */
  PCON |= 0x00; 
  ES=1;    //串行中断允许
   /*定时器2工作在模式2用来产生波特率,不产生中断,12M频率,则TH1=0xFA SMOD=1*/
  // TH2=RCAP2H=0xFF; //27MHz,9600bps下的时钟
  // TL2=RCAP2L=0xA8;  //27MHz,9600bps下的时钟

    TH2=RCAP2H=0xFF; //27MHz,38400bps下的时钟  
    TL2=RCAP2L=0xEB;  //27MHz,38400bps下的时钟 
  
  ET2=0;            //定时器2的中断是被禁止的
  T2CON=0x34;   //0011,0100, 设为波特率发生器,并启动定时器2
}

serial () interrupt 4       //串口中断处理
{  

   if (TI ) 
    {
      TI = 0;  
    	if (uart_tx_p<10)              
    	{
    	   SBUF= uart_tx_data[uart_tx_p];   //未发送完继续发送
    	   uart_tx_p++;             //最后传出去的字节位置加一
     	} 
    }
    else if (RI)  
    {
       RI = 0;	
    	if(uart_rx_p<7)
    	{
         uart_rx_data[uart_rx_p]= SBUF;            //放入数据            
         uart_rx_p++;                    //最后放入的位置加一 
        }
    	else{  //接收完8个数据
         //  uart_rx_data[0]=uart_rx_data[0]^led_table[uart_rx_data[7]];
         //  uart_rx_data[1]=uart_rx_data[1]^led_table[uart_rx_data[7]];
            uart_rx_p=0;
           if((uart_rx_data[0]==0x5A)&&(uart_rx_data[1]==0x5A))
           	{
           	switch(uart_rx_data[2])
           		{
           		   case 0x01:    //节目号
           		   	break;
           		   case 0x02:   //时间
           		   	break;
           		   case 0x03:
           		   	break;
           		   case 0x04:
           		   	break;           		   	
           		   case 0x05: //回传数据
           		   	break;
           		   default:
           		   	break;
           		}
           	}
    	}
     }
}

void send_key(unsigned char kye_board)    //发送按键
{
    //unsigned char i;

	   uart_tx_data[0]=0xA5;
	   uart_tx_data[1]=0x08;   
	   uart_tx_data[2]=kye_board;      
	   uart_tx_data[3]=0x00;
	   uart_tx_data[4]=0xFF;
 	   uart_tx_data[5]=0x00; 
	   uart_tx_data[6]=0x00;
       uart_tx_data[7]=0x00;  
       uart_tx_data[8]=0x00;  
       uart_tx_data[9]=0x00;  
                
	   uart_tx_p=0;
	   SBUF= uart_tx_data[uart_tx_p];
	   uart_tx_p++;
}












⌨️ 快捷键说明

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