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

📄 main.c

📁 使用芯片AT89S52,6位七段数码管显示以及串口通讯
💻 C
字号:
//*******************************************************************
#include"at89x52.h"
#include<intrins.h>
#include<math.h>  
bit FLAG0=0;    /*设定位标号FLAG0=1键盘扫描回应*/
bit FLAG1=1;    /*设定位标号20H.1比较密码回应旗号*/
char m,ptr=0,ptr1=0;   /*PTR键盘扫描指标,ptr1显示器扫描指标*/
char a1=0,b1=100,stand=0,m=0; /*宣告变数a1为TIMER0的中断次数,ptr为TIMER1扫描数码管指标*/
char disple[10];    /*显示值存放阵列*/ 
unsigned char bufuart[8];                /*串口接收值存放阵列*/
unsigned char tem[8];
unsigned char bufdata[9];
unsigned char num=0;
unsigned char key_sym;
unsigned char i=0;
unsigned char crc;
unsigned char sym;
unsigned char tim;
static const char tab[16]={0x01,0x02,0x03,0x0c, /*键盘码00,01,02,03,*/
                           0x04,0x05,0x06,0x0d, /*键盘码04,05,06,07,*/
                           0x07,0x08,0x09,0x0e, /*键盘码08,09,0a,0b,*/
                           0x0a,0x00,0x0b,0x0f};/*键盘码0c,0d,0e,0f*/
void delay (unsigned int value)  /*延时副程式*/
 {
      while (value!=0) value--;  /*10US延时*/
 }
void scan(void);   /*键盘扫描副程式*/
void clear(void);
void angle(void);
void speed(void);
void tserial(void);
void xch(void);
/*********************************************************************/
main()     /*主程式*/
{
 TMOD=0x01;   
 TH0=(65536-3000)/256;  
 TL0=(65536-3000)%256;	
 TR0=1;    
 T2CON=0x38;   
 TL2=0xfd;   
 TH2=0xff;   /*设定传输波特率9600,晶体振荡器=11.059Mhz*/
 RCAP2L=0xdc;   /*设定传输波特率9600,晶体振荡器=11.059Mhz*/
 RCAP2H=0xff;   /*设定传输波特率9600,晶体振荡器=11.059Mhz*/
 TH2=256-(28800/9600);  /*设定传输波特率9600,晶体振荡器=11.059Mhz*/
     /*|波特率9600时|SMOD=0|C/T=0|模式=2|自动载入TH1=FD|*/  
     /*|波特率4800时|SMOD=0|C/T=0|模式=2|自动载入TH1=FA|*/
     /*|波特率2400时|SMOD=0|C/T=0|模式=2|自动载入TH1=F4|*/
     /*|波特率1200时|SMOD=0|C/T=0|模式=2|自动载入TH1=E8|*/
        TR2=1;    /*启动TEMER2*/
 SCON=0x50;   /*设定UART工作在MODE3模式,可传送和接收数据 REN=1*/
     /*串列控制寄存器SCON_______________________*/
            /*|  7    6    5    4 |  3    2    1    0 |*/
            /*| SM0| SM1| SM2| REN| TB8| RB8| TI | RI |*/
            /*|___________________|___________________|*/
        IE=0x9f;   /*8是允许中断,a是TIMER0,TIMER1中断致能位*/
     /*|  7    6    5    4 |  3    2    1    0 |*/
            /*| EA |    | ET2| ES | ET1| EX1| ET0| EX0|*/
            /*|___________________|___________________|*/
        IP=0x10;   /*中断优先级寄存器IP_______________________*/
            /*|    |    | PT2| PS | PT1| PX1| PT0| PX0|*/
            /*|___________________|___________________|*/

       P2_0=1;    /*关喇叭灭指示灯*/
       key_sym=3;
  while(1)
 {
    scan();  
    if(tim>160)// 480ms
    {
	    tim=0;
        if(key_sym==1) angle();
        else if(key_sym==2) angle();
        else if(key_sym==3) speed();
    }

  if(FLAG0==1) /*判断有按键输入否?111111111111*/
 {
    switch(tab[ptr])  
  {
     case 0x00:
	 case 0x01:
     case 0x02:
	 case 0x03:
	 case 0x04:
     case 0x05:
	 case 0x06:
	 case 0x07:
     case 0x08:
	 case 0x09:
	      if(sym==1)
         {
		  xch();
          num++;
		 }
         break;
     case 0x0d: 
         key_sym=1;
         //angle();
         break;  
     case 0x0e:  
         key_sym=2;
         //angle();
		 break;  
     case 0x0f: 
         key_sym=3;   
         //speed();
		 break; 
     case 0x0a: 
         sym=1;
         num=0;
         clear();
         break;        
     case 0x0b: 
         if(sym==1)         
         {
		 sym=0; 
		 tserial();	
		 }	  				  
		 break; 
	 default: 
         break;
   }    
  delay(100);   
  while(m==P1);  
  delay(100);
 }/*判断有按键输入否?111111111111*/
 
 delay(300);
}//while(1)

}


/*--------------------------------------*/
void scan(void)    /*扫描键盘副程式*/
 {
 char a1=0xf7,i;   /*A1=0XF7列扫描初值,I行*/
        FLAG0=0;   /*设按键回应旗号为0,键盘扫描计数指标为0*/
        ptr=0;
        for(i=0;i<4;i++)  /*键盘4个扫描列*/
      {
               P1=a1;   /*列扫描输出,读入P1存入M,以便侦测行与侦测按键是否放开*/
                m=P1;
                switch(m&0xf0)  /*取行的高4位元,侦测那一行被按*/
            {
             case 0x70: ptr=i*4; /*第一行被按否?是则扫描指标=列X4*/
                           FLAG0=1; /*是则设FLAG0=1表有按键输入*/
                           break; /*跳出此循环*/
                case 0xb0: ptr=i*4+1; /*第二行被按否?是则扫描指标=列X4+1*/
                           FLAG0=1; /*是则设FLAG0=1表有按键输入*/
                           break; /*跳出此循环*/ 
                case 0xd0: ptr=i*4+2; /*第三行被按否?是则扫描指标=列X4+2*/
                           FLAG0=1; /*是则设FLAG0=1表有按键输入*/
                           break; /*跳出此循环*/
                case 0xe0: ptr=i*4+3; /*第四行被按否?是则扫描指标=列X4+3*/
                           FLAG0=1; /*是则设FLAG0=1表有按键输入*/
                 default:  break; /*跳出此循环*/
            }
         if(FLAG0==1)break;  /*不为1,则扫描列右移,扫描下一列*/
         a1=a1>>1|0x80;   /*高位补1,由于P1.7~P1.4未接+5V,而是由指令加载高电平*/
       }
 }     /*返回主程式*/

/****************************************************/
void clear(void)		
 {
     char c;		
     for(c=0;c<6;c++)		
     {
     	disple[c]=0x00;
     }				
 }


void xch(void)				/*显示向右移动副程式*/
 {
     char c;				/*宣告变数*/
     for(c=5;c>0;c--)
     {
     	disple[c]=disple[c-1];		/*将显示器disple[]移位交换,disple[3]->disple[4]->disple[5]...*/
     }
     disple[0]=tab[ptr];		/*新的按键值存入disple[0]*/
 }					/*返回主程式*/
/****************************************************/

void angle(void)
{
 signed int d;
 //clear();
/* if(crc!=tem[7]) 
 {
 disple[0]=10;
 disple[1]=10;
 disple[2]=10;
 disple[3]=10;
 if(key_sym==1) disple[5]=1;
 if(key_sym==2) disple[5]=2;
 }
 else*/
// {
 if(key_sym==1)
 {
 disple[5]=1;
 d=tem[2];
 d=d<<8;
 d=d+tem[1];
 }
 if(key_sym==2)
 {
 disple[5]=2;
 d=tem[4];
 d=d<<8;
 d=d+tem[3];
 }
 if(d<0)  
 { 
  disple[3]=10; d=abs(d); 
 }
  else disple[3]=0x0f;
 d=d/13;
 disple[0]=(char)(d%10);
 d=d/10;
 disple[1]=(char)(d%10);
 disple[2]=(char)(d/10); 
// }

}

void speed(void)
{
 signed int d;
//clear();
 /*if(crc!=tem[7]) 
 {
 disple[0]=10;
 disple[1]=10;
 disple[2]=10;
 disple[3]=10;
 disple[5]=3;
 }
 else*/
// {
 disple[5]=3;
 d=tem[6];
 d=d<<8;
 d=d+tem[5];
 if(d<0)  
 { 
  disple[3]=10; d=abs(d); 
 }
 else disple[3]=0x0f;
 d=d/34;
 disple[0]=(char)(d%10);
 d=d/10;
 disple[1]=(char)(d%10);
 disple[2]=(char)(d/10); 

}


void tserial(void)			/*宣告串口serial发送副程式*/	
{
   unsigned char i=4;
   char j;
   char a,b;
   int dat=0;   
   for(j=(num-1);j>=0;j--)
   {
    dat=dat+disple[j];
	dat=dat*10;
   }
   dat=dat<<2;
   a=dat&0x00ff;
   b=(dat&0xff00)>>8;
   bufdata[0]=a^b;
   bufdata[1]=b;  //gao字节
   bufdata[2]=a;  //di字节
   bufdata[3]=0xaa;   //aa 
   
   IE=0x8f;
        {while(i>0)
	    {
	       i--;
	       SBUF=bufdata[i];		/*根据扫描指标到TAB中取ASCII码由SBUF发送出去*/
	       while(TI!=1);			/*发送完成否?*/
	       TI=0;				/*是,则清除发送完成旗标TI=0*/
 	       delay(10);
	    }
   }  
   IE=0x9f;
}

/*--------------------------------------*/
void service_int0 () interrupt 1 using 2    /*设定每隔3000us中断扫描一次数码管*/
 {   
        TH0=0xf8;  /*每隔4000US扫描一次2000*/ 
        TL0=0x30;
        if (ptr1==4) ptr1=5;  /*ptr1>5表示6个数码管都已经扫描过*/
        P0=(ptr1<<4)|disple[ptr1]; /*将扫描值左移至高4位元再加上资料码*/
        ptr1++;     /*扫描指标加1*/
		if(ptr1==6) ptr1=0;
		tim++;
		if(tim>160) tim=161;
 }     /*返回主程式*/


/********************************************************/

/*void uartcom1_in1 () interrupt 4 using 1  
 {
  unsigned char v,i=0;
  crc=0;
     while(RI!=1);    
      { 
  RI=0;
 v=SBUF;    
 if(v==0xaa)  
    { 
            while(RI!=1);  
      bufuart[i]=v;
             for(i=1;i<8;i++) 
  {
         while(RI!=1);  
  bufuart[i]=SBUF; / 
  if(i<7) crc^=bufuart[i];
  RI=0;   
     }
           }
 else delay(10);
  RI=0;
      } 
 for(i=0;i<8;i++)
 {
 tem[i]=bufuart[i];
 }
 if(key_sym==1) angle();
 if(key_sym==2) angle();
 if(key_sym==3) speed();
 } */
void uartcom1_in1 () interrupt 4 using 1  
{
  unsigned char i=0;
  crc=0;
  while(RI!=1);     
  RI=0;
  bufuart[i]=SBUF;    
  if(bufuart[i]==0xaa)  
  {  
   for(i=1;i<8;i++) 
   {
    while(RI!=1);  
    bufuart[i]=SBUF; 
    if(i<7) crc^=bufuart[i];
    RI=0;   
   }

   for(i=0;i<8;i++)
   {
    tem[i]=bufuart[i];
   }
   /*if(key_sym==1) angle();
   if(key_sym==2) angle();
   if(key_sym==3) speed();*/
  }
  else delay(10);
  RI=0;  
}   
/********************************************************/

⌨️ 快捷键说明

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