概述
理解:16QAM是指包含16种符号的QAM调制方式。
16QAM 是用两路独立的正交 4ASK 信号叠加而成,4ASK 是用多电平信号去键控载波而得到的信号。它是 2ASK 体制的推广,和 2ASK 相比,这种体制的优点在于信息传输速率高。
正交幅度调制是利用多进制振幅键控(MASK)和正交载波调制相结合产生的。
16 进制的正交振幅调制是一种振幅相位联合键控信号。16QAM 的产生有 2 种方法:
(1)正交调幅法,它是有 2 路正交的四电平振幅键控信号叠加而成;
(2)复合相移法:它是用 2 路独立的四相位移相键控信号叠加而成。
通信系统中的常见调制方式:
BPSK:Binary Phase Shift Keying 二相相移键控,一个符号代表1bit
QPSK:Quadrature Phase Shift Keying 四相相移键控,一个符号代表2bit
8PSK:8 Phase Shift Keying 八相相移键控,一个符号代表3bit
16QAM:16 Quadrature Amplitude Modulation 16正交幅相调制,一个符号代表4bit
64QAM:64 Quadrature Amplitude Modulation 64正交幅相调制,一个符号代表6bitPSK是相移键控(Phase Shift Keying),是通过相位的变化代表“0”和“1”的。BPSK中的B是“Binary”的意思,也就是有两个变化状态,比如说相位上的“+90°(代表1)、-90°(代表0)”,一个状态代表的就是一个比特。QPSK的“Q”是“Quadrature”的意思,有四个变化状态,如相位上的“+45°(代表00)、-45°(代表11)、+135°(代表10)、-135°(代表01)”,那么一个状态就代表两个比特的信息,如图2所示。同理8PSK的一个状态代表三个比特。
等到QAM调制方式的时候,由于要描述的状态多了,只靠相位区分状态就不够了(相互区别起来有些困难了),需要加入幅度的变化来表示一个状态,就像我们用手指的方向“上下左右”表示“北南东西”的时候,我们同时加上了胳膊伸的长度表示远近,胳膊全伸开表示很远,胳膊伸一半,表示较近。眼神不好的人还真看不出来。所以说对接收机的要求比较高了。16QAM就是状态空间为16,每个状态是4个比特的信息;而64QAM的状态空间是64,每个状态是6个比特的信息,如图3所示。我们看到64卦中,每一卦都是由6个“爻”(爻分阴阳,就像比特最小单位0和1一样)组成
4.6.1 OFDM中的调制
4.6.2 QAM正交幅度调制
4.6.3 16QAM
4.6.4 模块实现
matlab:
function [data_outI,data_outQ]=QAM16_modulation(data_in)
%16QAM调制,符合802.11a标准
%%data_in为输入数据
%data_outI,data_outQ为映射后的星座数据
% Input bits (b0 b1) I-out Input bits (b2 b3) Q-out
% 00 –3 00 –3
% 01 –1 01 –1
% 11 1 11 1
% 10 3 10 3
Kmod=sqrt(10);%归一化量
L=length(data_in)/4;%I,Q支路输出的长度
%IQ初始化
data_outI=zeros(1,L);
data_outQ=zeros(1,L);
%星座映射
for k=1:L
switch [(data_in(4*k-3))*2+data_in(4*k-2)] %data_outI
case 0 %00
data_outI(k)=-3;
case 1 %01
data_outI(k)=-1;
case 3 %11
data_outI(k)=1;
case 2 %10
data_outI(k)=3;
otherwise
;
end
switch [(data_in(4*k-1))*2+data_in(4*k)] %data_outQ
case 0 %00
data_outQ(k)=-3;
case 1 %01
data_outQ(k)=-1;
case 3 %11
data_outQ(k)=1;
case 2 %10
data_outQ(k)=3;
otherwise
;
end
end
%归一化
data_outI=data_outI/Kmod;
data_outQ=data_outQ/Kmod;
换一种说法:
data_outI=11000011 00010100 11101100 00111101 11000011 00010100 11101100
data_outQ=11000011 00010100 11101100 00111101 11000011 00010100 11101100
fpga代码:
module DATA_16QAM_mapper(DM_DIN,DM_ND,DM_RST,DM_CLK,DM_RE,DM_IM,DM_INDEX,
DM_RDY);
input DM_DIN; //输入信号
input DM_CLK; //脉冲
input DM_ND; //来自上一模块的信号提示
input DM_RST; //复位信号
output[7:0] DM_RE; //输出16QAM调制的实部,八位,一位符号位,一位整数位,六位小数位
output[7:0] DM_IM; //输出16QAM调制的虚部
output[5:0] DM_INDEX;//输出标号
output DM_RDY; //输出信号提示
reg[7:0] DM_RE;
reg[7:0] DM_IM;
reg DM_RDY;
reg[7:0] RE_TEMP; //输出实部暂存
reg[7:0] IM_TEMP; //输出虚部暂存
reg[3:0] STOR; //由于四个输入信号对应一个星座点,因此需要四位的存储器存放
reg MAPEN;
reg[5:0] DM_COUNT;
reg[5:0] DM_INDEX;
reg OUTEN; //使Q_RDY比输入四个信号中最后一个晚一个脉冲的过渡,保证转换完成
reg[1:0] counter; //四个输入信号的计数
reg[1:0] OUT_COUNT;
always @(negedge DM_RST or posedge DM_CLK) //Q_RST高电平异步清零
if(!DM_RST)
begin
MAPEN<=1'b0;
DM_RE[7:0]<=8'b00000000;
DM_IM[7:0]<=8'b00000000;
DM_COUNT[5:0]<=6'b000000;
DM_INDEX[5:0]<=6'b000000;
DM_RDY<=0;
RE_TEMP[7:0]<=8'b00000000;
IM_TEMP[7:0]<=8'b00000000;
STOR[3:0]<=4'b0000;
OUTEN<=0;
counter[1:0]<=2'b00;
OUT_COUNT<=2'b00;
end
else
begin
if(DM_ND) //16QAM encoding
begin
counter<=counter+1;
case(counter)
2'b00:STOR[0]<=DM_DIN;
2'b01:STOR[1]<=DM_DIN; //存入输入数值
2'b10:STOR[2]<=DM_DIN;
2'b11:STOR[3]<=DM_DIN;
endcase
end
else
begin
counter[1:0]<=2'b00;
STOR[3:0]<=4'b0000;
end
if (counter==2'b11) // MAPEN 标记四个信号是否已经存入
MAPEN<=1'b1;
else
MAPEN<=1'b0;
if(MAPEN)
begin
case(STOR[1:0])
2'b00:RE_TEMP[7:0]<=8'b11000011;//
2'b10:RE_TEMP[7:0]<=8'b11101100;//
2'b01:RE_TEMP[7:0]<=8'b00111101;//b1b0,b0在低位,映射电平为3,计算
//3/sqrt(10)=0.9487,2^-1+2^-2+2^-3+2^-4+2^-6=0.9531
2'b11:RE_TEMP[7:0]<=8'b00010100;//电平为1,0.3125
endcase
case(STOR[3:2])
2'b00:IM_TEMP[7:0]<=8'b11000011;
2'b10:IM_TEMP[7:0]<=8'b11101100;
2'b01:IM_TEMP[7:0]<=8'b00111101;
2'b11:IM_TEMP[7:0]<=8'b00010100;
endcase
OUTEN<=1;
end
else
begin
OUTEN<=0;
RE_TEMP[7:0]<=8'b00000000;
IM_TEMP[7:0]<=8'b00000000;
end
if(OUTEN) // 输出
begin
DM_RE<=RE_TEMP;
DM_IM<=IM_TEMP;
DM_COUNT<=DM_COUNT+1;
DM_INDEX<=DM_COUNT;
DM_RDY<=1'b1;
end
if (DM_INDEX==47)
OUT_COUNT<=OUT_COUNT+1;
else
OUT_COUNT<=0;
if (OUT_COUNT==2'b11)
begin
DM_RE[7:0]<=8'b00000000;
DM_IM[7:0]<=8'b00000000;
DM_INDEX[5:0]<=6'b000000;
DM_COUNT[5:0]<=6'b000000;
DM_RDY<=0;
end
end
endmodule
tb:
`timescale 1ns/1ns
module DATA_16QAM_mapper_tb();
reg DM_DIN; //输入信号
reg DM_CLK; //脉冲
reg DM_ND; //来自上一模块的信号提示
reg DM_RST; //复位信号
wire[7:0] DM_RE; //输出16QAM调制的实部,八位,一位符号位,一位整数位,六位小数位
wire[7:0] DM_IM; //输出16QAM调制的虚部
wire[5:0] DM_INDEX;//输出标号
wire DM_RDY; //输出信号提示
DATA_16QAM_mapper DATA_16QAM_mapper_inst(
.DM_DIN(DM_DIN),
.DM_ND(DM_ND),
.DM_RST(DM_RST),
.DM_CLK(DM_CLK),
.DM_RE(DM_RE),
.DM_IM(DM_IM),
.DM_INDEX(DM_INDEX),
.DM_RDY(DM_RDY)
);
integer i=0;
integer j=0;
initial begin
DM_DIN = 0;
DM_CLK = 0;
DM_ND = 0;
DM_RST = 0;
#20.1
DM_RST = 1;
for (j=0; j<2;j=j+1)
#1000
begin
for (i=0;i<192;i=i+1)
begin
#10
DM_ND = 1;
DM_DIN = {$random}%2;
end
DM_ND = 0;
end
#100000
$stop;
end
always #5 DM_CLK=~DM_CLK;
endmodule
最后
以上就是酷炫外套为你收集整理的4.6 Data符号调制——16QAM的全部内容,希望文章能够帮你解决4.6 Data符号调制——16QAM所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复