原创 MAX7219与LCD与通讯的一个综合应用[原创]

2011-1-5 21:12 1441 6 6 分类: MCU/ 嵌入式

32e6b2ee-cc50-44be-9e75-236673b44077.jpg


功能说明:


本功能板配合某门禁控制器使用


可识别ID卡并显示卡号。


1.                      按键1


  通讯测试状态,按下发送遥控开门命令。与计算机通讯约定数据长度为10。


2.                      按键2


  测试门禁遥控开门功能,按下发送遥控开门命令,若返回正确,显示DOOR IS OPEN 。


 


3.                      按键3


  LED演示功能,按键依次从1-8循环显示。


//-----------------------89c52    11.0592MHZ-------------
//51FLY 于2003年3月
#i nclude <AT89X52.H>
#i nclude <absacc.h>
#i nclude <intrins.h>  


#define Uchar unsigned char
#define Uint  unsigned int
#define LCDCOM  XBYTE[0x1fff]       //写指令地址
#define LCDDATA XBYTE[0x3fff]      //写数据地址
#define LCDBUSY XBYTE[0x5fff]      //忙标志
sbit bflag=ACC^7;
Uchar idata s_HEXLCD[16]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};//字符表
Uchar idata s_READY[9]={0x52,0x45,0x41,0x44,0x59,0x2e,0x2e,0x2e,0x00};  //READY
Uchar idata s_IDID[9]={0x49,0x44,0x43,0x2d,0x49,0x44,0x3a,0X20,0x00};   //ID_ID:
Uchar idata s_COMMN[9]={0x43,0x4f,0x4d,0x4d,0x4e,0x3a,0x20,0x20,0x00};  //COMMN:
Uchar idata s_SEND[9]={0x53,0x45,0x4e,0x44,0x2e,0x2e,0x2e,0x2e,0x00};   //SEND....
Uchar idata s_OPEN[9]={0x4f,0x50,0x45,0x4e,0x20,0x20,0x20,0x20,0x00};   //OPEN
Uchar idata s_DOOR[9]={0x44,0x4f,0x4f,0x52,0x21,0x20,0x20,0x20,0x00};   //DOOR!
Uchar idata s_DOORIS[9]={0x44,0x4f,0x4f,0x52,0x20,0x49,0x53,0x20,0x00}; //DOOR IS
Uchar idata s_ERROR[9]={0x45,0x52,0x52,0x4f,0x52,0x21,0x21,0x21,0x00};  //ERROR!!!


Uchar idata LENTH;               // 定义接收字符的长度
Uchar idata s_LCD[9];
//-------------------7219led---------------------------
sbit DIN=P1^4;
sbit CLK=P1^5;
sbit LOAD=P1^6;


Uchar idata s_LED[8]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}; 
//----------------------------------------------------
Uchar idata idcard[4];
bdata Uchar haha;
sbit b0=haha^0;
Uchar times;
bit  flag_card;
Uchar k,i,j,temp;
//---------------------------------------------------
bit  flag_read;
bit  key1;
bit  key2;
Uchar idata buf[20];        
Uchar idata DATA[11]={0x5a,0xff,0xfe,0x10,0x27,0x00,0x01,0x03,0x00,0x34,0x6b};   //遥控开门命令
//----------------------------------------------------
void wait(void);
void init_lcd(void);
void d_char(Uchar a);
void display(Uchar posx,Uchar posy,Uchar idata  *s);
void Delay5ms(void);
void Delay400ms(void);
void service_int0(void);
void hex_lcd(Uchar idata *s_HEX,Uchar n);
//-----------------------------------------------------
void send_data(Uchar idata *d);
void receive(void);
void init_comm(Uint baudrate);
//------------------------------------------------------
void send_led(Uchar add,Uchar dat);
//------------------------------------------------------
void dlms(void);
Uchar kbscan(void);


//------------------主程序--------------------------------
//-----------------------------------------------------
void main(void)
{
    Uchar key;
    Delay400ms();
    init_lcd();                      //初始化LCD
     
    display(0,0,s_READY);            //在第一行0位置显示   //显示READY...
 Delay400ms();
    
    P3_5=0;                          //back light
 _nop_();
 P3_5=1;
///////////////////////////////////////////////////////
    init_comm(9600);
/////////////////////////////////////////////////////
    EX0=1;
    EA=1;
    P1=0x8c;                          //置P1口状态
    P2_0=0;                           //输入使能


   //主循环
   while(1)                        
   { 
        key=kbscan();
      if(key==1)
     {   
                LENTH=11;  
          key1=1;
       key2=0;
          hex_lcd(DATA,0x04);
          display(0,0,s_SEND);                          //显示SEND...
                display(0,1,s_LCD);                           //在第二行显示发送的数据


    send_data(DATA); 
    LENTH=10;
    
  }
         if(key==5)
     {      
                LENTH=11;
             key2=1;
    key1=0;
          display(0,0,s_OPEN);                          //显示OPEN
                display(0,1,s_DOOR);                          //显示DOOR!


    send_data(DATA); 
    LENTH=10;
  }
         if(key==2)
     {      
                send_led(0x0c,0x01);             //初始化7219LED
             send_led(0x0b,0x07);
             send_led(0x0a,0xf1);
             send_led(0x09,0xff);
             send_led(0x0f,0x00);


          send_led(0x01,s_LED[0]);                       
       send_led(0x02,s_LED[1]);
       send_led(0x03,s_LED[2]);
          send_led(0x04,s_LED[3]);
       send_led(0x05,s_LED[4]);
       send_led(0x06,s_LED[5]);
       send_led(0x07,s_LED[6]);
          send_led(0x08,s_LED[7]);


       temp=s_LED[0];                    //LED流水灯
       for(i=0;i<8;i++)
       s_LED=s_LED[i+1];
       s_LED[i-1]=temp; 
  }


         if(flag_card)
        {            
    flag_card=0;
          hex_lcd(idcard,0x04);
         
                display(0,0,s_IDID);                          //在第一行显示ID_ID:         
    display(0,1,s_LCD);                           //在第二行0位置显示卡号                                         
        }
                        
      if(flag_read)
    {   
     flag_read=0; 
     if(key1==1)
         {
          hex_lcd(buf,0x04);    
    
                display(0,0,s_COMMN);                         //第一行显示COMM:         
    display(0,1,s_LCD);                           //在第二行显示数据


       send_data(buf);                               //接收到数据发送
      }
     if(key2==1)
      {
        if((buf[0]==0x5a)&&(buf[4]==0x11)&&(buf[9]==0x6b))
                 display(0,0,s_DOORIS);                        //显示DOORIS    
     else
                 display(0,0,s_ERROR);                         //显示ERROR 
             display(0,1,s_OPEN);                          //显示OPEN
      }  
    }
    P3_4=~P3_4;                                                 //工作指示灯反转
    Delay5ms();
   }
}


//-------------------------------------------------------
//-------------------44780显示-------------------------------
void hex_lcd(Uchar idata *s_HEX,Uchar n)  //查找字符在LCD中对应的显示值,结果军在s_LCD[]中
{     
          
       Uchar i,j=0,temp=0;
     
        for(i=0;i<n;i++)
         {
           temp=s_HEX>>4;
                 s_LCD[j++]=s_HEXLCD[temp];               //字节高位
           temp=s_HEX&0x0f;
                 s_LCD[j++]=s_HEXLCD[temp];               //字节低位
         }
         s_LCD[j]=0x00;
  
}
//--------------------------------------------------
void wait(void)
 {
   do
   {
     ACC=LCDBUSY;
   }
   while(bflag==1);
 }


void init_lcd(void)
 {
   LCDCOM=0x38;
   Delay5ms();
 
   LCDCOM=0x38;
   Delay5ms();
 
   LCDCOM=0x38;
   Delay5ms();


   LCDCOM=0x38;          //置功能    二 行5×7点阵
   wait();
   LCDCOM=0x08;          //显示关闭
   wait();
   LCDCOM=0x01;          //清屏
   wait();
   LCDCOM=0x06;          //置输入模式,地址增量,显示屏不移动
   wait();
   LCDCOM=0x0f;          //显示开,显示光标,光标闪烁
   wait();
  
 }


void d_char(Uchar a)
{
  wait();
  LCDDATA=a;
}



void display(Uchar posx,Uchar posy,Uchar idata  *s)
{
    Uchar i=0;
 Uchar temp;
    temp =posx&0xf;
    posy&=0x1;
    if(posy)
    temp|=0x40;
    temp|=0x80;
 wait();
    LCDCOM=temp;                     //置显示位置地址
    while(s!=0x00)
    {
     d_char(s);
     i++;
    }
}



void Delay5ms(void)
{
   Uint i=5552;
   while(i--);
}



void Delay400ms(void)
{
  Uchar i=5;
  Uint j;
  while(i--)
  {
      j=7269;
   while(j--);
  };
}
//-------------------------------------------------------
//-------------------读卡相关----------------------------
void service_int0(void) interrupt 0 using 2   //int0 中断服务程序,使用第二组寄存器
{
      EX0=0;  
   for(k=0;k<3;k++)
     {  
           haha=0;
     for(times=0;times<8;times++)                          //8位
     {
                              //等待高电平
           for(j=0;j<0xff;j++)
         {
           if(P3_2==0)          
           {
               b0=P1_7;             
               haha=haha<<1;                                 
                    //等待低电平
             for(j=0;j<0xff;j++)
                {
                                if(P3_2==1) 
              goto next;            
                                              }
            
            goto reti;
           }
         }      
        goto reti;                                //电平未变化,退出
  next:     _nop_();
     }
      idcard[k]=haha;         
     }
                  flag_card=1;


reti:     EX0=1;
                 
}
//------------------------------------------------------------------------
//-----------------------------通讯相关-----------------------------------
void init_comm(Uint baudrate)   //fosc=11.059mhz,SMOD=0
{
    PCON=0x00;                  //SMOD=0;
    SCON=0x70;                  //通讯工作于方式1
    TMOD=0x20;                  //T1工作于方式2
    TL1=TH1=256-(28800/baudrate);


 TR1=1;                      //启动定时器
 ES=1;


}
//--------------------------------------------------
void send_data(Uchar idata *d)
{
     Uchar i;
     ES=0;
     P2_0=1;                        //输出使能
          
        for(i=0;i<LENTH;i++)
       {
         SBUF=d;
         while(TI==0);            //等待TI=1;
         TI=0;
       }   
  P2_0=0;                        //输入使能
     ES=1;
   
}
//--------------------串口中断---------------------------------
void receive(void)  interrupt 4 using 3
{
    Uchar i;
    ES=0;                            //关串口中断
      
         for(i=0;i<LENTH;i++)
      {
         while(RI==0); 
      RI=0;
         buf=SBUF; 
         } 
  
 flag_read=1;       
 ES=1;
}
//-----------------------------------------------------
//-------------------2*2键盘-------------------------------
void dlms()
 {
    Uchar i;
 for(i=200;i>0;i--){}
 }
//2*2键盘扫描
//键值  1号---1   2号------5 3号---2  4号-----6


 Uchar kbscan(void)                                      
 {
      Uchar sccode,recode;
   P1=0x0c;                                        //p1.0 p1.1输出扫描码p1.211 p
   if((P1&0x0c)!=0x0c)
       {
     dlms();                                   //去抖
     if((P1&0x0c)!=0x0c)    
        {                                      //有键按下
       sccode=0xfe;
                while(sccode!=0xfb)      
                    {
                       P1=sccode;                     //送出扫描码
                       if((P1&0x0c)!=0x0c)
                          {
                             recode=(P1&0x0c);         //得到列值
                             return(sccode+recode);    //返回键值
                          }
                       else
                       sccode=(sccode<<1)|0x01;
                    }
     }


       }
    return 0;
 }
//---------------------7912led  display-------------------------
void send_led(Uchar add,Uchar dat)       //在指定位置显示dat
   {
     Uchar AD,i,j;
  LOAD=0;
  i=0;
    while(i<16)
    {
      if(i<8)
        {AD=add;}
      else
        {AD=dat;}
       for(j=8;j>=1;j--)
       {
          DIN=AD&0x80;
       AD=AD<<1;
       CLK=1;
       CLK=0;
       }
      i=i+8;
    }
  LOAD=1;
   }


PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
6
关闭 站长推荐上一条 /3 下一条