datasheet

基于MSP430的FSK 调制与解调制技术

2016-10-10来源: eefocus关键字:MSP430  FSK  调制  解调制技术
首先,讲讲什么是FSK?FSK(Frequency -Shift keying)中文你翻译过来就是頻移键控,它是利用载波的频率变化来传递数字信息。
FSK可以将频率信息转换成数字信息,这个叫做FSK的解调制;而将数字信息转换成频率信息,就叫做FSK的调制。那么FSK能干嘛?FSK有一个很“酷”功能——可以与音频口通讯。无论是安卓系统的手机还是iOS系统的手机,统统可以通过FSK调制与解调制技术实现与手机的数据通讯。安卓系统还好,还可以通过USB口直接通讯,而苹果的iOS却没有开发USB协议,如果想与iphone等苹果产品直接进行数据通讯,除了花大量时间与金钱去做MFI认证,那也只能通过音频了。前阵子很火的“卡拉卡”,就是走的这种方案。
下面就开始讲讲FSK的调制与解调制技术。数据传输可以是同步传输,也可以是异步传输。对于点对点的连接,异步传输通常有一个起始位和一个停止位。下图中可以看到:ASCII码‘K’(0x4B)二进制数字信息在频率信息表示。
基于MSP430的FSK 调制与解调制技术 - ziye334 - ziye334的博客
可以看到 二进制信息‘0’在频率中用f1表示,二进制信息‘1’在频率中用f2表示。所以要实现FSK信息调制,只要将二进制信息'1'在1bit长度周期内生成f1的频率,二进制'0'在1bit长度周期内生成f2的频率;而FSK接调制,则判断频率是f1还是f2就可以判断是二进制'0'还是二进制'1'。
下面讲讲基于MSP430实现的FSK调制与解调制的思路。
1  FSK 调制
将串口0(USART0)作为用户应用软件与调制解调器之间的接口。我们配置串口0为异步传输,波特率为300bit/s。当数据写入串口缓冲区U0TXBUF,串口就开始在串口0发送引脚上输出相应的比特流(包括1位起始位,1位停止位,8为数据位, LSb形式发送)。可以看看MSP430的FSK调制模块:
基于MSP430的FSK 调制与解调制技术 - ziye334 - ziye334的博客
  串口0输出引脚直接外接到P1.3引脚。定时器A的捕获/比较模块CCR2配置成比较模式。定时器A配置成Timer_A.CLK频率下的定时任务。通过定时器A的定时与捕获/比较模块CCR2之间的相互配合,来触发生成相应频率的PWM信号,并在P1.7引脚输出。PWM的半周期可以通过下面公式计算:基于MSP430的FSK 调制与解调制技术 - ziye334 - ziye334的博客
  引脚P1.3配置成中断输入。当P1.3收到串口0发送的信号,就进入P1.3引脚的中断程序服务程序。中断程序的流程图如下:
基于MSP430的FSK 调制与解调制技术 - ziye334 - ziye334的博客
通过读取P1.3的中断触发边沿选择位P1IES3,中断服务程序就可以判断是下降沿触发还是上升沿触发引起的进入中断。如果是上升沿触发引起进入中断,则说明P1.3接收到的信号是'1',否则P1.3接收到的信号是'0'。因此,当P1.3检测到下降沿时,则在引脚P1.7输出信号‘0’对应的频率f1的PWM信号;当P1.3检测到上升沿,则在引脚P1.7输出信号'1'所对应的频率f2的PWM信号。转换结果如下图所示:
基于MSP430的FSK 调制与解调制技术 - ziye334 - ziye334的博客
在MSP430的具体实现代码:

#pragma vector=PORT1_VECTOR
__interrupt void P1_ISR(void) {
if(UART_COM_PORT_IFG & MODULATOR_DIGITAL_IN) { // isr caused by MODULATOR_DIGITAL_IN ?
if(UART_COM_PORT_IES & MODULATOR_DIGITAL_IN) {// caused by high-low transmission ?
BitFreq = _1850HzBitFreq; // load logical 0 value into modulation register
LED_PORT_OUT &= ~DATA_LED; // LED on
UART_COM_PORT_IES &= ~MODULATOR_DIGITAL_IN;// change pin isr edge sensivity
} else {
BitFreq = _1650HzBitFreq; // load logical 1 value into modulation register
LED_PORT_OUT |= DATA_LED; // LED off
UART_COM_PORT_IES |= MODULATOR_DIGITAL_IN; // change pin isr edge sensivity
}
UART_COM_PORT_IFG &= ~MODULATOR_DIGITAL_IN; // clear interrupt flag
} else {
UART_COM_PORT_IFG = 0;
}
}

2  FSK 解调制
经过运算放大器信号放大后,将接收到的频率信号通过引脚P2.3传入比较器,比较器A将接收到的信号与内部参考电压Vcc/2比较。可以通过定时器A的捕获/比较1Timer_A.CCR1模块,计算出接收到信号的频率。下面是CCR1捕获中断服务程序的流程图。
基于MSP430的FSK 调制与解调制技术 - ziye334 - ziye334的博客
 中断服务程序计算相邻两个上升沿或相邻两个下降沿之间的定时器定时的时间,即计算信号的周期值,然后与‘MARK’(980Hz, '1'信号)和‘SPACE’(1180Hz, ‘0’信号)的周期值进行比较(当然在一定的误差范围内),判断收到的应该是‘0’信号还是'1'信号。周期值的计算可以依照下面的公式计算:
基于MSP430的FSK 调制与解调制技术 - ziye334 - ziye334的博客
 下面的表格给出了频率不交的误差范围:
基于MSP430的FSK 调制与解调制技术 - ziye334 - ziye334的博客
 MSP430相关代码:

pragma vector=TIMERA1_VECTOR
__interrupt void Timer_A1(void) {

static signed int Prev_negEgdeCapture = 0;
static signed int Prev_posEgdeCapture = 0;
static unsigned char EdgeCounter = 0;
signed int CCR1_Capture;
signed int Capture_Diff;

switch(TAIV) {
// CCR1 interrupt handler
case 2:
CCR1_Capture = TACCR1;
if(ModemStatusReg & POSITIVE_EDGE) {
Capture_Diff = CCR1_Capture - Prev_posEgdeCapture;
Prev_posEgdeCapture = CCR1_Capture;
ModemStatusReg &= ~POSITIVE_EDGE;
} else {
Capture_Diff = CCR1_Capture - Prev_negEgdeCapture;
Prev_negEgdeCapture = CCR1_Capture;
ModemStatusReg |= POSITIVE_EDGE;
}

if(Capture_Diff > RX_FREQ_CHN1_SPACE-CHN1_MARGIN && Capture_Diff < RX_FREQ_CHN1_SPACE+CHN1_MARGIN) {
if(HandshakeStateMachine == DetectOnes)
EdgeCounter = 0;
// 0 detected
zeros++;
ModemStatusReg |= OFF_HOOK;
} else if(Capture_Diff > RX_FREQ_CHN1_MARK-CHN1_MARGIN && Capture_Diff < RX_FREQ_CHN1_MARK+CHN1_MARGIN) {
// handle detection of binary ones during negotiation handshake
if(HandshakeStateMachine == DetectOnes) { // are we performing the negotiation handshake?
EdgeCounter++; // increment counter
if(EdgeCounter == DetectTime_Chn1) { // sufficient edges detected?
HandshakeStateMachine = OnesDetected; // change to next negotiation handshake state
}
}
// 1 detected
ones++;
ModemStatusReg |= OFF_HOOK;
}
if(zeros>=6 && ModemStateMachine == DataMode && !(ModemStatusReg & STARTBIT)) {
ModemStatusReg |= STARTBIT; // startbit detected
BitCounter = 0;
zeros = 0; // reset counters
ones = 0;
UART_COM_PORT_OUT &= ~DEMODULATOR_DIGITAL_OUT; // show startbit to UART
LED_PORT_OUT &= ~DATA_LED;
TACCTL0 = CCIE;
TACCR0 = CCR1_Capture + BAUDRATE;
}
break;
}
}
代码中,只要检测6个‘SPACE’('0'信号),就表示收到了数据的起始位。此时,定时器Timer_A.CCR0 捕获/比较块设置成比较模式,通过引脚P2.3接收数据。只要收到数据,就开始触发定时时间为1/300s的在定时器中断,在该中断函数中,根据收到的是‘SPACE’信号还是'MAKR'信号,设置引脚P1.2的高低电平。具体程序流程图如下:
基于MSP430的FSK 调制与解调制技术 - ziye334 - ziye334的博客
MSP430实现的代码如下:

#pragma vector=TIMERA0_VECTOR
__interrupt void TA_CCR0_ISR(void) {

static unsigned int HandshakeCounter = 0;

// DataMode
if((ModemStatusReg & STARTBIT) && ModemStateMachine == DataMode) {
BitCounter++;
if(BitCounter == 9) { // processed one byte ?
TACCTL0 = 0; // stop bit detection trigger
ModemStatusReg &= ~STARTBIT;
UART_COM_PORT_OUT |= DEMODULATOR_DIGITAL_OUT; // show stopbit to UART
LED_PORT_OUT |= DATA_LED; // LED off
} else {
if(ones >= zeros) {
UART_COM_PORT_OUT |= DEMODULATOR_DIGITAL_OUT; // show 1 to UART
LED_PORT_OUT |= DATA_LED; // LED off
} else {
UART_COM_PORT_OUT &= ~DEMODULATOR_DIGITAL_OUT;// show 0 to UART
LED_PORT_OUT &= ~DATA_LED; // LED on
}
}
zeros = 0;
ones = 0;
}

.......

}

引脚P1.2成功将原来的频率信号转化成二进制数字信号,然后直接将引脚P1.2与串口0的接收引脚相连,这样的话我们就可以直接在串口缓冲中读取收到的数据。信号转换后的图形如下:
基于MSP430的FSK 调制与解调制技术 - ziye334 - ziye334的博客
 FSK解调制的过程可以下面的图来表示:
基于MSP430的FSK 调制与解调制技术 - ziye334 - ziye334的博客
总结
上面主要讲了代码实现FSK的调制与解调制的思路,但是如果想要做出产品还需要努力。比如想做一个类似“卡拉卡”的产品,除了单片机这边需要你编写FSK调制与解调制代码外,手机端还要编写相关的软件。一般来说,这需要至少两个人,一个做底下单片机相关部分编程,另一个做手机端软件编程,因为上下都精通的大牛少之又少 。

关键字:MSP430  FSK  调制  解调制技术

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/mcu/article_2016101030306.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:基于MSP430的低功耗便携式测温仪设计
下一篇:MSP430 PWM

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

MSP430 中ADC12用法

1.1.    介绍Figure 4  AD模块图在处AD时,我们关注的对象有如下几个,参考源、通道、存储地址、时钟、触发方式、精度,速度(200k)。在上图中我们都可以找到,msp430f149的参考正电源有VRFE+ VeREF+ ,Vcc,同时有对应的负电源。采样通道有16个,存储地址则有对应16个通道,时钟则是有内部时钟及3种时钟源的分频,触发方式有4种。因此,对于这些特点我们可以实现4种模式,单通道单次采样,单通道多次采样,多通道单次采样,多通道多次采样。1.2.    相关寄存器ADC12CTL0:前面8位是对采样保持时间的设置。后8位分别对应8种设置ADC12CTL1
发表于 2019-04-12
MSP430 中ADC12用法

MSP430串口接收控制LED

/**********************************************    *程序描述:单片机的P3.4、P3.5作为串口接收字符,将接受到的字符再发送出去*并且根据接受到的字符‘1’‘2’‘3’‘4’分别点亮LED1、LED2、LED3、LED4P2.0->LED1 ,P2.1->LED2, P2.2->LED3 ,P2.3->LED4***********************************************/  #include  <msp430x14x.h>  
发表于 2019-04-11

实验二:MSP430简单程序设计

1.实验目的    学会用C语言进行简单程序设计。2.实验要求    掌握编写排序程序。3.实验内容(1)设计一个对8个数据(0-255,任意设置)的由小到大排序程序。(2)将结果显示在LCD显示器上。4.参考资料#include <msp430x14x.h>#include "Config.h" //*************************************************************************// 初始化IO口
发表于 2019-04-10

实验三:MSP430输入输出接口实验(2学时)

1.实验目的    学会对P口的使用。2.实验要求    利用板上的按键,控制LED显示。3.实验内容(1)编写键盘扫描程序。(2)编写LED闪烁(时间间隔1秒,软件延时)显示程序。(3)编写用每一个键控制两个LED灯发光的程序,按键可以随时切换。4.参考资料#include <msp430x14x.h>#include "Config.h"#include "1602.c" uchar key; 
发表于 2019-04-10

实验四:MSP430定时器综合试验(2学时)

1.实验目的    学会定时器使用。2.实验要求    掌握定时器的定时控制编程。3.实验内容(1)编写键盘扫描程序。(2)编写LED显示程序。(3)用定时器控制8个LED循环显示程序(间隔时间1秒)。(4)编写用键控制LED灯循环方向,按键可以随时切换。。4.参考资料#include <msp430x14x.h>#include "Config.h"                     //开发板配置头文件,主要配置IO端口信息 
发表于 2019-04-10

MSP430 串口接收指令控制LED亮灭

准备器材:MSP430开发板一块,串口线,PC,串口调试助手(可从网上下载) 八位数据,1个停止位,9600波特率无校验/********************************************************************//DM430-L型最小系统板串口测试程序,使用单片机的串口0//使用板载BSL模块或者用户外接串口线到DB9,要求是直连公对母串口线//使用串口调试助手发送数据到系统板,比如02,03等//系统板会将收到的数据再发送到串口调试助手,接收采用中断模块,发送用查询//板载的BSL模块可以通过跳线帽设置为USB转串口模式,笔记本电脑没有串口可以直接代替//开发板
发表于 2019-04-10

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved