原帖由
i7
发自:dev.eefocus.com
------------------------------------------------------------------------------------------------------------------------------------------
/*
Serial1_2_MobilePhone_SMS_7bit 不保证程序无任何错误,请勿用于商业或其它违反中国法律的用途。使用前请自行测试,本人不承担运行此程序造成的任何结果。 2012-6-30 */
String phoneNumber = "+8613800138000";
String messageCenterNumber = "+8613800100500";
String message_text = "helloworld"; void setup()
{
Serial1.begin(9600);
} void loop()
{
SevenBitPduSms(messageCenterNumber, phoneNumber, message_text);
delay(20000);
}
//函数作用:AT指令发送7-bit编码的PDU短信。SMSCNumber:短息服务中心号码;ReceiverNumber:接收方号码;message:短信内容,字符类型
void SevenBitPduSms(String SMSCNumber, String ReceiverNumber, String message)
{
String PDUSMSCNumber; //把串口发送的数据,分为两个部分。此部分为经处理的短信服务中心号码。
String _SMSCNumber; //中间变量,处理短信服务中心号码时使用。
String msgPDU; //把串口发送的数据,分为两个部分。此部分为经过处理接收方的号码和信息内容。
String _ReceiverNumber; //中间变量,处理接收方号码时使用。
//////////////////////////////////////Short Message Service Center Number////////////////////////
//////////////////////////////////////处理短息服务中心号码///////////////////////////////////////
_SMSCNumber = SMSCNumber;
if(_SMSCNumber.charAt(0) == '+') //如果首位是‘+’,除掉它
_SMSCNumber = _SMSCNumber.substring(1,_SMSCNumber.length());
if(_SMSCNumber.length()%2 == 1) //如果号码的长度是奇数,在后面加上一个‘F’
_SMSCNumber += "F";
PDUSMSCNumber = Dec2Hex_String(_SMSCNumber.length()/2 + 1); //短信服务中心号码的长度,包括后面的“91“,两位、十六进制
PDUSMSCNumber += String(91); //Type of address of SMSC, "91"internation format
for(int i = 0; i < _SMSCNumber.length()/2; i++) //短信服务中心号码,十进制数值,将奇偶位互换
{
PDUSMSCNumber += _SMSCNumber.charAt(i*2+1);
PDUSMSCNumber += _SMSCNumber.charAt(i*2);
}
//////////////////////////////////////Reciever phoneNumber////////////////////////
///////////////////////////////////////处理接收方短信号码/////////////////////////
_ReceiverNumber = ReceiverNumber; if(_ReceiverNumber.charAt(0) == '+') //如果首位是‘+’,除掉它
_ReceiverNumber = _ReceiverNumber.substring(1,_ReceiverNumber.length());
msgPDU = "1100"; //"11" TP_MTI/VFP; "00" TP-MR
msgPDU += Dec2Hex_String(_ReceiverNumber.length()); //接收方号码的长度,不包括后面的“91”和“F”,两位、十六进制
msgPDU +="91"; //Type of address of SMSC, "91"internation format
if(_ReceiverNumber.length()%2 == 1) //如果号码的长度是奇数,在后面加上一个‘F’
_ReceiverNumber += 'F';
for(int i = 0; i < _ReceiverNumber.length()/2; i++) //接收方号码,十进制数值,将奇偶位互换
{
msgPDU += _ReceiverNumber.charAt(i*2+1);
msgPDU += _ReceiverNumber.charAt(i*2);
}
//////////////////////////////////////Message////////////////////////
msgPDU += "000000"; //“00” 协议标识(TP-PID)是普通GSM类型,点对点方式; “00”用户信息编码方式(TP-DCS) 7-bit编码; “00”有效期(TP-VP)
msgPDU += Dec2Hex_String(message.length()); //所发送的信息的长度,两位、十六进制
msgPDU += gsmEncode7bit(message); //所发送的信息,7位编码
//////////////////////////////////////Send Message////////////////////////
Serial1.print("AT+CMGS="); //发送AT指令“AT+CMGS=”
Serial1.println(msgPDU.length()/2); //经过处理接收方的号码和信息内容的长度,十进制,字节数 delay(50); //延时50ms
Serial1.print(PDUSMSCNumber); //把串口发送的数据,分为两个部分。此部分为经处理的短信服务中心号码。
Serial1.print(msgPDU); // 此部分为经过处理接收方的号码和信息内容
Serial1.println(char(26)); //结束标志Ctrl^z ,Ascii码值为26
} //将2位的十进制数转换为十六进制,字符串格式
String Dec2Hex_String(int number_2bit)
{
String number;
int firstBit = number_2bit/16; //高位
int secondBit = number_2bit%16; //低位
number = char(firstBit > 9 ? firstBit + 0x37 : firstBit + 0x30); //如果大于9,加0x37,转换为ASCII码 10->A;如果小于9,加0x30
number += char(secondBit > 9 ? secondBit + 0x37 : secondBit + 0x30); //如果大于9,加0x37,转换为ASCII码 10->A;如果小于9,加0x30
return number;
}
String gsmEncode7bit(String pSrc)
{
int nSrc = 0; //源字符串的计数值
String pDst ; //转换完的结果
String nStr ; //中间变量,将源字符串的每8位作为一组
int nSrcLength = pSrc.length(); //源字符串的长度
for(int byteSrc = 0; byteSrc <= nSrcLength/8; byteSrc++) //将源字符串的每8位作为一组
{
nStr = pSrc.substring(byteSrc*8,(byteSrc+1)*8);
for(int index = 0; index < 7; index ++)
{
int nChar;
nChar = (nStr.charAt(index)>>index) | ((nStr.charAt(index+1)&(0xFF>>(7-index)))<<(7-index)); //将8位编码转换为7位编码
pDst += Dec2Hex_String(nChar); //将2位的十进制数转换为十六进制,字符串格式 nSrc ++; //已经转换完的源字符数,如果已经转换完,退出程序
if(nSrc >= nSrcLength-1) break;
}
}
return pDst;
}
|