標題: 51單片機電話鍵盤撥號 [打印本頁]

作者: 593719    時間: 2017-12-27 21:45
標題: 51單片機電話鍵盤撥號
  1. #include<reg51.h> // 包含單片機寄存器的頭文件
  2. #include<intrins.h>//包含_nop_()函數(shù)定義的頭文件
  3. typedef unsigned int uint;
  4. typedef unsigned char uchar;
  5. uchar  temp;
  6. uchar  key=16;
  7. sbit rs=P2^0;  //LCD1602數(shù)據(jù)/命令選擇
  8. sbit rw=P2^1; //LCD1602讀/寫選擇
  9. sbit lcden=P2^2; //LCD1602使能端
  10. uchar idata table[18]="ATD+86";
  11. uchar idata table[18];  //LCD1602所顯示的號碼緩存數(shù)組
  12. uchar idata table_int[18]="ATD+86";
  13. uchar idata receive[7];
  14. uchar idata erro[7]="erronum";
  15. uchar num=6,a=0,b=0;                //b接收,a發(fā)送,num表示table[]第幾位

  16. #define delayNOP();{_nop_();_nop_();_nop_();_nop_();};//宏定義,方便寫代碼

  17. /*延時子程序*/

  18. void delay(uchar x)
  19. {
  20.      uchar i;
  21.      while(x--)
  22.      {
  23.           for(i=0;i<125;i++)
  24.           {
  25.               {;}
  26.            }
  27.       }
  28. }

  29. /*檢查LCD忙狀態(tài) */
  30. /*lcd_busy為1時,忙,等待。lcd-busy為0時,閑,可寫指令與數(shù)據(jù) */

  31. bit busy()//LCD忙檢測
  32. {
  33.      bit result;
  34.      rs=0;
  35.      rw=1;
  36.      lcden=1;
  37.      delayNOP();
  38.      result=(bit)(P0&Ox80);
  39.      lcden=0;
  40.      return result;
  41. }

  42. /*寫指令數(shù)據(jù)到LCD                           */
  43. /*RS=L,RW=L,E=高脈沖,D0-D7=指令碼。        */


  44. void lcd_com(uchar cmd)
  45. {
  46.      while(busy());
  47.      rs=0;
  48.      rw=0;
  49.      lcden=0;
  50.      _nop_();
  51.      P0=cmd;
  52.      delayNOP();
  53.      lcden=1;
  54.      delayNOP();
  55.      lcden=0;
  56. }


  57. void lcd_pos(uchar pos)
  58. {                            //設定顯示位置
  59.      lcd_com(pos|0x80);  //數(shù)據(jù)指針=80+地址變量
  60. }


  61. /*寫顯示數(shù)據(jù)到LCD    RS=H,RW=L,E=高脈沖,D0-D7=數(shù)據(jù)。*/


  62. void lcd_dat(uchar dat)
  63. {
  64.      while(busy());
  65.      rs=1;
  66.      rw=0;
  67.      lcden=0;
  68.      P0=dat;
  69.      delayNOP();
  70.      lcden=1;
  71.      delayNOP();
  72.      lcden=0;
  73. }


  74. /*LCD初始化設定*/


  75. void lcd_init()
  76. {        
  77.          delay(15);
  78.          lcd_com(0x38);//16*2顯示,5*7點陣,8位數(shù)據(jù)
  79.          delay(5);//延時
  80.          lcd_com(ox38);
  81.          delay(5);
  82.          lcd_com(ox38);
  83.          delay(5);


  84.          lcd_com(0x0c);     //顯示開,關光標
  85.          delay(5);
  86.          lcd_com(0x38);     //移動光標
  87.          delay(5);
  88.          lcd_com(0x38);     //清除LCD的顯示內容
  89.          delay(5);
  90. }


  91. /* LCD 顯示 */


  92. void display()
  93. {
  94.      uchar a=0;
  95.      lcd_pos(0);
  96.      delay(30);
  97.      while(table[a]!='\0');   //判斷下一位是否為空
  98.      {
  99.         lcd_dat(table[a]);   //顯示字符
  100.         a++;
  101.         if(a==16)
  102.         {
  103.             lcd_pos(0x40);  //設置顯示位置為第二行第1個字符
  104.         }
  105.      }
  106. }
  107. void keyscan()
  108. {
  109.      temp=0;
  110.      P1=0xf0;                   //高四位輸入   行為高電平  列為低電平
  111.      delay(50);
  112.      temp=P1;
  113.      temp=temp&0xf0;            //屏蔽低四位
  114.      temp=~((temp>>4)0|xF0);
  115.      if(temp==1)                //p1.4被拉低
  116.          key=0;
  117.      else if(temp==2)           //p1.5被拉低
  118.          key=1;
  119.      else if(temp==4)           //p1.6被拉低
  120.          key=2;
  121.      else if(temp==8)           //p1.7被拉低
  122.          key=3;
  123.      else
  124.          key=16;


  125.      P1=0x0f;                   //低四位輸入  列為高電平 行為低電平
  126.      delay(50);              
  127.      temp=P1;                   //讀P1口
  128.      temp=temp&0xf0;            
  129.      temp=~(temp|0xf0);
  130.      if(temp==2)                //p1.1被拉低
  131.          key=key+0;
  132.      else if(temp==4)           //p1.2被拉低
  133.          key=key+4;
  134.      else if(temp==8)           //p1.3被拉低
  135.          key=key+8;

  136.      else
  137.          key=16;
  138.          P1=0x0f;                                 
  139.          temp=P1;                  


  140.          if(key==0)   //以下是判斷按鍵,顯示相應的號碼
  141.          {
  142.              table[num]='1';
  143.                  num++;
  144.          }
  145.          if(key==1)
  146.          {
  147.              table[num]='2';
  148.                  num++;
  149.          }
  150.          if(key==2)
  151.          {
  152.              table[num]='3';
  153.                  num++;
  154.          }
  155.          if(key==3)
  156.          {
  157.              table[num]='4';
  158.                  num++;
  159.          }
  160.          if(key==4)
  161.          {
  162.              table[num]='5';
  163.                  num++;
  164.          }
  165.          if(key==5)
  166.          {
  167.              table[num]='6';
  168.                  num++;
  169.          }


  170.          if(key==6)
  171.          {
  172.              table[num]='7';
  173.                  num++;
  174.          }
  175.          if(key==7)
  176.          {
  177.              table[num]='8';
  178.                  num++;
  179.          }

  180.          if(key==8)
  181.          {
  182.              table[num]='9';
  183.                  num++;
  184.          }
  185.          if(key==9)
  186.          {
  187.              table[num]='0';
  188.                  num++;
  189.          }

  190.          if(key==10)
  191.          {
  192.              table[--num]='\0';         //刪除上一位
  193.              lcd_com(oxo1);             //清除LCD的所有顯示內容
  194.          }
  195.          if(key==11)
  196.          {
  197.               while(table[a]!='\0')
  198.                {
  199.                  if(num==17)
  200.                  {
  201.                       tab[a]=SBUF=table[a];          //顯示輸入數(shù)據(jù)
  202.                       while(!TI);                    //等特數(shù)據(jù)傳送
  203.                            TI=0;                          //清除數(shù)據(jù)傳送標志
  204.                       a++;
  205.                  }
  206.                  else
  207.                  {                                   //發(fā)送下一位字符
  208.                       tab[a]=SBUF=erro[a];           //顯示輸入數(shù)據(jù)
  209.                       while(!TI);                    //等特數(shù)據(jù)傳送
  210.                       TI=0;                         //清除數(shù)據(jù)傳送標志
  211.                       a++;
  212.                  }
  213.           }

  214.      }
  215. }



  216. /*   串口初始化  */


  217. void uart_int()
  218. {
  219.       TMOD=0x20;   //工作方式2,為常數(shù)自動重新裝入的8位定時器
  220.       TH1=0xf3;     //裝定時器初值
  221.       TL1=0xf3;
  222.       TR1=1;      //開啟定時器1
  223.       SM0=0;      //串口方式0
  224.       SM1=1;     //串口方式1
  225.       REN=1;     //允許接收
  226.       ES=1;      //是開啟串口中斷
  227.       EA=1;      //開中斷總開關
  228. }
  229. void main()
  230. {
  231.       uart_int();
  232.       lcd_int();
  233.       while(num<=17)
  234. {
  235.       keyscan();                  //鍵盤掃描
  236.       display();                  //LCD顯示
  237.       if(receive[4]=='E')       //判斷PC機返回的是否是ATD+ERR
  238.       {
  239.           P2=0xfe;
  240.           while(tab[a]!='\0')
  241.           {
  242.              SBUF=tab[a];         //串口發(fā)送
  243.              while(!TI);          //等特數(shù)據(jù)傳送(TI發(fā)送中斷標志)
  244.              TI=0;                       //清除數(shù)據(jù)傳送標志
  245.              a++;                        //下一個字符
  246.            }
  247.              a=0;


  248.             receive[4]='\0';  // PC機返回ATD+OK
  249.        }

  250.        else if(receive[4]=='0')  //判斷PC機返回的是否是ATD+OK
  251.        {
  252.              P2=0xfd;
  253.              receive[4]='\0';
  254.        }
  255.        if((receive[5]='K'||(receive[6]=='R')) //判斷PC機返回的是否是ATD+K或ATD+R
  256.        {
  257.           b=0;
  258.           receive[5]='\0';  //PC機返回ATD+OK
  259.           receive[6]='\0';
  260.        }
  261.     }
  262. }


  263. /*  串口接收  */


  264. void ser() interrupt 4  //串行口中斷子函數(shù)

  265. {
  266.       if(RI==1)    //中斷允許標志位,為0時允許
  267.       {
  268.           receive[ b]=SBUF;
  269.           b++;
  270.           RI=0;
  271.       }
  272. }
復制代碼







歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1