查看: 11625|回复: 3
打印 上一主题 下一主题

串口发送AT指令给短信收发设备没有返回值

[复制链接]
跳转到指定楼层
楼主
发表于 2013-12-11 23:45:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
从网上找来的一个串口发送AT指令给短信收发设备没有返回值的问题:


请教一个关于串口连接短信收发设备发短信的问题,我看这里也有很多贴子时关于这个问题的,可是我没有我的答案,我用C#写的,打开串口后,发送“AT\r”,返回“OK”正常,但是再发送其他AT指令的话就都没有返回值了。但奇怪的是,我用超级终端打开过串口后,再在程序里打开串口,发送其他AT指令就会有正常的返回值了(例如:“AT+CGMI\r”)。请问有人知道是怎么回事吗?


回答:
我也碰到过这种 问题 研究了很长时间才解决,发送完 号码时候 要发送个 特殊的内容,在超级终端里面是不用输入那个特殊的标志的
public class PortData
    {
        public event PortDataReceivedEventHandle Received;   //接收事件
        public event SerialErrorReceivedEventHandler Error;  // 接收事件异常处理
        private SerialPort port;                //端口
        private bool ReceiveEventFlag = false;  //接收事件是否有效 false表示有效
        private PDUdecoding PDU;               //PDU 编码类
         /// <summary>
         /// 构造函数
         /// </summary>
         /// <param name="sPortName">端口名称 "com1,com2.... com255"</param>
         /// <param name="baudrate">波特率</param>
         /// <param name="parity">校验</param>
         /// <param name="dataBits">数据位</param>
            /// <param name="stopBits">停止位数</param>
         /// <param name="RtimeOut">读端口时间超时</param>
         /// <param name="WtimeOut">写端口时间超时</param>
        public PortData(string sPortName, int baudrate,Parity parity , int dataBits,StopBits stopBits,int RtimeOut,int WtimeOut)
        {
            port = new SerialPort(sPortName, baudrate, parity, 8, stopBits);
            this.PDU = new PDUdecoding();  
            port.RtsEnable = true;
            port.ReadTimeout = RtimeOut;
            port.WriteTimeout = WtimeOut;   
            port.DataReceived += new SerialDataReceivedEventHandler(DataReceived);
            port.ErrorReceived += new SerialErrorReceivedEventHandler(ErrorEvent);
            this.Open();
        }
        /// <summary>
        /// 析构函数
        /// </summary>
        ~PortData()
        {
            Close();
        }
        /// <summary>
        /// 打开com口
        /// </summary>
        public void Open()
        {
            if (!port.IsOpen)
            {
                try
                {
                    port.Open();
                }
                catch(Exception ex)
                {
                    throw ex;
                }
            }
        }
        /// <summary>
        /// 关闭com口
        /// </summary>
        public void Close()
        {
            if (port.IsOpen)
            {
                try
                {
                    port.Close();
                }
                catch(Exception ex)
                {
                    throw ex;
                }
            }
        }
        //数据发送
        /// <summary>
        /// 暂无使用
        /// </summary>
        /// <param name="data"></param>
        public void SendData(byte[] data)
        {
            if (port.IsOpen)
            {
                port.Write(data, 0, data.Length);
            }
        }
        /// <summary>
        /// 暂无使用
        /// </summary>
        /// <param name="data"></param>
        /// <param name="offset"></param>
        /// <param name="count"></param>
        public void SendData(byte[] data,int offset,int count)
        {
            if (port.IsOpen)
            {
                port.Write(data, offset, count);
            }
        }
        /// <summary>
        /// 发送各种命令
        /// </summary>
        /// <param name="Sendcmd">命令正文</param>
        /// <param name="ReceiveData">返回结果</param>
        /// <param name="Overtime">发送超时</param>
        /// <returns>发送标识</returns>
        private int SendCommand(string Sendcmd, ref  string ReceiveData,int Overtime)
        {
            if (!port.IsOpen)
            {
                this.Open();
            }
            if (port.IsOpen)
            {
                try
                {
                 ReceiveEventFlag = true;        //关闭接收事件
                    port.DiscardInBuffer();         //清空接收缓冲区                 
                    port.Write(Sendcmd);            //写入命令
                    int num = 0, ret = 0;            
                    while (num++ < Overtime)
                    {
                        System.Threading.Thread.Sleep(1000);
                        if (port.BytesToRead > 0)    //存在需要读取的数据
                        {
                            ret = port.BytesToRead;
                            break;
                        }
                        else
                            System.Threading.Thread.Sleep(1);    //延时1毫秒  等待数据发送到端口上
                    }
                    if (ret > 0)                          //如果要读取的数据存在  读取数据 并且 打开接收
                    {
                        ReceiveData = port.ReadExisting();  //先读取再激活接收事件  ReadExecting()
                        ReceiveEventFlag = false;       //打开事件
                    }
                    //如果是发送短信则休息3秒
                    if (ReceiveData.ToLower().Contains("cmgs:"))
                        System.Threading.Thread.Sleep(3000);
                    return ret;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            return -1;
        }
        /// <summary>
        /// 处理异常  
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void ErrorEvent(object sender, SerialErrorReceivedEventArgs e)
        {
            if(Error != null) Error(sender, e);
        }
        /// <summary>
        /// 接收短信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            //禁止接收事件时直接退出
            if (ReceiveEventFlag) return;
            byte[] data = new byte[port.BytesToRead];
            this. port.Read(data, 0, data.Length);
            if (Received != null) Received(sender, new PortDataReciveEventArgs(data));
        }
       /// <summary>
        /// 判读 com口是不是打开的
        /// </summary>
        /// <returns>打开 true ,否则 false</returns>
        public bool IsOpen()
        {
            return port.IsOpen;
        }
        /// <summary>
        /// 初始化 Modem
        /// </summary>
        public  void Initial()
        {
            if (!this.IsOpen())
            {
                this.Open();
            }
            string result = "";
            string all = "";
            string newLine = Environment.NewLine;

            if (this.Check("AT" + Environment.NewLine, 100).ToLower() != "true")
            {
                this.port.Write("32");  //如果处于发送状态则强制结束
                this.port.Write("AT"+Environment.NewLine);
            }
            this.SendCommand("AT+CMEE=1" + newLine, ref result, 1000);  //设置报错方式
            all += result;
            this.SendCommand("AT+CMGF=0"+newLine,ref result,500);//设置为PDU方式
            all+=result ;
            this.SendCommand("AT+CNMI=2,2" + newLine, ref result, 500); //不接收短信,不接收小区广播方式   AT+CSMS=1,0,1,0 // AT+CNMI=2,2 设置为
            all+=result ;
            this.SendCommand("AT+CSMP=17,167,0,8" + newLine, ref result, 500); //短信在短信中心保存24小时
            all += result;
            this.SendCommand("AT&w"+newLine ,ref result ,500 ); //保存以上设置
            all += result;  
            if (all.Length - all.ToLower().Replace("ok", "").Length  !=10)  //结果中 不够 5个 ok
            {
                Exception e = new Exception("设置 ModeM出错");
                throw e;
            }
        }
        /// <summary>
        /// 获得配置文件
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        ///
        public static string GetConfig(string key)
        {
            return ConfigurationSettings.AppSettings[key];
        }
        /// <summary>
        /// 检测 短信收发设备 是否有信号  无信号可能说明没钱了
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="time"></param>
        /// <returns></returns>
        public string Check(string cmd, int time)
        {
            string rst = "";
            this.SendCommand(cmd, ref rst, 1000);
            if (rst.ToLower().Contains("ok"))
                return "true";
            return rst;
        }

        /// <summary>
        /// 发送短息 包括超长短信
        /// </summary>
        /// <param name="phone">接收方号码</param>
        /// <param name="msg">要发送的信息</param>
        /// <returns></returns>
        public int SendMessage(string phone, string msg)
        {
            int star = 0;           //用于分割长短信
            int last = msg.Length;  //短信内容长度
            string buffer = "more"; //用来标识长短信 参考参数
            const int longmsg = 67; // 超长短信每条个容纳67个unicode字符
            int i = 1;              //用于计数发送的第几条短信
            int result = 0;

            if (msg.Length == 0||phone .Length<11)  // 如果短信长度为0  或者手机号码长度小于11返回
                return 0;
            
            if (msg.Length > 70)  //需要短信分页的 如果发送信息长度小于等于70则用 单条发送的方法
            {
                string[] txt = new string[(msg.Length /67)+1];  //超长短信是67个汉字分割的,分割长几条发送
                for (star = 0; star < txt.Length; star++)
                {
                    txt[star] = msg.Substring(star *67, (last /67 - star) > 0 ? 67 : (last - star * 67));   //短信分页
                }
                //以下是发送功能入口
                foreach (string t in txt)
                {
                    result=this.BaseSendMessage(phone, t, buffer,txt.Length,i);
                    if (result>0)
                    {
                        i++;
                        continue;
                    }
                    else                //有一条发送失败则 返回
                    {
                        //break;
                        return result;
                    }
                }
                return 1;  //全部发送成功
            }
            else
            {
                //单条短信发送方法入口
                if (this.BaseSendMessage(phone, msg,"",0,0) > 0)    //发送成功
                    return 1;
                else
                    return 0;
            }
        }
        /// <summary>
        /// 发送短信的函数
        /// </summary>
        /// <param name="phone">接收的号码</param>
        /// <param name="msg">单条发送内容</param>
        /// <param name="buffer">参考标识</param>
        /// <param name="count">长短信中共几条</param>
        /// <param name="index">长短信中当前是第几条</param>
        /// <returns>状态标志 1:发送成功 0:发送失败 2:AT+CMGS 失败 </returns>
        public int BaseSendMessage(string phone, string msg,string buffer,int count,int index)
        {
            string result = "";     //用于保存端口返回结果
            string smg ;            //用于保存编码后的发送信息
            
            if (buffer.Length > 1) //长短信 编码后正文
                smg = this.PDU.smsDecodedsms( phone, msg, count.ToString() , index.ToString() ) + "32";
            else
                smg = this.PDU.smsDecodedsms(phone, msg) + "32";   //单条短信编码后的正文
            //发送前的准备工作
            if (this.Check("AT" + Environment.NewLine, 100).ToLower() != "true")  
            {
                this.port.Write("32");  //如果处于发送状态则强制结束
                this.port.Write("AT" + Environment.NewLine);
            }
            //发送 AT+CMGS 命令
            this.SendCommand("AT+CMGS=" + this.PDU.nLength+ "\n", ref result, 1000);  //+buffer.Length).ToString()+
            if (result.ToLower().Contains(">"))
            {   
                //短信正文发送
                this.SendCommand(smg, ref result, 6000);  //6秒钟的发送 时间足够 机器反应了
                if (result.ToLower().Contains("ok"))
                {
                    return 1;
                }
                else  //正文发送失败再发送一次
                {
                    //发送 AT+CMGS 命令
                    this.SendCommand("AT+CMGS=" + this.PDU.nLength + "\n", ref result, 10000);  //+buffer.Length).ToString()+
                    this.SendCommand(smg, ref result, 10000);  //10秒钟的发送 时间足够 机器反应了
                    if (result.ToLower().Contains("ok"))
                    {
                        return 1;
                    }
                    else
                    return 0;
                }
            }// AT+CMGS 命令失败
            else
            {
                return 2;
            }
        }
        /// <summary>
        /// 检查信号   目前无效
        /// </summary>
        /// <returns></returns>
        public   bool CheckSingal()
        {
            string s = "";  //保存结果
            if (this.Check("AT" + Environment.NewLine, 100).ToLower() != "true")
            {
                this.port.Write("32");  //如果处于发送状态则强制结束
                this.port.Write("AT" + Environment.NewLine);
            }
            this.SendCommand("AT+CREG? " + Environment.NewLine, ref s, 5000);
            if (!s.Contains("CREG: 0,1")) //  sim 没信号了
            {
                MessageBox.Show("天线未接好,或者手机欠费了!");
                return false ;
            }
            return true;
        }
    }
    /// <summary>
    /// 接收短信事件代理
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    public delegate void PortDataReceivedEventHandle(object sender, PortDataReciveEventArgs e);
    /// <summary>
    ///
    /// </summary>
    public class PortDataReciveEventArgs : EventArgs
    {
        /// <summary>
        ///
        /// </summary>
        public PortDataReciveEventArgs()
        {
            this.data = null;
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="data"></param>
        public PortDataReciveEventArgs(byte[] data)
        {
            this.data = data;
        }
        /// <summary>
        ///
        /// </summary>
        private byte[] data;
        /// <summary>
        ///
        /// </summary>
        public byte[] Data
        {
            get { return data; }
            set { data = value; }
        }
    }
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|小黑屋|未来时代科技 ( 粤ICP备12044031号-1

GMT+8, 2024-11-23 08:16 , Processed in 0.075753 second(s), 30 queries .

Powered by WLSD X3.1

© 2013-2014 WLSD Inc.

快速回复 返回顶部 返回列表
 
【电话】(15118131494)
【QQ】 未来时代科技01 售前咨询
【QQ】 未来时代科技02 售后技术
【旺旺】 请问有什么可以帮到您?不在线可留言.
【邮箱】
inextera@sina.com
【地址】 (深圳市龙岗坂田扬马小区)