MSP430单片机控制GSM模块发短信(源码)
我这套源码(2个java文件,5个c文件,使用开发环境eclipse+IAR EW for MSP430;实现的功能有,以下代码上有很多不足的地方,仅供参考,如有错误,请予以指正:
java
功能1:上位机读 写串口, 以修改单片机中短信内容
功能2:中文短信的编码
String2Unicode.java
public class String2Unicode {public static void main(String[] args) {System.out.println(convert("工作愉快!"));System.out.println(number("13641285663"));String s = composite("13641285663", "工作愉快!");System.out.println(s + "\n" + s.length());System.out.println((char)Integer.parseInt("26"));System.out.println("0891683108100005F0" + s);System.out.println("0891683108100005F011000D91683146215866F30008000a5de54f5c61095febff01".length());System.out.println((int)'$');System.out.println((int)'a');System.out.println((int)'_');System.out.println("1_25_0891683108100005F011000D91683146215866F30008000a5de54f5c61095febff01$".length());}public static String composite(String number, String msg) {StringBuffer sb = new StringBuffer();return sb.append("11000D91").append(number(number)).append("000800").append(convert(msg)).toString();}public static String number(String str) {StringBuffer sb = new StringBuffer();StringBuffer sb2 = new StringBuffer();int length = str.length();if (str.length() % 2 != 0) {sb.append(str).append("F");}sb2.append("68");for (int i = 0; i < length; ++i) {sb2.append(sb.charAt(i + 1)).append(str.charAt(i));++i;}return sb2.toString();}public static String convert(String str) {String tmp;StringBuffer sb = new StringBuffer(1000);StringBuffer sb2 = new StringBuffer();char c;int i, j;sb.setLength(0);for (i = 0; i < str.length(); i++) {c = str.charAt(i);if (c > 255) {j = (c >>> 8);tmp = Integer.toHexString(j);if (tmp.length() == 1)sb.append("0");sb.append(tmp);j = (c & 0xFF);tmp = Integer.toHexString(j);if (tmp.length() == 1)sb.append("0");sb.append(tmp);} else {sb.append(c);}}int length = sb.length() / 2;tmp = Integer.toHexString(length);if (tmp.length() == 1)tmp = "0" + tmp;sb2.append(tmp).append(sb);return sb2.toString();}}
import java.awt.BorderLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import javax.comm.CommPortIdentifier;import javax.comm.NoSuchPortException;import javax.comm.PortInUseException;import javax.comm.SerialPort;import javax.comm.UnsupportedCommOperationException;import javax.swing.JButton;import javax.swing.JComboBox;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.JTextField;/** * * @author ydp * *使用本程序前,请先安装java的串口API *(http://llk.media.mit.edu/projects/cricket/software/javaSerial.zip) *或 *(http://www.oracle.com/technetwork/java/index-jsp-141752.html) *包括三个文件 *win32com.dll放到Windows\System32目录下 *comm.jar放到jdk1.6.0_07\jre\lib\ext目录下 *javax.comm.properties放到jdk1.6.0_07\jre\lib目录下 * * */public class Comm extends JFrame implements ActionListener {private static final long serialVersionUID = 1L;private JButton openCommBtn;private JLabel recvLabel;private JTextArea recvArea;private JScrollPane recvPane;private JPanel panelTest;private JLabel typeLabel;private JComboBox typeComboBox;private JLabel phoneNumberLabel;private JButton sendMsgBtn;private JTextField phoneNumberField;private JPanel panelPhone;private JTextArea sendMsgArea;private JScrollPane sendMsgPane;private JPanel panelBtn;private JLabel sendMsgLabel;private CommPortIdentifier serialPortId;private SerialPort port;private JLabel commLabel;private JComboBox commComboBox;private InputStream in;private OutputStream out;private String type[] = { "1", "2" };private String comm[] = { "COM1", "COM2", "COM3", "COM4", "COM5", "COM6","COM7" };public Comm(String title) {super(title);recvLabel = new JLabel("接收消息");recvLabel.setSize(30, 5);recvArea = new JTextArea(7, 30);recvArea.setEditable(false);recvArea.setAutoscrolls(true);recvPane = new JScrollPane(recvArea);typeLabel = new JLabel("协议");typeComboBox = new JComboBox(type);phoneNumberLabel = new JLabel(" 电话号码");phoneNumberLabel.setSize(5, 5);phoneNumberField = new JTextField(11);sendMsgLabel = new JLabel(" 发送消息 : ");panelPhone = new JPanel();panelPhone.add(typeLabel);panelPhone.add(typeComboBox);panelPhone.add(phoneNumberLabel);panelPhone.add(phoneNumberField);panelPhone.add(sendMsgLabel);sendMsgArea = new JTextArea(5, 30);sendMsgArea.setAutoscrolls(true);sendMsgPane = new JScrollPane(sendMsgArea);commLabel = new JLabel("串口");commComboBox = new JComboBox(comm);openCommBtn = new JButton("打开串口");sendMsgBtn = new JButton("发送消息 ");panelBtn = new JPanel();panelBtn.add(commLabel);panelBtn.add(commComboBox);panelBtn.add(openCommBtn);panelBtn.add(sendMsgBtn);panelTest = new JPanel();panelTest.add(recvLabel);panelTest.add(recvPane);panelTest.add(panelPhone);panelTest.add(sendMsgPane);panelTest.add(panelBtn);this.pack();this.getContentPane().add(BorderLayout.CENTER, panelTest);this.setSize(370, 380);this.setVisible(true);this.setLocation(300, 200);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.openCommBtn.addActionListener(this);}public static void main(String[] args) {new Comm("短信配置工具");}@Overridepublic void actionPerformed(ActionEvent event) {try {serialPortId = CommPortIdentifier.getPortIdentifier(commComboBox.getSelectedItem().toString());System.out.println(commComboBox.getSelectedItem().toString());port = (SerialPort) serialPortId.open("ydp", 30);port.setSerialPortParams(9600, SerialPort.DATABITS_8,SerialPort.STOPBITS_1, SerialPort.FLOWCONTROL_NONE);in = port.getInputStream();out = port.getOutputStream();} catch (NoSuchPortException e) {e.printStackTrace();} catch (PortInUseException e) {e.printStackTrace();} catch (UnsupportedCommOperationException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}Thread t = new Thread(new Runnable() {@Overridepublic void run() {byte[] data = new byte[256];while (true) {try {int length = in.read(data);if (0 != length) {recvArea.append(new String(data, 0, length, "UTF-8") + "\n");}} catch (IOException e) {e.printStackTrace();}}}});t.start();this.sendMsgBtn.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// System.out.println(sendField.getText());// System.out.println(sendMsgArea.getText());String s = String2Unicode.composite(phoneNumberField.getText(),sendMsgArea.getText());StringBuffer sb = new StringBuffer();sb.append(typeComboBox.getSelectedItem().toString()).append("_").append(s.length() / 2).append("_").append("0891683108100005F0").append(s).append("$");System.out.println(sb);try {// out.write("AT\r\n".getBytes());// out.write("AT+CMGF=0\r\n".getBytes());// out.flush();// Thread.sleep(1000);// out.write(("AT+CMGS=" + (s.length() / 2) +// "\r\n").getBytes());// out.flush();// Thread.sleep(1000);// out.write(("0891683108100005F0" + s + (char)// Integer.parseInt("26") + "\r\n").getBytes());// System.out.println("0891683108100005F0" + s + (char)// Integer.parseInt("26") + "\r\n");out.write(sb.toString().getBytes());out.flush();} catch (IOException e1) {e1.printStackTrace();}}});}}
#include <stdio.h>#include <msp430x14x.h>#include "delay.h"#define uchar unsigned char #define uint unsigned int #define PRINTSUCCESS 0#define PRINTNULL 1#define PRINTTOOLARGE 2#define UARTBUFLEN 100void init_uart0(void);void R_S_Byte(uchar R_Byte);unsigned char printArr(uchar* array, uchar len);unsigned char printStr(uchar* string);unsigned char checkUART();
#include "UART.h"//#include <string.h>uchar uart_Buf[UARTBUFLEN];uchar buf_count;uchar finishFlag; // 0表示没有接收完,1表示接收完一条指令/*//======================初始化串口==============================================void init_uart0(void) {//====================串口工作模式设置======================================== U0CTL=0x00; // U0CTL包含串口0通信协议、通信模式、校验位等设置,允许UART0 U0CTL +=CHAR; //(CHAR=0x10)当CHAR=0时位7位数据,当 CHAR=1时为8位数据 //不需要校验,数据位为8位,无反馈,异步UART通信,UART被允许//====================串口发送操作设置======================================== U0TCTL=0x00; //U0TCTL包含串口0发送功能操作 U0TCTL +=SSEL0; //波特率发生器选择ACLK //#define SSEL1 (0x20) #define SSEL0 (0x10)//====================串口拨特率设置9600====================================//===================拨特率计算公式:拨特率=BRCLK/(UBR+(M7+M6+。。。。+M0)/8) UBR0_0=0x03; //UBR0_0为串口0波特率整数部分低地址 UBR1_0=0x00; //UBR1_0为串口0波特率整数部分高地址 UMCTL_0=0x4A; //UBR1_0为串口0波特率小数部分高地址 //===================串口收发使能控制========================================= ME1 |= UTXE0; //串口0发送功能使能 ME1 |= URXE0; //串口0接收功能使能 //===================串口中断使能控制========================================= IE1 |= URXIE0; //串口0接收中断使能// IE1 |= UTXIE0; //串口0发送中断使能//===================端口第二功能使能========================================= P3SEL |=BIT4; //设置P3。4为UART0 的TXD P3SEL |=BIT5; //设置P3。5为UART0 的RXD P3DIR |=BIT4; //设置P3。4为输出 UCTL0 &= ~SWRST; // 初始化UART状态机 }*/void init_uart0(void){ P6DIR |= BIT2;P6OUT |= BIT2; // 关电平转换 P3SEL |= 0x30; // P3.4,5选择为UART收发端口 UCTL0 |= CHAR; // 8-bit character UTCTL0 |= SSEL0; // UCLK = ACLK UBR00 = 0x03; // 32k/9600 - 3.41 UBR10 = 0x00; // UMCTL0 = 0x4A; // Modulation ME1 |= UTXE0 + URXE0; // 使能USART0收发 UCTL0 &= ~SWRST; // 初始化UART0状态机 IE1 |= URXIE0; // 使能接收中断 }//==============================================================================void R_S_Byte(uchar R_Byte){ while((IFG1&UTXIFG0)==0);//是否上一个串口数据发送完成 TXBUF0=R_Byte;}unsigned char printArr(unsigned char* array, unsigned char len){ unsigned char i=0; if(array==NULL) return PRINTTOOLARGE; for(i=0;i<len;i++) { R_S_Byte(array[i]); } return PRINTSUCCESS;}unsigned char printStr(unsigned char* string){ unsigned char i=0; if(string==NULL) return PRINTNULL; while(1) { R_S_Byte(string[i]); delay_us(100); i++; if(string[i]==0x00) return PRINTSUCCESS; if(i==255) return PRINTTOOLARGE; } }/*接收中断函数,将接收到的字符放在uart_Buf中,收到$表示一条命令接收完成*/#pragma vector = UART0RX_VECTOR__interrupt void UART0_RXISR(void){ //LPM3_EXIT;//退出低功耗模式。 if(finishFlag==0) { uart_Buf[buf_count]=RXBUF0; buf_count++; if(uart_Buf[buf_count-1]=='$'||buf_count>=UARTBUFLEN)//实际buffer的可用空间是UARTBUFLEN-1 { buf_count=0; finishFlag=1; //printStr(uart_Buf); //memset(uart_Buf, 0, sizeof(uart_Buf)); } } }
#include <stdio.h>#include <msp430x14x.h>#define uchar unsigned char #define uint unsigned int #define SegmentA 0x1080 //0x01080到0x010FF#define SegmentB 0x1000 //0x1000到0x107Fvoid flash_clr(uint *ptr);void flash_write_int8(uchar *ptr, uchar value);void flash_write_int16(uint *ptr, uint value);void flash_memcpy(uchar *ptr, uchar *from, uint len);
#include "flash.h"#define int8_t unsigned char#define int16_t unsigned intvoid flash_clr(uint *ptr){ _DINT(); //关中断 FCTL3 = 0x0A500; //* Lock = 0 开锁 FCTL1 = 0x0A502; //* Erase = 1 使能擦除 *((int *) ptr) = 0; //* 擦除段 _EINT();}void flash_write_int8(uchar *ptr, uchar value){ _DINT(); FCTL3 = 0x0A500; // Lock = 0 开锁 FCTL1 = 0x0A540; // Write = 1使能写入 *((int8_t *) ptr) = value; // 写入数据 _EINT();}void flash_write_int16(uint *ptr, uint value){ _DINT(); FCTL3 = 0x0A500; /* Lock = 0 */ FCTL1 = 0x0A540; /* Write = 1 */ *((int16_t *) ptr) = value; /* Program the flash */ _EINT();}void flash_memcpy(uchar *ptr, uchar *from, uint len){ _DINT(); FCTL3 = 0x0A500; /* Lock = 0 */ FCTL1 = 0x0A540; /* Write = 1 */ while (len) { *ptr++ = *from++; len--; } _EINT();}
#include <msp430x14x.h>#include "UART.h"#include "flash.h"#include <string.h>#include <stdlib.h>unsigned int L1=~((0X01)<<0);unsigned int L2=~((0X01)<<1);unsigned int L3=~((0X01)<<2);unsigned int L4=~((0X01)<<3);unsigned int L5=~((0X01)<<4);unsigned int L6=~((0X01)<<5);unsigned int L7=~((0X01)<<6);unsigned int L8=~((0X01)<<7);unsigned int L9=~((0X01)<<8);extern uchar uart_Buf[UARTBUFLEN];extern uchar buf_count;extern uchar finishFlag; struct MSG{ uint len; uint size; uchar m[100];};#define MCLK_C (4)//定义主时钟频率,供延时使用#define Delay_ms(n) __delay_cycles(n*(1000L)*MCLK_C)void initSys();void readFlash(uchar* addr, struct MSG *msg);void sendMsg(struct MSG *msg);uint interrupt=0;uchar p4=0;/**315模块连接线0*/void main(void){ WDTCTL = WDTPW + WDTHOLD; //关闭看门狗 initSys(); //_EINT(); init_uart0(); //进入低功耗3模式。 //_BIS_SR(LPM3_bits); P2DIR = 0xff; //设置P2口方向为输出 P2OUT = 0xff; P4DIR =0xf0; //设置P4口方向为输入 //P4DIR&=~0x0F; P2OUT |= BIT0; //P2OUT |= BIT2; P2OUT ^= 0x01; P1IE |= 0x10; // P1.4中断使能 P1IES |= 0x10; // P1.4设置为高低边沿中断 P1IFG &= ~0x10; // P1.4中断标志位清零 //_BIS_SR(LPM4_bits + GIE); // 进入LPM4中断 struct MSG msg; uchar * startA = (uchar*)SegmentA; flash_clr((uint*)SegmentA); uchar * startB = (uchar*)SegmentB; flash_clr((uint*)SegmentB); while(1) { if(finishFlag != 0) { P2OUT ^= 0x01; memset(&msg, 0, sizeof(msg)); char temp[100]; char *p; memcpy(temp, uart_Buf, 100); p = strtok(temp, "_"); //短信类型 switch(atoi(p)) { case 1: { p = strtok(NULL, "_"); msg.len = atoi(p); p = strtok(NULL, "_"); msg.size = strlen(p)-1; for(int i=0; i<strlen(p)-1; ++i) { msg.m[i]=p[i]; } printStr("1\r\n"); printStr(msg.m); printStr("\r\n"); flash_clr((uint*)SegmentA); flash_memcpy(startA, (uchar *)&msg,sizeof(struct MSG)); memset(&msg, 0, sizeof(msg)); break; } case 2: { p = strtok(NULL, "_"); msg.len = atoi(p); p = strtok(NULL, "_"); msg.size = strlen(p)-1; for(int i=0; i<strlen(p)-1; ++i) { msg.m[i]=p[i]; } printStr("2\r\n"); printStr(msg.m); printStr("\r\n"); flash_clr((uint*)SegmentB); flash_memcpy(startB, (uchar *)&msg,sizeof(struct MSG)); memset(&msg, 0, sizeof(msg)); break; } default: { //P2OUT ^= 0x02; break; } } finishFlag = 0; memset(p,0,strlen(p)); memset(temp,0,sizeof(temp)); //printArr(uart_Buf, 100); memset(uart_Buf,0,100); finishFlag = 0; } if(interrupt==1) { Delay_ms(50); switch(p4) { case 8: { readFlash(startA, &msg); break; } case 9: { readFlash(startB, &msg); break; } default: { //P2OUT ^= 0x01; //char x[5]; //sprintf(x, "%d", p4); //printStr((uchar*)x); //printStr("\r\n"); break; } } //while(interrupt==1); interrupt=0; } } }void initSys(){ unsigned int iq0; _EINT(); BCSCTL1 &=~XT2OFF; //打开高速晶振 do { IFG1 &= ~OFIFG;// 清除振荡器失效标志 for (iq0 = 0xFF; iq0 > 0; iq0--);// 延时,等待XT2起振 } while ((IFG1 & OFIFG) != 0);// 判断XT2是否起振 BCSCTL2 =SELM1+SELS; //MCLK,SMCLK时钟为XT2,MCLK SMCLK为8MHz//???USART0}void sendMsg(struct MSG *msg){ printStr("AT\r\n"); Delay_ms(100); printStr("AT+CMGF=0\r\n"); Delay_ms(100); printStr("AT+CMGS="); char y[5]; sprintf(y, "%d", msg->len); printStr((uchar*)y); printStr("\r\n"); Delay_ms(100); printStr(msg->m); R_S_Byte(0x1A); printStr("\r\n");}void readFlash(uchar* addr, struct MSG *msg){ uint l = ((struct MSG *)addr)->size; for(int j=0; j<l; ++j) { msg->m[j]= ((struct MSG *)addr)->m[j]; } msg->len = (uint)((struct MSG *)addr)->len; //printStr("\r\n"); //printStr(msg->m); sendMsg(msg); memset(msg, 0, sizeof(*msg));}// 端口1的中断服务例程#pragma vector=PORT1_VECTOR__interrupt void Port_1(void){ //LPM4_EXIT; p4 = P4IN&0x0F; P2OUT ^= 0x01; // P1.0 状态翻转 P1IFG &= ~0x10; // P1.4 中断标志清零 interrupt=1;}