MSP430F149驱动T8650北斗模块实现短报文通信实战

在一些偏远地区(比如海洋渔业、无人区探险、森林防火),手机没信号是常事。但北斗卫星的短报文功能 ,可以让你在没有地面网络的地方,通过卫星发送和接收最多120个汉字的信息。今天,我就以MSP430F149 为主控,配合博纳雨田 T8650 北斗模块,实现北斗短报文的发送与接收。

一、方案选定

T8650是集成了RDSS(短报文通信)和RNSS(定位)功能的"四合一"模块,发射功率10W,通信成功率≥95%。它的串口协议遵循北斗 4.0 协议(兼容2.1协议),指令格式规范。MSP430F149有两个串口(UART0和UART1),一个用来与T8650的短报文通信,另一个与T8650的定位通信。

二、 T8650 模块硬件要点

1. 电源是关键

  • 模块需要两路供电:VCC 5V 给基带和接收部分,VCCPA 12V~15V 给功放(发射时用)。发射瞬间峰值电流较大,VCCPA必须加大容量电容( ≥470μF
  • 严禁空载发射!TX天线端口未接天线时,绝对不要给VCCPA供电,否则功放会烧毁。

2. 串口电平
T8650的串口是LVTTL 电平( 3.3V ,与MSP430F149(3.3V)可以直接连接。注意:MSP430的RX接T8650的TX,TX接T8650的RX,交叉连接。

3. 天线
使用无源天线(需另配LNA和滤波器,但T8650内部已集成低噪放,直接接RX口即可)。天线须朝向南方(北斗卫星在赤道上空,我国境内朝南信号最好),且顶部无明显遮挡。

4. 电源电路

T8650模块需要12V和5V供电,MSP430F149要3.3V供电,总共3路供电,输入电压需要DC15V以上,上图中R1为210K时输出5V,电感取值10-15UH,R1为560K时可以输出12V,电感22UH。

三、北斗 4.0 协议 ------ 看懂指令格式

北斗用户机与外设之间通过帧格式 通信。每个指令以$开头(ASCII码0x24),后跟指令名(如TXSQ表示通信申请),然后是长度、用户地址、信息内容、校验和。

基本格式$``指令名``,``长度``,``用户地址``,``信息内容``,``校验和

  • 长度 :从$到校验和前一字节的总字节数。
  • 校验和 :从$到校验和前一个字节,逐个字节异或的结果。
  • 用户地址:3字节,低21bit有效(你的北斗卡ID)。

常用指令举例

  • 定位申请$DWSQ,请求当前位置。
  • 通信申请$TXSQ,发送短报文。
  • 功率检测$GLJC,查询信号强度。

四、 MSP430F149 软件设计

1. 串口初始化
复制代码
#include <msp430x14x.h>
复制代码
复制代码
void UART1_Init(void)  //与T8650的RDSS通信,波特率115200
复制代码
{
复制代码
    P3SEL |= 0xC0;      // P3.6, P3.7选择外围模块功能
复制代码
    U1CTL = SWRST;      //复位串口
复制代码
    U1CTL = CHAR;       // 8位数据
复制代码
    U1TCTL = SSEL1;     // SMCLK
复制代码
    U1BR1 = 0x01;       // 115200 @ 8MHz SMCLK
复制代码
    U1BR0 = 0x45;
复制代码
    U1MCTL = 0x00;
复制代码
    ME2 |= UTXE1 + URXE1; //使能发送和接收
复制代码
    U1CTL &= ~SWRST;
复制代码
    IE2 |= URXIE1;       //使能接收中断
复制代码
    _EINT();
复制代码
}
复制代码
复制代码
void UART0_Init(void)   //与T8650的RNSS通信,波特率9600
复制代码
{
复制代码
    P3SEL |= 0x30;      // P3.4, P3.5
复制代码
    U0CTL = SWRST;
复制代码
    U0CTL = CHAR;
复制代码
    U0TCTL = SSEL0;     // ACLK
复制代码
    U0BR1 = 0x00;
复制代码
    U0BR0 = 0x0D;       // 9600 @ 32768Hz
复制代码
    U0MCTL = 0x00;
复制代码
    ME1 |= UTXE0 + URXE0;
复制代码
    U0CTL &= ~SWRST;
复制代码
}
2. 发送北斗指令

以发送短报文为例,指令为$TXSQ。假设用户地址为0x123456,向地址0x654321发送"HELLO"的代码电文。

复制代码
unsigned char cal_checksum(unsigned char *buf, unsigned char len)
复制代码
{
复制代码
    unsigned char cs = 0;
复制代码
    for(unsigned char i=0; i<len; i++) cs ^= buf[i];
复制代码
    return cs;
复制代码
}
复制代码
复制代码
void Send_ShortMsg(unsigned long dest_addr, char *msg)
复制代码
{
复制代码
    unsigned char cmd[200];
复制代码
    unsigned char len_pos, cs_pos;
复制代码
    //构造指令字符串: $TXSQ,长度,用户地址(本机ID),信息内容,校验和
复制代码
    //为了简化,这里直接按固定格式组装二进制帧(4.0协议要求二进制传输)
复制代码
    //注意:实际使用时需根据协议封装二进制数据
复制代码
    //示例:定位申请
复制代码
    unsigned char dwsq[] = {0x24, 0x44, 0x57, 0x53, 0x51}; // "$DWSQ"
复制代码
    //长度、地址等省略...
复制代码
    //发送
复制代码
    for(int i=0; i<sizeof(dwsq); i++) UART1_SendChar(dwsq[i]);
复制代码
}

更严谨的做法:根据协议表,将指令、长度、地址、信息内容按字节顺序填入数组,计算校验和,然后一并发送。

3. 接收解析

T8650返回的数据也遵循相同格式。我们可以编写一个简单的状态机来接收:

复制代码
unsigned char rx_buffer[100];
复制代码
unsigned char rx_index = 0;
复制代码
unsigned char start_flag = 0;
复制代码
复制代码
#pragma vector=UART1RX_VECTOR
复制代码
__interrupt void UART1_RX_ISR(void)
复制代码
{
复制代码
    unsigned char ch = U1RXBUF;
复制代码
    if(ch == '$') {
复制代码
        start_flag = 1;
复制代码
        rx_index = 0;
复制代码
    }
复制代码
    if(start_flag) {
复制代码
        rx_buffer[rx_index++] = ch;
复制代码
        if(rx_index >= 2 && rx_buffer[1] == '?') //根据实际帧长度判断结束
复制代码
            start_flag = 0;
复制代码
    }
复制代码
}

然后解析定位信息($DWXX)或通信信息($TXXX),提取经纬度或电文内容。

五、实战步骤

  1. 上电顺序:先接好天线,再给VCC(5V)供电,最后给VCCPA(12V)供电。发射时确保天线已连接。
  2. 发送定位申请 :发送$DWSQ,等待约2秒,模块会返回$DWXX帧,解析出经纬度。
  3. 发送短报文 :构造$TXSQ帧,包含目标地址、电文内容(中文需GB2312编码,代码电文用BCD码)。发送后,如果成功,会收到$TXHZ(通信回执)。
  4. 接收短报文 :当有别人给你发短信时,模块会自动输出$TXXX帧,解析出发信方地址、时间和电文。

六、常见坑点与经验

  • 电源纹波大:发射时峰值电流大,如果电源纹波大,模块会重启。解决方法:VCCPA输入端并一个大电容(470μF)和一个小电容(0.1μF)。
  • 天线问题:务必使用频率匹配的北斗无源天线(中心频率1615.68MHz),增益≥3dB。天线朝南,周围无金属遮挡。

七、完整例程片段

下面是一个简化的发送"HELLO"代码电文的函数(假设本机地址为0x00A1B2,目标地址0x00C3D4):

复制代码
void Send_Text(void)
复制代码
{
复制代码
    unsigned char frame[50];
复制代码
    unsigned char i, cs;
复制代码
    //帧头"$TXSQ"
复制代码
    frame[0]='$'; frame[1]='T'; frame[2]='X'; frame[3]='S'; frame[4]='Q';
复制代码
    //长度占2字节(大端),后面计算
复制代码
    //用户地址(3字节)
复制代码
    frame[5]=0x00; frame[6]=0xA1; frame[7]=0xB2;
复制代码
    //信息类别(报文通信)
复制代码
    frame[8]=0x00;  //假设
复制代码
    //目标地址(3字节)
复制代码
    frame[9]=0x00; frame[10]=0xC3; frame[11]=0xD4;
复制代码
    //电文长度(比特数)HELLO 5个字符,ASCII编码,5\*8=40bit
复制代码
    frame[12]=0x00; frame[13]=0x28;
复制代码
    //是否应答0
复制代码
    frame[14]=0x00;
复制代码
    //电文内容"HELLO"
复制代码
    frame[15]='H'; frame[16]='E'; frame[17]='L'; frame[18]='L'; frame[19]='O';
复制代码
    //总长度= 20字节(从$到O)
复制代码
    frame[4]=20; //注意:长度字段实际应该在指令之后,这里简化
复制代码
    //计算校验和
复制代码
    cs = 0;
复制代码
    for(i=0; i<20; i++) cs ^= frame[i];
复制代码
    frame[20] = cs;
复制代码
    //发送
复制代码
    for(i=0; i<=20; i++) UART1_SendChar(frame[i]);
复制代码
}

实际开发时,请严格按照协议文档中的表格填写各字段,特别是"信息类别"、"电文长度"等。

另:北斗一号短报文模块的RNSS定位精度只有100米左右,远低于现在常用的导航模块如和芯星通的UM220系列的2米精度,可以用T8650与 UM220配合使用。

掌握北斗短报文的开发,可以让你在应急通信、野外监控等领域多一项硬技能。MSP430F149的低功耗特性结合T8650,特别适合电池供电的便携设备。

你在北斗短报文开发中用过哪些模块或者遇到过哪些问题,欢迎关注我在评论区留言!

后续干货不断,咱们一起在单片机的世界里,共同进步。

相关推荐
会周易的程序员7 小时前
aiDgeScanner:工业设备扫描与管理的一体化利器——深度解析上位机与扫描端的无缝协作
c++·物联网·typescript·electron·vue·iot·aiot
hoiii1877 小时前
基于STM32的音频播放系统,实现SD卡读取音频文件PWM输出播放
stm32·嵌入式硬件·音视频
Deitymoon8 小时前
STM32——软件IIC显示字符
stm32·单片机·嵌入式硬件
AAAAA92408 小时前
电气火灾监控行业全景解析:从被动响应到主动智防
物联网·智慧城市·智慧消防
百万老师8 小时前
自然语言编程时代,如何零基础学习掌握嵌入式编程
c语言·单片机·嵌入式硬件·学习·ai全流程闭环开发
初雪云8 小时前
让安卓发版再简单一点,体验一键自动化发布
android·运维·自动化
efangfd8 小时前
TXS0104 和 TXB0104 的 IO 驱动电流对比
单片机·嵌入式硬件
gihigo19989 小时前
STM32F407 Modbus RTU主站例程
stm32·单片机·嵌入式硬件
砍材农夫10 小时前
物联网 基于netty构建mqtt服务协议支持
java·物联网·struts·netty