找回密码
 立即注册

QQ登录

只需一步,快速开始

帖子
查看: 3084|回复: 0
打印 上一主题 下一主题
收起左侧

51单片机电话键盘拨号

[复制链接]
跳转到指定楼层
楼主
ID:268029 发表于 2017-12-27 21:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. #include<reg51.h> // 包含单片机寄存器的头文件
  2. #include<intrins.h>//包含_nop_()函数定义的头文件
  3. typedef unsigned int uint;
  4. typedef unsigned char uchar;
  5. uchar  temp;
  6. uchar  key=16;
  7. sbit rs=P2^0;  //LCD1602数据/命令选择
  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所显示的号码缓存数组
  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发送,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忙状态 */
  30. /*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据 */

  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. /*写指令数据到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);  //数据指针=80+地址变量
  60. }


  61. /*写显示数据到LCD    RS=H,RW=L,E=高脉冲,D0-D7=数据。*/


  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位数据
  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];          //显示输入数据
  202.                       while(!TI);                    //等特数据传送
  203.                            TI=0;                          //清除数据传送标志
  204.                       a++;
  205.                  }
  206.                  else
  207.                  {                                   //发送下一位字符
  208.                       tab[a]=SBUF=erro[a];           //显示输入数据
  209.                       while(!TI);                    //等特数据传送
  210.                       TI=0;                         //清除数据传送标志
  211.                       a++;
  212.                  }
  213.           }

  214.      }
  215. }



  216. /*   串口初始化  */


  217. void uart_int()
  218. {
  219.       TMOD=0x20;   //工作方式2,为常数自动重新装入的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];         //串口发送
  243.              while(!TI);          //等特数据传送(TI发送中断标志)
  244.              TI=0;                       //清除数据传送标志
  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  //串行口中断子函数

  265. {
  266.       if(RI==1)    //中断允许标志位,为0时允许
  267.       {
  268.           receive[ b]=SBUF;
  269.           b++;
  270.           RI=0;
  271.       }
  272. }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表