我这套源码(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();
}
}
Comm.java
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("短信配置工具");
}
@Override
public 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() {
@Override
public 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() {
@Override
public 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();
}
}
});
}
}
c
功能1:控制GSM模块发送短信
功能2:接收315模块发送的报警指令(包括烟雾,火灾和陌生人入侵信号)
功能3:修改flash中短信内容
UART.h
#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 100
void 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();
UART.c
#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));
}
}
}
flash.h
#include <stdio.h>
#include <msp430x14x.h>
#define uchar unsigned char
#define uint unsigned int
#define SegmentA 0x1080 //0x01080到0x010FF
#define SegmentB 0x1000 //0x1000到0x107F
void 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);
flash.c
#include "flash.h"
#define int8_t unsigned char
#define int16_t unsigned int
void 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();
}
main.c
#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;
}