我是靠谱客的博主 酷炫外套,最近开发中收集的这篇文章主要介绍4.6 Data符号调制——16QAM,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

理解: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一样)组成

https://file2.kaopuke.com:8081/files_image/2023052811/202305281117577587991.jpg

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所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部