借助系统模型,阐明基于西门子公司的TC35型GSM手机模块收发短信、打电话的基本概念以及串口控制 SMS 的基本原理。详细介绍C51单片机STC12C5A32S2控制GSM 模块工作的软件实现过程,对怎样用单片机控制GSM 模块收发短信、打电话进行探讨,也对程序设计的主体思想作了较为细致的分析。
文章重点阐述了STC12C5A32S2单片机和TC35模块的接口、TC35的特点和主要功能、AT指令的应用等。该系统单片机STC12C5A32S2的TXD/RXD分别接TC35模块的TXD/RXD,完成对TC35模块的初始化和短消息的数据收发以及打电话的功能。
这个是制作成功的实物图:
压缩包里面含完整的PCB图 proteus仿真原理图和源程序程序等
单片机源程序如下:
- #include <reg52.h>
- #include <absacc.h>
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
- #include <stdlib.h>
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- #define lcd_data_port P0 //定义与1602LCD的数据口的单片机口线
- sbit lcden=P2^5; // lcd使能
- sbit lcdrs=P2^3; // lcd读
- sbit lcdrw=P2^4; // lcd写
- sbit beep=P2^2;//蜂鸣器
- void delayms(uint x);
- void lcd_write_com(uchar lcd_com); //送命令数据到LCD的子函数声明
- void lcd_write_data(uchar lcd_data); //送显示数据到LCD的子函数声明
- void lcd_int(); //LCD初始化子函数声明
- void write_sfm(uchar wz,uchar date);//在第一行写一个数函数
- #define key_4x4_port P1 //定义4x4键盘使用的单片机端口
- uchar key; //4x4键盘扫描所得的键值保存到这里
- void key_4x4_scan(); //声明4x4键盘扫描子函数,得到的键值送至全局变量key
- #define Phone_connection 1 //正在打电话状态标志
- #define Clear_Connect 0 //电话已挂断状态标志
- char Calls_State_Flag=Clear_Connect; //电话状态
- void ScanMessage(void);
- void clr_rsbuf(void);
- uchar code AT[]="AT\r" ; //握手信号
- uchar code AT_CMGF[]= "AT+CMGF=1\r";//发送数据为TXET格式
- uchar code AT_CMGS[]= "AT+CMGS=15994473659\r";
- uchar code AT_CMGR[]= "AT+CMGR=2\r";
- uchar code AT_CSCA[]="AT+CSCA=\"+8613800771500\""; //设置服务中心号码
- uchar code AT_CNMI[]= "AT+CNMI=2,1,0,0\r";//新消息提示:设置为mode=2,mt=1
- uchar code AT_CLIP[]= "AT+CLIP=1,1\r";//显示来电号码
- uchar Sms[]="hello!";
- uchar Phone_call[]="15994473659";
- uchar Phone_num[12];
- uchar RsPoint=0;
- uchar RsBuf[100];
- uchar j=0;
- uint i, k,ii;
- void di()
- {
- beep=0;
- delayms(250);
- beep=1;
- }
- /*-------------------------------------------------------------------------------------------*/
- void delayms(uint x)//延时
- {
- uint i,j;
- for(i=x;i>0;i--)
- for(j=110;j>0;j--);
- }
- /***********************************************************
- 函数名称:Print_Char
- 函数功能:发送单个字符
- 入口参数:ch 出口参数:无
- ***********************************************************/
- void Print_Char(uchar ch)//发送单个字符
- {
- SBUF=ch; //送入缓冲区
- while(TI==0); //等待发送完毕
- TI=0; //软件清零
- }
- /***********************************************************
- 函数名称:Print_Str
- 函数功能:发送字符串
- 入口参数:*str 出口参数:无
- ***********************************************************/
- void Print_Str(uchar *str)//发送字符串
- {
- while(*str!='\0')
- {
- Print_Char(*str++);
- }
- }
- void clr_rsbuf(void)//清空接收缓存
- {
- for(RsPoint=0;RsPoint<100;RsPoint++)
- {
- RsBuf[RsPoint]=0x00;
- }
- RsPoint=0;
- }
- void ser()interrupt 4
- {
- if(RI==1)
- {
- RI=0;
- RsBuf[RsPoint++]=SBUF;
- if (RsPoint>=sizeof(RsBuf))
- {
- RsPoint=0;//FlagRs485=0;
- } //????
- }
- }
- /***********************************************************
- 函数名称:Ini_UART
- 函数功能:串口初始化、定时器初始化
- 入口参数:无 出口参数:无
- ***********************************************************/
- Ini_UART(void)//串口初始化、定时器初始化
- {
- TMOD = 0x20; //T1方式2,用于UART波特率
- TH1 = 0xFD; //UART波特率设置:9600
- TL1 = 0xFD;
- SCON = 0x50; ////UART方式1:8位UART; REN=1:允许接收
- PCON = 0x00;
- TF1 = 1; // 中断标志位
- TR1 = 1; // 启动定时器1
- ES=1; //启动串行口中断
- ET0=1; //启动中断功能
- EA=1;
- }
- /***********************************************************
- 函数名称:main
- 函数功能:主函数
- ***********************************************************/
- void main()
- {
- di();
- Ini_UART();
- lcd_int();
- k=0;
- Print_Str(AT);
- delayms(100);
- Print_Str(AT_CMGF);
- delayms(100);
- Print_Str(AT_CNMI);
- delayms(200);
- Print_Str(AT_CLIP);
- delayms(250);
- clr_rsbuf();
- P1=0xff; //P0开机初始化
- key=0xff; //键盘值开机初始化为ff(检测到的键值应为0----15)
- while(1)
- {
- ScanMessage();
- key_4x4_scan();//不停调用键盘扫描程序
- };//原地循环
- }
- void ScanMessage(void)
- {
- for(ii=0;ii<32;ii++)
- if(RsBuf[ii-3]=='C'&&RsBuf[ii-2]=='M'&&RsBuf[ii-1]=='T'&&RsBuf[ii]=='I')
- {
- di();
- delayms(50);
- di();
- delayms(50);
- di();
- delayms(50);
- lcd_write_com(0x80); //将要显示的位置定位在LCD的第一行第0个字符处
- clr_rsbuf();
- Print_Str(AT_CMGR);
- delayms(250);delayms(250);delayms(250);delayms(250);
- lcd_write_com(0x80); //将要显示的位置定位在LCD的第一行第0个字符处
- for(i=0;i<15;i++)
- {
- lcd_write_data(RsBuf[i+20]); //显示
- delayms(100);
- }
- lcd_write_com(0x80+0x40); //将要显示的位置定位在LCD的第一行第0个字符处
- for(i=15;i<32;i++)
- {
- lcd_write_data(RsBuf[i+20]); //显示
- delayms(100);
- }
- }
- else if(RsBuf[ii-3]=='C'&&RsBuf[ii-2]=='L'&&RsBuf[ii-1]=='I'&&RsBuf[ii]=='P')
- {
- beep=0;
- delayms(250);
- delayms(250);
- lcd_write_com(0x80); //将要显示的位置定位在LCD的第一行第0个字符处
- for(i=(ii+3);i<15+(ii+3);i++)
- {
- lcd_write_data(RsBuf[i]); //来电显示
- delayms(5);
- }
- lcd_write_com(0x80+0x40); //将要显示的位置定位在LCD的第一行第0个字符处
- for(i=(ii+3)+15;i<32+(ii+3);i++)
- {
- lcd_write_data(RsBuf[i]); //显示"ATH"
- delayms(5);
- }
- while(!beep)
- {
- key_4x4_scan();//不停调用键盘扫描程序
- }
- clr_rsbuf();
- }
- }
- /***********************************************************
- 函数名称:phone
- 函数功能:拨打目标电话
- 入口参数:无 出口参数:无
- ***********************************************************/
- void phone() //打电话函数
- {
- uchar ATD1[]="ATD"; //拨
- uchar ATD3[]=";\r";
- uchar ATDINTOL[25];
- strcpy(ATDINTOL,ATD1);
- strcat(ATDINTOL,Phone_num); //EEE
- strcat(ATDINTOL,ATD3);
- Print_Str(ATDINTOL);
- delayms(250); delayms(250);
- }
- /***********************************************************
- 函数名称:GSM_ATH
- 函数功能:挂电话
- 入口参数:无 出口参数:无
- ***********************************************************/
- void GSM_ATH()
- {
- Print_Str("ATH"); //发送挂电话指令
- Print_Str("\r"); //发送回车
- delayms(250);delayms(250);delayms(250);delayms(250);
- }
- /***********************************************************
- 函数名称:Rphone
- 函数功能:接听目标电话
- 入口参数:无 出口参数:无
- ***********************************************************/
- void Rphone() //接听电话函数
- {
- Print_Str("ATA");
- Print_Str("\r"); //发送回车
- delayms(250);delayms(250);delayms(250);delayms(250);
- }
- /***********************************************************
- 函数名称:GSM_TEXT
- 函数功能:设置发送数据为TXET格式
- 入口参数:无 出口参数:无
- ***********************************************************/
- //void GSM_TEXT() //设置GSM为TEXT格式
- //{
- // Print_Str(AT_CMGF); //发送设置指令
- // ES=1;
- // delayms(250);delayms(250);
- //}
- /***********************************************************
- 函数名称:GSM_TEXT_SMS
- 函数功能:发送数据为TXET格式的短信内容
- 入口参数:无 出口参数:无
- ***********************************************************/
- void GSM_TEXT_SMS() //发送TEXT格式内容
- {
- Print_Str(AT_CMGS);
- Print_Str(Phone_call);
- Print_Str("\r");
- delayms(200);
- Print_Str(Sms);
- Print_Char(0x1A); //发送短息内容结束符对应的ASCII为0x1a
- ES=1;
- delayms(250);delayms(250);
- }
- /***********************************************************
- LCD相关函数定义
- ***********************************************************/
- //-----------------------------------------
- void lcd_write_com(uchar lcd_com) //LCD送命令子函数
- {
- lcdrs=0;
- lcd_data_port=lcd_com;
- delayms(5);
- lcden=1;
- delayms(5);
- lcden=0;
- }
- //-----------------------------------------
- void lcd_write_data(uchar lcd_data) //LCD送显示数据子函数
- {
- lcdrs=1;
- lcd_data_port=lcd_data;
- delayms(5);
- lcden=1;
- delayms(5);
- lcden=0;
- }
- //-----------------------------------------
- void lcd_int() //LCD初始化子函数
- {
- lcdrw=0;
- lcden=0;
- lcd_write_com(0x38); //设置LCD工作于16x2、5x7点阵、8位数据接口模式
- lcd_write_com(0x0c); //开显示,不显示光标
- lcd_write_com(0x06); //写一个字符后地址指针自动加1
- lcd_write_com(0x01); //清屏
- }
- //----------------------------------------------------------------
- //-----------------------------------------
- void write_sfm(uchar wz,uchar date) //在第一行写一个数函数
- {
- lcd_write_com(0x80+wz); //设置显示位置
- lcd_write_data(0x30+date);
- }
- /*-------------------------------------------------------------------------------------------*/
- //-----------------------------------------
- void key_4x4_scan() //4x4键盘扫描子函数,得到的键值送至全局变量key
- {
- uchar temp ;
- key_4x4_port=0xfe; //送出最低位0电平去扫描
- temp=key_4x4_port; //读出整个口的得到的值
- temp=temp&0xf0; //屏蔽低4位
- if(temp!=0xf0) //假如高4位不是全1
- {
- delayms(10); //延时消抖再读
- temp=key_4x4_port;
- temp=temp&0xf0;
- if(temp!=0xf0) //消抖后如果再次确定高4位不是全1
- {
- temp=key_4x4_port; //读出此次按键的值
- switch(temp)
- {
- ///////////////拨打电话按键////////////////////////////
- case 0xee: key=0;
- lcd_write_com(0x01); //清屏
- clr_rsbuf();
- phone(); //拨打电话
- lcd_write_com(0x80); //将要显示的位置定位在LCD的第一行第0个字符处
- for(i=0;i<32;i++)
- {
- lcd_write_data(RsBuf[i]); //显示
- delayms(50);
- }
- delayms(250);
- Calls_State_Flag=Clear_Connect;
- break; //11101110
- ///////////////挂电话按键//////////////////////////
- case 0xde: key=1;
- lcd_write_com(0x01); //清屏
- clr_rsbuf();
- GSM_ATH(); //发送挂电话指令
- beep=1;
- lcd_write_com(0x80); //将要显示的位置定位在LCD的第一行第0个字符处
- for(i=0;i<32;i++)
- {
- lcd_write_data(RsBuf[i]); //
- delayms(50);
- }
- delayms(250);
- Calls_State_Flag=Phone_connection;
- break; //11011110
- ////////////////TEXT格式及TEXT格式内容///////////////////////////////
- case 0xbe: key=2;
- lcd_write_com(0x01); //清屏
- clr_rsbuf();
- //GSM_TEXT();//设置GSM为TEXT格式
- GSM_TEXT_SMS();//发送TEXT格式内容
- lcd_write_com(0x80); //将要显示的位置定位在LCD的第一行第0个字符处
- for(i=0;i<15;i++)
- {
- lcd_write_data(RsBuf[i]); //显示
- delayms(100);
- }
- for(i=15;i<32;i++)
- {
- lcd_write_data(RsBuf[i]); //显示
- delayms(100);
- }
- delayms(250);
- delayms(250);
- break; //10111110
- ///////////////0号键////////////////////////////////
- case 0x7e: key=3;
- lcd_write_com(0x80); //将要显示的位置定位在LCD的第一行第0个字符处
- Phone_num[k++]=0x30;
- write_sfm((j+1),0);
- j=j+1;
- break; //01111110
- }
- while(temp!=0xf0) //等待按键放开
- { temp=key_4x4_port;
- temp=temp&0xf0;
- }
- }
- }
- key_4x4_port=0xfd; //11111101
- temp=key_4x4_port;
- temp=temp&0xf0;
- if(temp!=0xf0)
- { delayms(10);
- temp=key_4x4_port;
- temp=temp&0xf0;
- if(temp!=0xf0)
- { temp=key_4x4_port;
- switch(temp)
- {
- ///////////////接听电话按键////////////////////////////////
- case 0xed: key=4;
- lcd_write_com(0x01); //清屏
- clr_rsbuf();
- Rphone(); //接听电话
- beep=1;
- lcd_write_com(0x80); //将要显示的位置定位在LCD的第一行第0个字符处
- for(i=0;i<32;i++)
- {
- lcd_write_data(RsBuf[i]); //显示
- delayms(50);
- }
- delayms(250);delayms(250);
- break; //11101101
- ////////////////7号键////////////////////////////////
- case 0xdd: key=5;
- Phone_num[k++]=0x37;
- write_sfm((j+1),7);
- j=j+1;
- break; //11011101
- /////////////////4号键///////////////////////////////
- case 0xbd: key=0x36;
- Phone_num[k++]=0x34;
- write_sfm((j+1),4);
- j=j+1;break; //10111101
- ////////////////1号键////////////////////////////////
- Phone_num[k++]=0x31;
- case 0x7d: key=7;
- write_sfm((j+1),1);
- j=j+1; break; //01111101
- }
- while(temp!=0xf0)
- { temp=key_4x4_port;
- temp=temp&0xf0;
- }
- }
- }
- key_4x4_port=0xfb; //11111011
- temp=key_4x4_port;
- temp=temp&0xf0;
- if(temp!=0xf0)
- { delayms(250);delayms(250);delayms(250);delayms(250);
- temp=key_4x4_port;
- temp=temp&0xf0;
- if(temp!=0xf0)
- { temp=key_4x4_port;
- switch(temp)
- {
- //////////////清屏按键//////////////////////////
- case 0xeb: key=8;
- lcd_write_com(0x01); //清屏
- j=0;k=0;
- break; //11101011
- ///////////////8号键//////////////////////////
- case 0xdb: key=9;
- Phone_num[k++]=0x38;
- write_sfm((j+1),8);
- j=j+1;break; //11011011
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
文档预览: http://www.51hei.com/bbs/dpj-85499-1.html
全部资料打包下载地址:
基于GSM的手机设计.7z
(1.55 MB, 下载次数: 547)
|