通过串口发送手机短信C精品.docx

上传人:b****6 文档编号:7490590 上传时间:2023-01-24 格式:DOCX 页数:13 大小:23.39KB
下载 相关 举报
通过串口发送手机短信C精品.docx_第1页
第1页 / 共13页
通过串口发送手机短信C精品.docx_第2页
第2页 / 共13页
通过串口发送手机短信C精品.docx_第3页
第3页 / 共13页
通过串口发送手机短信C精品.docx_第4页
第4页 / 共13页
通过串口发送手机短信C精品.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

通过串口发送手机短信C精品.docx

《通过串口发送手机短信C精品.docx》由会员分享,可在线阅读,更多相关《通过串口发送手机短信C精品.docx(13页珍藏版)》请在冰豆网上搜索。

通过串口发送手机短信C精品.docx

通过串口发送手机短信C精品

【关键字】方案、目录、建议、方法、空间、文件、模式、计划、运行、地方、问题、系统、有效、继续、执行、制定、了解、位置、需要、环境、工程、项目、途径、资源、方式、标准、设置、管理、保证、确保、支持、解决、实现、规范、中心、热心

通过串口发送手机短信(C#版)

原理篇

  短信编码

  在收发短信方面,按时间产生先后,共产生了三种模式:

BlockMode、基于AT指令的TextMode、基于AT指令的PDUModem,TextMode比较简单,多款诺基亚手机均支持该模式。

西门子的手机大多只支持PDU模式,PDU模式是发送或接收手机SMS信息的一种方法,短信息正文经过十六进制编码后被传送。

目前,PDU已取代BlockMode,因我们主要探讨PDU模式的发送。

以西门子3508手机为例。

  SMS是由Etsi所制定的一个规范(GSM03.40和GSM03.38)。

当使用7-bits编码时,它可以发送最多160个字符;但用8-bit编码,最多可以发送140个字符,通常无法直接通过手机显示;还有用16-bit编码时,最多70个字符,被用来显示Unicode(UCS2)文本信息,可以被大多数的手机所显示。

我们今天讨论的是UCS2编码,也就是说,最多只能发送70个字符,不管英文还是中文。

  现例如我们现在要发送如下信息,向我的手机发送"你好,Hello!

"。

在没有发送之前,你要清楚,手机SIM卡所在地的短信中心号,并不是你现在所在地方的短信中心号,像我在深圳,深圳的短信中心号是:

86,即使我现在到外地,短信中心号仍是深圳。

从上面我们得到了下面的信息:

  接收的手机号:

  短信中心号:

86

  短信内容:

你好,Hello!

  在实际使用中,上面这些信息并不为手机所执行,要进行编码手机才会执行,先不管,看看编码后的信息:

08705500F011000D352446F24F60597DFF0C006C006C006F0021

  看不懂吧,我来解释一下:

  08-指的是短信中心号的长度,也就是指(91)+(5500F0)的长度

  91-指的是短信息中心号码类型。

91是TON/NPI遵守International/E.164标准,指在号码前需加'+'号;此外还有其它数值,但91最常用。

  5500F0-短信息中心号码。

由于位置上略有处理,实际号码应为:

86(字母F是指长度减1)。

这需要根据不同的地域作相应的修改。

前面的(08)+(91)+(5500F0)实际上就构成了整个短信的一部份,通称短消息中心地址(AddressoftheSMSC)。

  11-文件头字节

  00-信息类型(TP-Message-Reference)

  0D-被叫号码长度

  91-被叫号码类型

  其实在实际处理中,我们通常把11000D91写死在程序中,因为在国内,这些数据都是不会改变的。

  2446F2-被叫号码,经过了位移处理,实际号码为"86"。

上面的(00)+(0D)+(91)+(2446F2),构成了整个短信的第二部份目的地址(TP-Destination-Address)。

  00-协议标识TP-PID,这里一般为00

  08-数据编码方案TP-DCS(TP-Data-Coding-Scheme),采用前面说的USC2(16bit)数据编码

  00-有效期TP-VP(TP-Valid-Period)

  12-长度TP-UDL(TP-User-Data-Length),也就是4F60597DFF0C006C006C的长度36/2=18的十六进12

  4F60597DFF0C006C006C006F0021-这里就是短信内容了,实际内容为:

"你好,Hello!

"程序实现,请参考本文章所带源程序的PDUdecoding.cs。

AT指令

  说到AT指令可多了,有厚厚的一本书,不属于我们今天讨论的范围,在这里我仅讨论在发送短信中必须要用的几个AT指令。

  与SMS有关的GSMAT指令(fromGSM07.05)如表1所示:

AT指令

功能

AT+CMGC

SendanSMScommand(发出一条短消息命令)

AT+CMGD

DeleteSMSmessage(删除SIM卡内存的短消息)

AT+CMGF

SelectSMSmessageformate(选择短消息信息格式:

0-PDU;1-文本)

AT+CMGL

ListSMSmessagefrompreferredstore(列出SIM卡中的短消息PDU/text:

0/"RECUNREAD"-未读,1/"RECREAD"-已读,2/"STOUNSENT"-待发,3/"STOSENT"-已发,4/"ALL"-全部的)

AT+CMGR

ReadSMSmessage(读短消息)

AT+CMGS

SendSMSmessage(发送短消息)

AT+CMGW

WriteSMSmessagetomemory(向SIM内存中写入待发的短消息)

AT+CMSS

SendSMSmessagefromstorage(从SIN|M内存中发送短消息)

AT+CNMI

NewSMSmessageindications(显示新收到的短消息)

AT+CPMS

PreferredSMSmessagestorage(选择短消息内存)

AT+CSCA

SMSservicecenteraddress(短消息中心地址)

AT+CSCB

Selectcellbroadcastmessages(选择蜂窝广播消息)

AT+CSMP

SetSMStextmodeparameters(设置短消息文本模式参数)

AT+CSMS

SelectMessageService(选择短消息服务)

表一:

相关的GSMAT指令

  我现在以实例来说明这些指令的使用方法:

  先用手机数据线将手机连接到电脑串口,并将串口的波特率设置为19200,可以开始了。

  1、首先测试你的连接及手机是否支持AT指令,请在你的串口调试程序中输入:

  AT<回车>

  屏幕上返回"OK"表明计算机与手机连接正常,那样我们就可以进行其它的AT指令测试了

  2、设置短信发送格式

  AT+CMGF=1<回车>

  屏幕上返回"OK"表明现在短信的发送方式为PDU方式,如果是设置为TEXT方式,则,AT+CMGF=0<回车>

  3、发送短信

  发送内容及手要号仍旧同上面在编码中的一样,编码后,得到要发送的数据如下

08705505F011000D352446F24F60597D002C006C006C006F0021

  我们用如下指令来发送

  AT+CMGS=33<回车>

  如果返回">",就把上面编码数据输入,并以CTRL+Z结尾,稍等一下,你就可以看到返回OK啦。

  说明一下,为什么AT+CMGS=33呢,是这样得来的:

11000D352446F24F60597D002C006C006C006F0021

  这一段字符串的长度除以2得到的结果,上面的字符串,短信中心号加上短信内容得到的,怎么得到的,请回顾一下解码部份

  在我们前面的讨论中,一条完整的短信发送,只要执行三条AT指令,AT、AT+CMGS=?

、AT+CMGS=?

就可以了。

由于篇幅,我只能在这里提到这么多,大家要是想了解更多,可以向各手机厂商索取AT指令白皮书,里面很详细的。

  上面讲到的,只能为我们实际中作准备,我们还必须要一个发送途径,根据我们的需要,我们选择投资最少,实现比较方便的串口通信。

注意,串口通过数据线跟手机相连,用AT指令来实现发送短信,在我们选择数据线时,建议购买原厂所配,非原厂所配,在使用过程中,经常出现一些莫明其妙的问题,比如,手机屏幕黑了,手机老是提示电池电量不足之类的。

串口通信

在C#中要实现串口通信,很多人都不知所措,在论坛上经常可以看到"怎么用MSCOMM实现串口通信"、"怎样能过串口与设备相连"诸如此类的问题。

其实国外的网友早就把这些列入FAQ中了。

  通常,在C#中实现串口通信,我们有四种方法:

  第一:

通过MSCOMM控件这是最简单的,最方便的方法。

可功能上很难做到控制自如,同时这个控件并不是系统本身所带,所以还得注册,不在本文讨论范围。

可以访问/tutorial_details.aspx?

tutorial_id=320,一个国外网友的写的教程,作者很热心,我曾有发邮件给他,很快就回复了。

  第二:

微软在.NET新推出了一个串口控件,基于.NET的P/Invoke调用方法实现,详细的大家可以访问微软网站/issues/02/10/NETSerialComm/default.aspx,方便得到更多资料。

  第三:

就是用第三方控件啦,可一般都要付费的,不太合实际,不作考虑

  第四:

自己用API写串口通信,这样难度高点,但对于我们来说,可以方便实现自己想要的各种功能

  在本文,我们采用第四种方法来实现串口通信,不过不是自己写,用一个国外网友现成的已经封装好的类库,不过功能简单点,相对我们来说已经够用了。

  在整个终端短信的操作过程中,与串口的通信,只用到了四个功能,打开、写、读、关闭串口。

下面是类库对这四个功能的定义:

  打开串口:

  函数原型:

publicvoidOpen()

  说明:

打开事先设置好的端口

  示例:

usingJustinIO;

staticJustinIO.CommPortss_port=newJustinIO.CommPort();

ss_port.PortNum=COM1;//端口号

ss_port.BaudRate=19200;//串口通信波特率

ss_port.ByteSize=8;//数据位

ss_port.Parity=0;//奇偶校验

ss_port.StopBits=1;//停止位

ss_port.ReadTimeout=1000;//读超时

try

{

 if(ss_port.Opened)

 {

  ss_port.Close();

  ss_port.Open();//打开串口

 }

 else

 {

  ss_port.Open();//打开串口

 }

 returntrue;

}

catch(Exceptione)

{

 MessageBox.Show("错误:

"+e.Message);

 returnfalse;

}

  写串口:

  函数原型:

publicvoidWrite(byte[]WriteBytes)

  WriteBytes就是你的写入的字节,注意,字符串要转换成字节数组才能进行通信

  示例:

ss_port.Write("AT+CGMI\r"));//获取手机品牌

  读串口:

  函数原型:

publicbyte[]Read(intNumBytes)

  NumBytes读入缓存数,注意读取来的是字节数组,要实际应用中要进行字符转换

  示例:

stringresponse=;//读取128个字节缓存

  关闭串口:

  函数原型:

ss_port.Close()

  示例:

ss_port.Close();

  由于篇幅,以及串口通信涉及内容广泛,我在这里只讲这些。

  在上面我们已经把终端短信所需的各种原始技术有所了解,是可以小试牛刀的时候了。

实践篇

  在整个开始的时候,你要准备以下软硬件:

   硬件:

西门子3508或C35系列手机一个

   西门子手机通信数据线一条

   软件:

VS.NET(C#)

   短信编码类库(PDUdecoding.cs)

   串口通信类库(JustinIO.cs)

  当所要求的软硬件都准备好后,我们就可以正式开始了。

下面以我自己的测试用例为大家详细介绍。

   做什么事情都应该有计划,虽然我们的测试用例很简单,但还是画个简单的流程图:

  有了流程图,还只是明白了程序怎么运行,再看看界面,会让你更心动的了。

图二、短信终端C#版界面图

  再不开始,就有人骂我了。

下在我讲的开发环境是在VS.NET(C#)中。

COMEGO,GO…

  步骤一、打开VS.NET,新建项目->VisualC#项目->Windows应用程序,名称中输入你的工程名就行啦,我的是smsForCsharp

  步骤二、参照上面的界面图,设计你的程序界面,下面是我程序中各控件的主要属性

控件名称

控件Name属性

说明

TextBox

targetNumber

接收手机号码

TextBox

CenterNumber

短信中心号

TextBox

smsState

发送短信后,返回的信息。

注意设置控件为多行

TextBox

smsContent

短信内容,同样,注意设置为多行

ComboBox

ConnectPort

连接手机的端口,例:

COM1\COM2

ComboBox

ConnectBaudRate

串口连接的波特率,在串口通信中很重要的

Button

btnSend

发送按钮

Button

btnConnect

连接按钮,主要用于程序的初始化

Button

btnExit

退出按钮

  步骤三、将PDUdecoding.cs与JustinIO.cs拷入刚刚新建工程目录,并打开解决方案资源管理器,右键添加现有项,选中两个文件就行了,这里再打开类视图,里面是不是多了两个类,JustinIO与SMS类啊,如图三,要是没有,那你再试。

图三,添加类后的类视图

  步骤四、引用命名空间,用代码查看方式打开Form1.cs(这里以我电脑为准,如果你自己更改过,请以你电脑为准),在代码前面加上

usingJustinIO;

usingSMS;

usingSystem.IO;

usingSystem.Text;

  步骤五、在smsFormCsharp类中,添加两个字段ss_port、sms,分别为JustinIO及SMS的对象,如下

  步骤六、添加串口初始化代码,如下:

///<summary>

///初始化串口

///</summary>

publicboolInitCom(stringm_port,intm_baudrate)

{

 ss_port.PortNum=m_port;//串口号

 ss_port.BaudRate=m_baudrate;//波特率

 ss_port.ByteSize=8;//数据位

 ss_port.Parity=0;//

 ss_port.StopBits=1;//停止位

 ss_port.ReadTimeout=1000;//读超时

 try

 {

  if(ss_port.Opened)

  {

   ss_port.Close();

   ss_port.Open();

  }

  else

  {

   ss_port.Open();//打开串口

  }

  returntrue;

 }

 catch(Exceptione)

 {

  MessageBox.Show("错误:

"+e.Message);

  returnfalse;

 }

}

  将上述代码直接拷入你的程序中,并确保添加在Main主函数的后面,按F5,调试应该没什么问题,不过上面还没有实际任何看得见的功能,仅仅是打开了串口而以。

步骤七、打开串口后,我们就应该初始化程序,取得手机的名牌,型号,以及短信中心号,双击连接按钮,并把下面代码拷入程序中:

///<summary>

///初始化代码,并获取手机相关信息

///</summary>

///<paramname="sender"></param>

///<paramname="e"></param>

privatevoidbtnConnect_Click(objectsender,System.EventArgse)

{

 boolopened=InitCom(,Convert.ToInt32(;//打开并初始化串口

 boolConnected=false;

 if(opened)

 {

  ss_port.Write("AT+CGMI\r"));//获取手机品牌

  stringresponse=;

  if(response.Length>0)

  {

   ConnectState.Text=response.Substring(10,7);

   Connected=true;

  }

  else

  {

   ConnectState.Text="与手机连接不成功";

   Connected=false;

  }

  ss_port.Write("AT+CGMM\r"));//获取手机型号

  response=;

  if(response.Length>0)

  {

   ConnectState.Text=ConnectState.Text+""+response.Substring(10,5)+"连接中......";

   Connected=true;

  }

  else

  {

   ConnectState.Text="与手机连接不成功";

   Connected=false;

  }

  ss_port.Write("AT+CSCA?

\r"));//获取手机短信中心号

  response=;

  if(response.Length>0)

  {

   CenterNumber.Text=response.Substring(20,13);

   Connected=true;

  }

  else

  {

   Connected=false;

  }

  if(Connected==true)

  {

   btnConnect.Enabled=false;

   btnSend.Enabled=true;

  }

  else

  {

   btnConnect.Enabled=true;

   btnSend.Enabled=false;

  }

 }

}

  到这里,你可以按F5,编译调试,通过,在确保你的手机与电脑连接正常下,点击连接按钮看看,是不是像我的一样,手机型号及短信中心号者正常显示出来了。

图四、连接后程序界面

  步骤八、看到上在的结果,是不是感觉到离成功发送短信很近啦,看这么长的文章,费了大家不少时间,再不亮出发短信部份,对不起大家了。

  双击发送按钮,将下面代码拷入程序中。

///<summary>

///发送短信

///</summary>

///<paramname="sender"></param>

///<paramname="e"></param>

privatevoidbtnSend_Click(objectsender,System.EventArgse)

{

 stringdecodedSMS=sms.smsDecodedsms(CenterNumber.Text,targetNumber.Text,smsContent.Text);

 byte[]buf="AT+CMGS={0}\r",sms.nLength));

 ss_port.Write(buf);

 stringresponse=;

 stringSendState="";

 if(response.Length>0&&response.EndsWith(">"))

 {

  ss_port.Write("{0}\x01a",decodedSMS)));

  SendState="发送成功!

";

 }

 else

 {

  SendState="发送失败";

 }

 stringResult=String.Format("{0},{1},{2},\n\r",targetNumber.Text,smsContent.Text,SendState);

 smsState.Text+=Result;

}

  快按F5吧!

神啊,快通过吧!

不用求神了,已经通过了,现在你就可以发短信了,请确保手机可以正常连接电脑。

按连接,然后填入你要的发送的目标手机号,并在内容中添入你要发送的内容,发送吧!

成功了!

成功了是这样子的!

看你的跟我的一样吗?

图五、发送成功

86

  还有一些事不要忘了,记得添加退出代码。

双击退出,添加下面代码:

///<summary>

///关闭串口,退出程序

///</summary>

///<paramname="sender"></param>

///<paramname="e"></param>

privatevoidbtnExit_Click(objectsender,System.EventArgse)

{

 ss_port.Close();

 Application.Exit();

}

  到这里都告一个段落了,所有的功能都完成了!

不过由于这仅仅是一个演示用例,还有很多没有考虑,像串口通信中的,在实际操作不可这样操作的,应该用多线程来处理,一个专门用来读串口,一个专门用来写串口。

还有程序中很多防出错代码没有添加进去,希望有心有朋友添加,并公布出来,这也是我写这篇文章希望看到的结果。

请勿将本程序直接用于实际中,真诚提醒你!

  终于写完了,我也放松了许多,本来很早就应该完成了,因为一些个人原因,没有及时写完,向那些曾经问过我相关问题,没有及时回复的朋友,抱歉一声,希望你们继续支持我!

  调试环境:

  Windows2000Professional、VisualStudio.NET、西门子3508手机、西门子专用数据线。

常见问题:

  第一,手机品牌,因为不同产商的手机,对AT指令的支持不同,所以请选择适合你手机AT指令,像NOKIA的就只能用TEXT模式的AT指令。

  第二,数据线,问题出得最多的地方也就是数据,如果接上数据线后,你的手机显示为黑屏,建议你换数据线。

  第三,手机SIM卡上的短信中心号设置,请确保在你的手机上可以发送短信。

  第

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 信息与通信

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1