<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

        GSM_TC35“大哥大”(1602屏顯)(第二層)

        作者:馬梓熔   來源:馬梓熔的空間   點擊數:  更新時間:2014年04月10日   【字體:
        從初學AT指令到用上位機成功發送指令到下位機進行固定撥打電話發中英文短信到今天2012-11-30“”大哥大“調試成功差不多花去了半個月的時光~在實驗室每天花這么多時間浸淫的作品,都是血和淚,學習和積累了不少。。。。。。



















        4x4keyscan.h
        /***************************************************************************************************   
        功能描述: 用掃描法實現矩陣鍵盤掃描(無源有源皆實用)
        //     按鍵    掃描結果 |   按鍵   掃描結果|  按鍵   掃描結果 |  按鍵   掃描結果
        //     0      0XEE      |   4     0XDE    |   8     0XBE     |   12    0X7E
        //     1      0XED      |   5     0XDD    |   9     0XBD     |   13    0X7D
        //     2      0XEB      |   6     0XDB    |   10    0XBB     |   14    0X7B
        //     3      0XE7      |   7     0XD7    |   11    0XB7     |   15    0X77
        ***************************************************************************************************/
        #ifndef _4x4KEYSCAN_H_
        #define _4x4KEYSCAN_H_
        #define uchar unsigned char
        #define uint  unsigned int
        #define key P2
        //*****************************延時函數
        void delay_1ms(uint z); 
        //**************************************矩陣鍵盤掃描函數
        KeyScan();
        //***************************************矩陣鍵盤掃描結果處理函數
        uchar KeyHandle(uchar value);
        #endif  
        LCD1602display.h 
        #ifndef _LCD1602DISPLAY_H_
        #define _LCD1602DISPLAY_H_
        #define uchar unsigned char
        #define uint  unsigned int
        //************************LCD引腳定義
        sbit LCM_RS=P1^0;
        sbit LCM_RW=P1^1;
        sbit LCM_E=P1^2;
        //**************************延時
        void delay(uint z);
        //**************************初始化
        void InitLCM();
        //****************************讀狀態
        uchar ReadStatusLCM();
        //******************************讀數據
        //uchar ResdDataLCM();
        //***************************寫指令
        void WriteCommandLCM(uchar WCLCM, Busy);
        //***************************寫數據
        void WriteDataLCM(uchar WDLCM);
        //******************************顯示1個字符
        void DisplayOneChar(uchar X,uchar Y,uchar DData);
        //******************************顯示字符串
        void DisplayListChar(uchar X,uchar Y,uchar *DData);
        #endif
        GSM_call.h
        #ifndef _GSM_CALL_H_
        #define _GSM_CALL_H_
        #define uchar unsigned char
        #define uint  unsigned int
        #define Buf_Max 40 //緩存長度40
        /*
        //*****************************延時函數
        void delay_1ms(uint z);
        */
        //************************初始化串口函數
        void Serial_Init();
        //************************串口發送函數
        //void Send_Char(uchar ddata);
        //************************串口發送字符串
        void Send_String(uchar *tab);
        //****************************清除緩存內容
        void CLR_Buf();       
        //************************串口中斷函數
        //void Serial()interrupt 4;
        #endif 
        4x4keyscan.c
        #include <reg51.h>     
        #include "4x4keyscan.h"
        uchar z; //按鍵釋放的標志位
        uchar temp,KeyValue;          //定義掃描結果參數
        //*****************************延時函數
        void delay_1ms(uint z)
        {
         uint x,y;
         for(x=z;x>0;x--)
          for(y=110;y>0;y--);
        }
        //**************************************************************************************************
        //矩陣鍵盤掃描函數
        //**************************************************************************************************
        KeyScan() 
        {
          uchar scode=0x00;//掃描碼
          uchar rcode=0x00;//讀回碼
         
          key=0xf0;
          if((key&0xf0)!=0xf0)                   //判斷高4位是否為全1(高4位全1代表沒按鍵按下)
            {
              delay_1ms(10);                        //延時去抖動,一般為5ms~10ms(由于機械觸點的彈性作用,按鍵在閉合時不會馬上穩定地接通,
                                             //而在閉合瞬間伴隨有一連串的抖動,鍵抖動會引起一次按鍵被誤讀多次)
              key=0xf0;
              if((key&0xf0)!=0xf0)               //還能檢測到有鍵盤按下去,按行掃描
                {
          
                     scode=0xfe;                   //置掃描碼
                  while(scode!=0xef)            //如果沒有掃描完,繼續掃描
                     {
             
                       key=scode;                //送掃描碼
                       if((key&0xf0)!=0xf0)      //檢測到了
                         {
                            rcode=key;           //保存P2口的狀態
                            rcode=rcode & 0xf0; //生成返回碼高4位
                            scode=scode & 0x0f; //生成返回碼低4位
                            KeyValue=scode + rcode;//返回鍵盤編碼, 程序跳出鍵盤掃描函數(程序執行到return語句的時候就返回,他后面的語句都不會執行)
             
             while((key&0xf0)!=0xf0);  //等待松開按鍵
             z=1;       //松開按鍵后z置1
             return (KeyValue);     
                         }
                       else
                         {
                           scode=(scode<<1)|0x01;//移位,產生下一行掃描碼,順序:0xfe>>0xfd>>0xfb>>0xf7>>0xef
                         //當掃描碼為0xef時,判斷條件scode!=0xe為假 ,跳出while 循環
                         }
            
                     }
                   return(0);  //沒有檢測到返回0
                }
              else             //沒有鍵盤按下去,上一次是一個干擾
                {
                 return(0);    //沒有檢測到返回0
                }
            }
          else  //沒有鍵盤按下去
            {
             return(0);  //沒有檢測到返回0
            }
        }                          
        //**************************************************************************************************
        //矩陣鍵盤掃描結果處理函數
        //**************************************************************************************************
        uchar KeyHandle(uchar value)                    
        {
          switch(value)
          {
           case 0xee:{return(1);break;}    //對應按鍵S1
           case 0xde:{return(2);break;}    //對應按鍵S2 
           case 0xbe:{return(3);break;}    //對應按鍵S3 
           case 0x7e:{return(4);break;}    //對應按鍵S4 
           case 0xed:{return(5);break;}    //對應按鍵S5 
           case 0xdd:{return(6);break;}    //對應按鍵S6 
           case 0xbd:{return(7);break;}    //對應按鍵S7 
           case 0x7d:{return(8);break;}    //對應按鍵S8 
           case 0xeb:{return(9);break;}    //對應按鍵S9 
           case 0xdb:{return(10);break;}    //對應按鍵S10 
           case 0xbb:{return(11);break;}   //對應按鍵S11 
           case 0x7b:{return(12);break;}   //對應按鍵S12
           case 0xe7:{return(13);break;}   //對應按鍵S13 
           case 0xd7:{return(14);break;}   //對應按鍵S14 
           case 0xb7:{return(15);break;}   //對應按鍵S15 
           case 0x77:{return(16);break;}   //對應按鍵S16
           default:{return(0);break;} 
          }
        }
         

        LCD1602display.c
        #include <reg51.h>
        #include "LCD1602display.h"
        //********************延時
        void delay(uint z)
        {
         uint i,j;
         for(i=z;i>0;i--)
          for(j=110;j>0;j--);
        }
        //**********************LCM初始化
        void InitLCM()
        {
         WriteCommandLCM(0x38,0);  //三次顯示模式設置,不檢測忙信號
         delay(1);
         WriteCommandLCM(0x38,0);
         delay(1);
         WriteCommandLCM(0x38,0);
         delay(1);
         WriteCommandLCM(0x38,1);  //顯示模式設置:16×2顯示,5×7點陣,8位數據接口
         WriteCommandLCM(0x0c,1);  //顯示模式設置:顯示開,無光標
         WriteCommandLCM(0x06,1);  //顯示模式設置:光標右移,字符不移
         WriteCommandLCM(0x01,1);  //清屏幕指令,將以前的顯示內容清除
        }
        //*********************讀狀態
        uchar ReadStatusLCM()
        {
         P0 = 0x80;
         LCM_RS = 0;
         LCM_RW = 1;
         LCM_E = 1;
         while (P0 & 0x80); //檢測忙信號
         return(0);
        }
        //***********************讀數據
        /*uchar ResdDataLCM()
        {
         LCM_RS=1;
         LCM_RW=1;
         LCM_E=1;
        } */
        //**********************寫指令
        void WriteCommandLCM(uchar WCLCM, Busy)
        {
         if(Busy) ReadStatusLCM();
         P0=WCLCM;
         LCM_RS=0;
         LCM_RW=0;
         LCM_E=0;
         LCM_E=1;
        }
        //***********************寫數據
        void WriteDataLCM(uchar WDLCM)
        {
         ReadStatusLCM();
         P0=WDLCM;
         LCM_RS=1;
         LCM_RW=0;
         LCM_E=0;
         LCM_E=1;
        }
        //*************************顯示字符
        void DisplayOneChar(uchar X,uchar Y,uchar DData)
        {
         if(Y) X|=0X40;   //Y=1顯示第二行,Y=0顯示第一行
         X|=0X80;
         WriteCommandLCM(X,1); //X用來選擇哪一位,1是用來忙檢測
         WriteDataLCM(DData); //DData用來寫數據
        }
        //**************************顯示字符串
        void DisplayListChar(uchar X,uchar Y,uchar *DData)
        {
         uchar ListLength;
         ListLength=0;
         while(DData[ListLength]!='\0')
         {
          if(X<=15)
          {
           DisplayOneChar( X,Y,DData[ListLength]);
           ListLength++;
           X++;
          }
         }
        }
        GSM_call.c
        #include <reg51.h>
        #include "GSM_call.h"
        uchar i=0;             //定義緩存指針 
        uchar Rec_Buf[Buf_Max];  //定義緩存數組       
        /*
        //*****************************延時函數
        void delay_1ms(uint z)
        {
         uint x,y;
         for(x=z;x>0;x--)
          for(y=110;y>0;y--);
        }
        */
        //************************初始化串口函數
        void Serial_Init()
        {
         SCON=0x50;   //SM0,SM1=0,1方式1。REN=1,允許接收。
         PCON=0x00;  //比特率不加倍
         TMOD=0x20;  //定時器1的8位自動重裝計數
         TH1=0xFD;  //產生波特率為9600
         TL1=0xFD;
         IE=0x90; //EA=1,ES=1開總中斷和串口中斷
         TR1=1;  //打開定時器1
        }
        //************************串口發送函數
        //void Send_Char(uchar ddata)
        //************************串口發送字符串
        void Send_String(uchar *tab)
        {
            ES = 0;                   //關串口中斷,防止中斷嵌套
            for (tab; *tab!='\0';tab++)
             {
                 SBUF = *tab;
                 while(TI!=1);     //等待發送完成
           TI = 0;           //清除發送中斷標志位
          }   
         ES = 1;                   //開串口中斷 
        }
        //****************************清除緩存內容
        void CLR_Buf()
        {
         uchar k;
         for(k=0;k<Buf_Max;k++)  //將緩存內容清零
          {
           Rec_Buf[k]=0;
          }  
         i=0;
        }       
        //************************串口中斷函數
        void Serial()interrupt 4
        {
         ES=0;      //關串口中斷,防止中斷嵌套
         if(TI)      //如果是發送中斷,則不做任何處理
          {
           TI=0;    //清除發送中斷標志位
          }
         if(RI)      //如果是接收中斷,則進行處理
          {
           RI=0;    //清除接收中斷標志位
           if((SBUF<=90&&SBUF>=65)||(SBUF>=48&&SBUF<=59))  //只存儲‘A-Z’大寫字母和‘0-9’數字和”:;“
            {
             Rec_Buf[i] = SBUF;       //將接收到的字符串存到緩存中
             i++;                     //緩存指針向后移動
             if(i>40)                //如果緩存滿,將緩存指針指向緩存的首地址
              {
               i= 0;
              }
            }
          }
         ES = 1;       //開啟串口中斷  

        main.c 

        //*******************************************************************************************
        //                  mega3 大哥大(打電話、接電話)(1602回顯)
        //作者:馬梓熔
        //2012-11-30
        //
        //*******************************************************************************************
        #include <reg51.h> 
        #include "LCD1602display.h"
        #include "4x4keyscan.h"
        #include "GSM_call.h"
        #include "stdio.h"
        //********"4x4keyscan.h"
        extern uchar temp,KeyValue;  
        extern uchar z;
        //********"GSM_call.h"
        extern uchar i;             //定義緩存指針 
        extern uchar Rec_Buf[Buf_Max];  //定義緩存數組
        //*********main
        uchar str1[]="hello  mazirong!";
        uchar str2[]="calling.........";
        uchar AT[]="AT\r";
        uchar call[]="ATD13297961386;\r";
        uchar ATA[]="ATA\r";
        uchar ATH[]="ATH\r";
        //**************************************撥號函數
        void Phone()
        {          //    "012"
         uchar m=3;       //不更改“ATD”
         while(1)                      //進入while死循環
         {
          if(i!=0)
           {
            delay(1000); //接收GSM的返回命令(這個延時很有必要)
            DisplayListChar(0,1,Rec_Buf);
          //  delay(1000);    //屏蔽
          //  WriteCommandLCM(0x01,1); //為常顯    
            CLR_Buf();
           }
          KeyScan();                 //按鍵掃描
          temp=KeyHandle(KeyValue);  //處理掃描結果
          if(z==1)      //如果按鍵釋放
           {       //按鍵標志位清0
            z=0;
            switch(temp)
             {
              case 1:
               call[m]='1';  //1 被按下
               break;
              case 2:
               call[m]='2';  //2 被按下
               break;
              case 3:
               call[m]='3';  //3 被按下
               break;
              case 4: 
               break;    //空按鍵
              case 5:
               call[m]='4';  //4 被按下
               break;
              case 6:
               call[m]='5';  //5 被按下
               break;
              case 7:
               call[m]='6';  //6 被按下
               break;
              case 8:
               break;    //空按鍵
              case 9:
               call[m]='7';  //7 被按下
               break;
              case 10:
               call[m]='8';  //8 被按下
               break;
              case 11:
               call[m]='9';  //9 被按下
               break;
              case 14:
               call[m]='0';  //0 被按下
               break;
             }
           DisplayOneChar(m-3,0,call[m]);
           m++;
           switch(temp)
            {
              case 12:     //清屏按鍵按下
              m=3;
              WriteCommandLCM(0x01,1);
              break;
             case 13:        //撥號按鍵按下
              m=3;
              Serial_Init();  
              Send_String(call);
              WriteCommandLCM(0x01,1);//清屏
              DisplayListChar(0,0,str2); //uchar str2[]="calling........."; 
              break;
             case 15:     //掛斷按鍵按下
              m=3;
              Serial_Init();  
              Send_String(ATH);     
              WriteCommandLCM(0x01,1);//清屏   
              break;
             case 16:     //接聽鍵按下
              m=3;
              Serial_Init();  
              Send_String(ATA);   
              WriteCommandLCM(0x01,1);//清屏               
              break;    
            }
           }
         }     
        }
        //********************************主函數
        void main()                      

         InitLCM();     //初始化液晶
         DisplayListChar(0,0,str1); //uchar str1[]="hello  mazirong!";
         delay(1500);
         WriteCommandLCM(0x01,1); //清屏
         Serial_Init();    //串口初始化
         Send_String(AT);   //發送“AT指令”
         delay(100);        //硬件反應時間(很有必要)
         Phone();
        關閉窗口
        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮