找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 13647|回复: 25
收起左侧

单片机+TC35 GSM模块的手机制作与设计全套资料下载 含仿真 PCB 原理图 程序

  [复制链接]
ID:203115 发表于 2017-5-21 13:21 | 显示全部楼层 |阅读模式
借助系统模型,阐明基于西门子公司的TC35型GSM手机模块收发短信、打电话的基本概念以及串口控制 SMS 的基本原理。详细介绍C51单片机STC12C5A32S2控制GSM 模块工作的软件实现过程,对怎样用单片机控制GSM 模块收发短信、打电话进行探讨,也对程序设计的主体思想作了较为细致的分析。

文章重点阐述了STC12C5A32S2单片机和TC35模块的接口、TC35的特点和主要功能、AT指令的应用等。该系统单片机STC12C5A32S2的TXD/RXD分别接TC35模块的TXD/RXD,完成对TC35模块的初始化和短消息的数据收发以及打电话的功能。

这个是制作成功的实物图:
0.png

压缩包里面含完整的PCB图 proteus仿真原理图和源程序程序等
0.png

单片机源程序如下:
  1. #include <reg52.h>
  2. #include <absacc.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <math.h>
  6. #include <stdlib.h>
  7. #include <intrins.h>
  8. #define uint unsigned int
  9. #define uchar unsigned char

  10. #define lcd_data_port P0   //定义与1602LCD的数据口的单片机口线
  11. sbit lcden=P2^5;        // lcd使能
  12. sbit lcdrs=P2^3;        // lcd读
  13. sbit lcdrw=P2^4;        // lcd写
  14. sbit beep=P2^2;//蜂鸣器

  15. void delayms(uint x);
  16. void lcd_write_com(uchar lcd_com);   //送命令数据到LCD的子函数声明
  17. void lcd_write_data(uchar lcd_data); //送显示数据到LCD的子函数声明
  18. void lcd_int();                      //LCD初始化子函数声明

  19. void write_sfm(uchar wz,uchar date);//在第一行写一个数函数
  20. #define key_4x4_port P1             //定义4x4键盘使用的单片机端口
  21. uchar key;                        //4x4键盘扫描所得的键值保存到这里
  22. void key_4x4_scan();    //声明4x4键盘扫描子函数,得到的键值送至全局变量key

  23. #define Phone_connection  1    //正在打电话状态标志
  24. #define Clear_Connect     0    //电话已挂断状态标志
  25. char Calls_State_Flag=Clear_Connect;   //电话状态  
  26. void ScanMessage(void);
  27. void clr_rsbuf(void);

  28. uchar code AT[]="AT\r" ;                             //握手信号   
  29. uchar code AT_CMGF[]= "AT+CMGF=1\r";//发送数据为TXET格式
  30. uchar code AT_CMGS[]= "AT+CMGS=15994473659\r";  
  31. uchar code AT_CMGR[]= "AT+CMGR=2\r";
  32. uchar code AT_CSCA[]="AT+CSCA=\"+8613800771500\""; //设置服务中心号码     
  33. uchar code AT_CNMI[]= "AT+CNMI=2,1,0,0\r";//新消息提示:设置为mode=2,mt=1
  34. uchar code AT_CLIP[]= "AT+CLIP=1,1\r";//显示来电号码                  
  35. uchar Sms[]="hello!";
  36. uchar Phone_call[]="15994473659";
  37. uchar Phone_num[12];
  38. uchar RsPoint=0;
  39. uchar RsBuf[100];
  40. uchar j=0;
  41. uint i, k,ii;
  42. void di()
  43. {
  44.     beep=0;
  45.     delayms(250);
  46.         beep=1;
  47. }
  48. /*-------------------------------------------------------------------------------------------*/

  49. void delayms(uint x)//延时
  50. {
  51.         uint i,j;
  52.         for(i=x;i>0;i--)
  53.                 for(j=110;j>0;j--);
  54. }
  55. /***********************************************************
  56. 函数名称:Print_Char
  57. 函数功能:发送单个字符     
  58.           入口参数:ch      出口参数:无
  59. ***********************************************************/
  60. void Print_Char(uchar ch)//发送单个字符
  61. {
  62. SBUF=ch; //送入缓冲区
  63. while(TI==0); //等待发送完毕
  64. TI=0; //软件清零
  65. }
  66. /***********************************************************
  67. 函数名称:Print_Str
  68. 函数功能:发送字符串     
  69.           入口参数:*str    出口参数:无
  70. ***********************************************************/
  71. void Print_Str(uchar *str)//发送字符串   
  72. {

  73. while(*str!='\0')
  74. {
  75. Print_Char(*str++);
  76.     }
  77. }
  78. void clr_rsbuf(void)//清空接收缓存   
  79. {
  80. for(RsPoint=0;RsPoint<100;RsPoint++)
  81. {
  82. RsBuf[RsPoint]=0x00;
  83. }
  84. RsPoint=0;
  85. }
  86. void ser()interrupt 4
  87. {
  88.          if(RI==1)
  89.   {
  90.     RI=0;
  91.     RsBuf[RsPoint++]=SBUF;
  92.     if (RsPoint>=sizeof(RsBuf))
  93.     {
  94.     RsPoint=0;//FlagRs485=0;
  95.     }  //????
  96.   }
  97. }
  98. /***********************************************************
  99. 函数名称:Ini_UART
  100. 函数功能:串口初始化、定时器初始化     
  101.           入口参数:无     出口参数:无
  102. ***********************************************************/
  103. Ini_UART(void)//串口初始化、定时器初始化
  104. {
  105. TMOD = 0x20;      //T1方式2,用于UART波特率     
  106. TH1 = 0xFD;       //UART波特率设置:9600     
  107. TL1 = 0xFD;
  108. SCON = 0x50;  ////UART方式1:8位UART;   REN=1:允许接收   
  109. PCON = 0x00;

  110. TF1 = 1;     // 中断标志位
  111. TR1 = 1;    // 启动定时器1   
  112. ES=1;       //启动串行口中断
  113. ET0=1;      //启动中断功能
  114. EA=1;
  115. }
  116. /***********************************************************
  117. 函数名称:main
  118. 函数功能:主函数
  119. ***********************************************************/
  120. void main()
  121. {      
  122.        di();
  123.        Ini_UART();
  124.        lcd_int();
  125.            k=0;
  126.        Print_Str(AT);  
  127.        delayms(100);
  128.        Print_Str(AT_CMGF);
  129.        delayms(100);
  130.        Print_Str(AT_CNMI);
  131.        delayms(200);
  132.        Print_Str(AT_CLIP);
  133.        delayms(250);
  134.            clr_rsbuf();
  135.        P1=0xff;  //P0开机初始化   
  136.        key=0xff; //键盘值开机初始化为ff(检测到的键值应为0----15)   
  137.        while(1)
  138.            {  
  139.            ScanMessage();
  140.                key_4x4_scan();//不停调用键盘扫描程序            
  141.             };//原地循环     
  142. }
  143. void ScanMessage(void)
  144. {
  145.         for(ii=0;ii<32;ii++)  
  146.                 if(RsBuf[ii-3]=='C'&&RsBuf[ii-2]=='M'&&RsBuf[ii-1]=='T'&&RsBuf[ii]=='I')
  147.             {
  148.                  di();
  149.              delayms(50);
  150.              di();
  151.              delayms(50);
  152.              di();
  153.              delayms(50);
  154.              lcd_write_com(0x80);   //将要显示的位置定位在LCD的第一行第0个字符处
  155.              clr_rsbuf();
  156.              Print_Str(AT_CMGR);  
  157.              delayms(250);delayms(250);delayms(250);delayms(250);
  158.              lcd_write_com(0x80);   //将要显示的位置定位在LCD的第一行第0个字符处
  159.              for(i=0;i<15;i++)
  160.              {
  161.                       lcd_write_data(RsBuf[i+20]);    //显示
  162.               delayms(100);
  163.              }
  164.              lcd_write_com(0x80+0x40);   //将要显示的位置定位在LCD的第一行第0个字符处
  165.              for(i=15;i<32;i++)
  166.              {
  167.                       lcd_write_data(RsBuf[i+20]);    //显示
  168.               delayms(100);
  169.              }
  170.                 }
  171.                  else if(RsBuf[ii-3]=='C'&&RsBuf[ii-2]=='L'&&RsBuf[ii-1]=='I'&&RsBuf[ii]=='P')
  172.          {
  173.                  beep=0;
  174.              delayms(250);
  175.              delayms(250);
  176.              lcd_write_com(0x80);   //将要显示的位置定位在LCD的第一行第0个字符处
  177.              for(i=(ii+3);i<15+(ii+3);i++)
  178.              {
  179.                         lcd_write_data(RsBuf[i]);    //来电显示
  180.                 delayms(5);
  181.               }
  182.              lcd_write_com(0x80+0x40);   //将要显示的位置定位在LCD的第一行第0个字符处
  183.              for(i=(ii+3)+15;i<32+(ii+3);i++)
  184.              {
  185.                         lcd_write_data(RsBuf[i]);    //显示"ATH"
  186.                 delayms(5);
  187.               }
  188.                          while(!beep)
  189.                          {
  190.                          key_4x4_scan();//不停调用键盘扫描程序
  191.                        }                        
  192.                          clr_rsbuf();
  193.                  }
  194. }
  195. /***********************************************************
  196. 函数名称:phone
  197. 函数功能:拨打目标电话      
  198.           入口参数:无     出口参数:无
  199. ***********************************************************/
  200. void phone()    //打电话函数   
  201. {  
  202.          uchar ATD1[]="ATD"; //拨
  203.      uchar ATD3[]=";\r";
  204.      uchar ATDINTOL[25];
  205.      strcpy(ATDINTOL,ATD1);
  206.      strcat(ATDINTOL,Phone_num); //EEE   
  207.      strcat(ATDINTOL,ATD3);
  208.      Print_Str(ATDINTOL);
  209.      delayms(250);   delayms(250);   
  210. }
  211. /***********************************************************
  212. 函数名称:GSM_ATH
  213. 函数功能:挂电话      
  214.           入口参数:无     出口参数:无
  215. ***********************************************************/
  216. void GSM_ATH()   
  217. {   
  218.      Print_Str("ATH"); //发送挂电话指令  
  219.      Print_Str("\r");   //发送回车   
  220.      delayms(250);delayms(250);delayms(250);delayms(250);
  221. }         
  222. /***********************************************************
  223. 函数名称:Rphone
  224. 函数功能:接听目标电话      
  225.           入口参数:无     出口参数:无
  226. ***********************************************************/
  227. void Rphone()    //接听电话函数
  228. {  
  229.          Print_Str("ATA");
  230.      Print_Str("\r");   //发送回车
  231.      delayms(250);delayms(250);delayms(250);delayms(250);     
  232. }
  233. /***********************************************************
  234. 函数名称:GSM_TEXT
  235. 函数功能:设置发送数据为TXET格式      
  236.           入口参数:无     出口参数:无
  237. ***********************************************************/
  238. //void GSM_TEXT()   //设置GSM为TEXT格式
  239. //{   
  240. //     Print_Str(AT_CMGF);   //发送设置指令
  241. //     ES=1;
  242. //         delayms(250);delayms(250);
  243. //}
  244. /***********************************************************
  245. 函数名称:GSM_TEXT_SMS
  246. 函数功能:发送数据为TXET格式的短信内容      
  247.           入口参数:无     出口参数:无
  248. ***********************************************************/
  249. void GSM_TEXT_SMS()  //发送TEXT格式内容   
  250. {      
  251.      Print_Str(AT_CMGS);
  252.          Print_Str(Phone_call);
  253.      Print_Str("\r");
  254.      delayms(200);
  255.      Print_Str(Sms);
  256.      Print_Char(0x1A);  //发送短息内容结束符对应的ASCII为0x1a
  257.          ES=1;
  258.      delayms(250);delayms(250);
  259. }
  260. /***********************************************************
  261. LCD相关函数定义
  262. ***********************************************************/
  263. //-----------------------------------------
  264. void lcd_write_com(uchar lcd_com)   //LCD送命令子函数
  265. {
  266.   lcdrs=0;
  267.   lcd_data_port=lcd_com;
  268.   delayms(5);
  269.   lcden=1;
  270.   delayms(5);
  271.   lcden=0;
  272. }
  273. //-----------------------------------------
  274. void lcd_write_data(uchar lcd_data)  //LCD送显示数据子函数
  275. {
  276.   lcdrs=1;
  277.   lcd_data_port=lcd_data;
  278.   delayms(5);
  279.   lcden=1;
  280.   delayms(5);
  281.   lcden=0;
  282. }
  283. //-----------------------------------------
  284. void lcd_int()                 //LCD初始化子函数
  285. {
  286.   lcdrw=0;
  287.   lcden=0;
  288.   lcd_write_com(0x38);  //设置LCD工作于16x2、5x7点阵、8位数据接口模式
  289.   lcd_write_com(0x0c);  //开显示,不显示光标
  290.   lcd_write_com(0x06);  //写一个字符后地址指针自动加1
  291.   lcd_write_com(0x01);  //清屏
  292. }
  293. //----------------------------------------------------------------
  294. //-----------------------------------------
  295. void write_sfm(uchar wz,uchar date)             //在第一行写一个数函数
  296. {
  297.              lcd_write_com(0x80+wz);                  //设置显示位置
  298.                 lcd_write_data(0x30+date);  
  299. }
  300. /*-------------------------------------------------------------------------------------------*/
  301. //-----------------------------------------
  302. void key_4x4_scan()                    //4x4键盘扫描子函数,得到的键值送至全局变量key
  303. {      
  304.     uchar temp ;
  305.     key_4x4_port=0xfe;           //送出最低位0电平去扫描
  306.     temp=key_4x4_port;           //读出整个口的得到的值
  307.     temp=temp&0xf0;                   //屏蔽低4位
  308.     if(temp!=0xf0)                   //假如高4位不是全1
  309.     {
  310.           delayms(10);                   //延时消抖再读
  311.           temp=key_4x4_port;
  312.           temp=temp&0xf0;
  313.          if(temp!=0xf0)           //消抖后如果再次确定高4位不是全1
  314.         {
  315.           temp=key_4x4_port; //读出此次按键的值
  316.           switch(temp)
  317.            {
  318.          ///////////////拨打电话按键////////////////////////////   
  319.                      case 0xee:  key=0;
  320.                          lcd_write_com(0x01);  //清屏
  321.              clr_rsbuf();
  322.              phone();  //拨打电话
  323.              lcd_write_com(0x80);   //将要显示的位置定位在LCD的第一行第0个字符处
  324.              for(i=0;i<32;i++)
  325.              {
  326.                       lcd_write_data(RsBuf[i]);    //显示
  327.               delayms(50);
  328.              }
  329.              delayms(250);
  330.              Calls_State_Flag=Clear_Connect;   
  331.                          break;   //11101110
  332.                  ///////////////挂电话按键//////////////////////////
  333.              case 0xde:  key=1;
  334.                          lcd_write_com(0x01);  //清屏
  335.              clr_rsbuf();
  336.              GSM_ATH(); //发送挂电话指令
  337.              beep=1;
  338.                          lcd_write_com(0x80);   //将要显示的位置定位在LCD的第一行第0个字符处
  339.              for(i=0;i<32;i++)
  340.              {
  341.                       lcd_write_data(RsBuf[i]);    //
  342.               delayms(50);
  343.              }
  344.              delayms(250);
  345.              Calls_State_Flag=Phone_connection;
  346.                          break;   //11011110
  347.         ////////////////TEXT格式及TEXT格式内容///////////////////////////////
  348.              case 0xbe:  key=2;
  349.                          lcd_write_com(0x01);  //清屏
  350.                          clr_rsbuf();
  351.              //GSM_TEXT();//设置GSM为TEXT格式
  352.                      GSM_TEXT_SMS();//发送TEXT格式内容
  353.              lcd_write_com(0x80);   //将要显示的位置定位在LCD的第一行第0个字符处
  354.              for(i=0;i<15;i++)
  355.              {
  356.                       lcd_write_data(RsBuf[i]);    //显示
  357.               delayms(100);
  358.              }
  359.              for(i=15;i<32;i++)
  360.              {
  361.                       lcd_write_data(RsBuf[i]);    //显示
  362.               delayms(100);
  363.              }
  364.              delayms(250);
  365.              delayms(250);
  366.              break;   //10111110
  367.            ///////////////0号键////////////////////////////////
  368.              case 0x7e:  key=3;
  369.                       lcd_write_com(0x80);   //将要显示的位置定位在LCD的第一行第0个字符处
  370.              Phone_num[k++]=0x30;
  371.                          write_sfm((j+1),0);
  372.                          j=j+1;
  373.              break;   //01111110
  374.             }
  375.          while(temp!=0xf0)          //等待按键放开
  376.          { temp=key_4x4_port;
  377.            temp=temp&0xf0;
  378.          }
  379.       }
  380.     }
  381.     key_4x4_port=0xfd;  //11111101
  382.     temp=key_4x4_port;
  383.     temp=temp&0xf0;
  384.     if(temp!=0xf0)
  385.     { delayms(10);
  386.       temp=key_4x4_port;
  387.       temp=temp&0xf0;
  388.       if(temp!=0xf0)
  389.       {        temp=key_4x4_port;
  390.         switch(temp)
  391.         {
  392.                ///////////////接听电话按键////////////////////////////////   
  393.                      case 0xed:   key=4;
  394.              lcd_write_com(0x01);  //清屏
  395.              clr_rsbuf();
  396.              Rphone();  //接听电话            
  397.              beep=1;
  398.              lcd_write_com(0x80);   //将要显示的位置定位在LCD的第一行第0个字符处
  399.              for(i=0;i<32;i++)
  400.              {
  401.                       lcd_write_data(RsBuf[i]);    //显示
  402.               delayms(50);
  403.              }
  404.                          delayms(250);delayms(250);
  405.                          break;   //11101101
  406.         ////////////////7号键////////////////////////////////
  407.              case 0xdd:   key=5;
  408.                          Phone_num[k++]=0x37;
  409.                          write_sfm((j+1),7);
  410.                          j=j+1;
  411.                          break;   //11011101
  412.             /////////////////4号键///////////////////////////////
  413.              case 0xbd:   key=0x36;
  414.                         Phone_num[k++]=0x34;
  415.                          write_sfm((j+1),4);
  416.                          j=j+1;break;   //10111101
  417.             ////////////////1号键////////////////////////////////
  418.                         Phone_num[k++]=0x31;
  419.              case 0x7d:   key=7;
  420.                          write_sfm((j+1),1);
  421.                      j=j+1; break;   //01111101
  422.          }
  423.          while(temp!=0xf0)
  424.          { temp=key_4x4_port;
  425.            temp=temp&0xf0;
  426.          }
  427.       }
  428.       }
  429.     key_4x4_port=0xfb;  //11111011
  430.     temp=key_4x4_port;
  431.     temp=temp&0xf0;
  432.     if(temp!=0xf0)
  433.     { delayms(250);delayms(250);delayms(250);delayms(250);
  434.              temp=key_4x4_port;
  435.       temp=temp&0xf0;
  436.       if(temp!=0xf0)
  437.       { temp=key_4x4_port;
  438.         switch(temp)
  439.         {
  440.            //////////////清屏按键//////////////////////////
  441.                      case 0xeb:  key=8;
  442.              lcd_write_com(0x01);  //清屏
  443.              j=0;k=0;
  444.                          break;  //11101011
  445.           ///////////////8号键//////////////////////////
  446.              case 0xdb:  key=9;
  447.                          Phone_num[k++]=0x38;
  448.                          write_sfm((j+1),8);
  449.                      j=j+1;break;  //11011011
  450. ……………………

  451. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

文档预览:http://www.51hei.com/bbs/dpj-85499-1.html

全部资料打包下载地址:
基于GSM的手机设计.7z (1.55 MB, 下载次数: 542)
回复

使用道具 举报

ID:1 发表于 2017-5-21 17:33 | 显示全部楼层
好资料,51黑有你更精彩!!!
回复

使用道具 举报

ID:185367 发表于 2017-5-21 17:41 | 显示全部楼层
看看这个,换一下思路,很有帮助。
回复

使用道具 举报

ID:157057 发表于 2017-5-21 23:19 | 显示全部楼层
好资料,51黑有你更精彩!!!
回复

使用道具 举报

ID:94068 发表于 2017-6-8 11:03 | 显示全部楼层
很好的设计资料,赞一个!
回复

使用道具 举报

ID:297505 发表于 2018-3-26 22:07 | 显示全部楼层
好资料啊  正想用单片机做个手机玩玩
回复

使用道具 举报

ID:96011 发表于 2018-4-22 16:07 | 显示全部楼层
666厉害,谢谢大神
回复

使用道具 举报

ID:295874 发表于 2018-5-23 09:19 | 显示全部楼层
实际仿真无法进行,进行时LCD显示数据不正常。
回复

使用道具 举报

ID:336367 发表于 2018-5-23 11:41 | 显示全部楼层
厉害了
回复

使用道具 举报

ID:336367 发表于 2018-5-23 11:42 | 显示全部楼层
这是个简易版手机吗
回复

使用道具 举报

ID:294865 发表于 2018-5-23 16:05 | 显示全部楼层
学习一下
回复

使用道具 举报

ID:363261 发表于 2018-7-2 16:00 | 显示全部楼层
非常感谢,下载学习一下
回复

使用道具 举报

ID:202314 发表于 2018-7-24 06:14 | 显示全部楼层
好资料 谢谢分享
回复

使用道具 举报

ID:390236 发表于 2018-8-26 22:03 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:468297 发表于 2019-1-19 18:19 | 显示全部楼层
好资料,谢谢分享。
回复

使用道具 举报

ID:412558 发表于 2019-3-22 22:14 | 显示全部楼层
好东西啊,点赞
回复

使用道具 举报

ID:696981 发表于 2020-2-23 15:47 | 显示全部楼层
好棒好棒
回复

使用道具 举报

ID:654774 发表于 2020-3-22 10:07 来自手机 | 显示全部楼层
怎么下载呀?
回复

使用道具 举报

ID:630491 发表于 2020-4-1 13:44 | 显示全部楼层
大神啊!膜拜了
回复

使用道具 举报

ID:630491 发表于 2020-4-1 14:42 | 显示全部楼层
liyongan_1985 发表于 2018-5-23 09:19
实际仿真无法进行,进行时LCD显示数据不正常。

我推荐不要用仿真!任何业内人士都不推荐!我觉得你要是喜欢它,你就可以做一个出来,这样你才会真正学会mcu
回复

使用道具 举报

ID:630491 发表于 2020-4-16 13:14 | 显示全部楼层
加一个麦克风就可以真的用来通话了,还可以改成用arm单片机,那样就可以和市面上的手机媲美了
回复

使用道具 举报

ID:730707 发表于 2020-4-16 16:45 | 显示全部楼层
好资料,51黑有你更精彩!!!
回复

使用道具 举报

ID:247907 发表于 2020-5-26 23:43 来自手机 | 显示全部楼层
真是厉害,不错
回复

使用道具 举报

ID:727538 发表于 2020-5-30 10:00 | 显示全部楼层
哇哇哇,这个资料太棒了,感谢大神
回复

使用道具 举报

ID:517951 发表于 2020-11-15 17:45 | 显示全部楼层
不错,值得学习。51hei有你更精彩!!
回复

使用道具 举报

ID:647404 发表于 2020-12-7 09:07 | 显示全部楼层
好东西以后用来参考
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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