receive.m
上传用户:m_sun_001
上传日期:2014-07-30
资源大小:1115k
文件大小:7k
源码类别:

matlab例程

开发平台:

Matlab

  1. function [Datarx, DiffPhRx] = receive(TimeSignal,ifftsize,carriers,...
  2.  wordsize,guardtype,guardtime,DataAvg,NoData,OutWordSize)
  3. %RECEIVE Decodes a COFDM time waveform back into its data.
  4. % It decode the data from one data frame. This function requires
  5. % that the TimeSignal has the correct starting position.
  6. % function [Datarx, DataOut, DiffPh] = receive(TimeSignal,ifftsize,carriers,...
  7. %  wordsize,guardtype,guardtime,DataAvg,NoData)
  8. %
  9. % INPUTS:
  10. % ========
  11. %  TimeSignal : This is the input time signal for the COFDM waveform. The format
  12. %      of the output is a row vector.
  13. % ifftsize   : Size of ifft to use for generating the waveform
  14. % carriers   : Which carriers to use for the transmission
  15. % wordsize   : Number of bits to transmit on each carrier eg. 2 => QPSK
  16. %             1 => BPSK, 4 => 16PSK, 8 => 256PSK.
  17. %              Must be one of: 1,2,4 or 8
  18. % guardtype  : What type of guard period to use
  19. %              Options:
  20. %             0 = No Guard period
  21. %             1 = zero level guard period
  22. %             2 = cyclic extension of end of symbols
  23. %             3 = same as 2 but with the first half of the guard period = zero
  24. % guardtime  : Number of sample to use for the total guard time
  25. % DataAvg    : Data Averaging. Number of repeats sent of the same
  26. %      data word, so that it can be averaged at the receiver
  27. %      to help reduce the phase error.
  28. % NoData: is used for removing padding of the data. The padding is added
  29. %      by the transmitter on the last symbol if the number of data
  30. %      words doesn't fit into an integer number of symbols. NoData
  31. %      is the number of data words transmitted in the frame being
  32. %      decoded, e.g. if 10 bytes of data was sent and the DataOut
  33. %      format is byte format then NoData = 10.
  34. %      If padding hasn't been used set NoData to 0.
  35. % OutWordSize: This is the wordsize of the output data (DataOut). This will
  36. %      normally be set to 8, if the original data is in a byte format.
  37. %      However OutWordSize may be set to higher values (e.g. 16) if
  38. %      analog signal are being transmitted on the COFDM instead of
  39. %      digital data. The value of OutWordSize must match InWordSize
  40. %      on the transmitted. Note : OutWordSize is an optional
  41. %      parameter with a default of 8 bits.
  42. %
  43. % OUTPUTS:
  44. % ========
  45. % Datarx     : This is the output data that has been decoded from the 'TimeSignal'
  46. %             Its format is in words the same size as 'wordsize'. The output
  47. %      format of the data is a row vector.
  48. %
  49. % DiffPhTx   : This is the actual phase difference between each symbol for the data
  50. %      This includes any noise or aborations due to the channel. It can be
  51. %      used for generating a histogram of the phase error. It has been adjusted
  52. %      so that the phase is centered around the phase locations of the data
  53. %      For Example for QPSK, the output phase is from -45 deg to 315 deg. This
  54. %      is for IQ locations at, 0, 90, 180, 270 deg.
  55. %
  56. % Copyright (c) Eric Lawrey 1997
  57. %
  58. % See: TRANSMIT, WRFILE, CHANNEL
  59. % Modifications:
  60. % 16/6/97 Started working on the function, it isn't finished yet.
  61. % 17/6/97 Continued work on the receive function, it is now mostly finished
  62. % and has been partly tested.
  63. % 18/6/97 Changed the way thay the DiffPhTx is generated, so that the phase out is based
  64. % on the phase locations. This was done so the phase error can be easily
  65. % calculated. Negative phase errors centered around the 0deg phasor are no
  66. % longer 359.6 deg for example but -0.4 deg. Fixed a bug due to having
  67. % guardtype = 0
  68. % 3/8/97 Added data averaging allowing duplicate data to be sent to
  69. % reduce the error rate.
  70. % 12/8/97 Updated to data averaging to the same method used by the transmitter
  71. % and added the ability to trim the data back to compensate for padding.
  72. % The padding doesn't work yet
  73. % 13/8/97 The padding problem was fixed by rotating the transmitted data
  74. % which was incorrect, and clipping the DiffPhRx array to the
  75. % correct length.
  76. %
  77. % Required External Functions
  78. % subsamp.m
  79. if nargin < 9,
  80. OutWordSize = 8; %Set the default
  81. end
  82. %=========================================================================
  83. %Strip back the number of samples to make it a multiple of the symbol size
  84. %=========================================================================
  85. if guardtype == 0,
  86. guardtime = 0;
  87. end
  88. SymbLen = length(TimeSignal)+guardtime; %Find total number of samples
  89. %per symbol, including guard.
  90. TimeSignal = TimeSignal(1:(SymbLen-rem(SymbLen,ifftsize+guardtime)));
  91. %Find the number of symbols in the input time waveform
  92. numsymb = length(TimeSignal)/(ifftsize+guardtime);
  93. %==========================================================================
  94. %Reshape the linear time waveform into fft segments and remove guard period
  95. %==========================================================================
  96. if guardtype ~= 0,
  97. symbwaves = reshape(TimeSignal,ifftsize+guardtime,numsymb);
  98. symbwaves = symbwaves(guardtime+1:ifftsize+guardtime,:); %Strip off the guard period
  99. else
  100. symbwaves = reshape(TimeSignal,ifftsize,numsymb);
  101. end
  102. fftspect = fft(symbwaves)'; %Find the spectrum of the symbols
  103. DataCarriers = fftspect(:,carriers); %Extract the used carriers from the symbol spectrum.
  104. clear fftspect; %Save some memory
  105. CarrPh = angle(DataCarriers); %Find the phase angle of the data
  106. NegCarrPh = find(CarrPh<0); %Map the phase angle to 0 - 2pi radians
  107. CarrPh(NegCarrPh) = rem(CarrPh(NegCarrPh)+2*pi,2*pi);
  108. clear NegCarrPh;
  109. %================================
  110. %Apply DQPSK on the received data
  111. %================================
  112. DiffPh = diff(CarrPh);   %Compare phase of current to previous symbol
  113. DiffPh = DiffPh*360/(2*pi); %convert from radians to degrees
  114. NegPh=find(DiffPh<0); %Make all phases between 0 - 360 degrees
  115. DiffPh(NegPh)=DiffPh(NegPh)+360;
  116. DiffPh = reshape(DiffPh',1,size(DiffPh,1)*size(DiffPh,2)); %Convert back to a serial stream
  117. DiffPh = subsamp(DiffPh,DataAvg,1,0); %Average the phase for duplicate words
  118. NegPh=find(DiffPh<0); %Make all phases between 0 - 360 degrees
  119. DiffPh(NegPh)=DiffPh(NegPh)+360;
  120. %DiffPh = reshape(DiffPh,size(DiffPh,1)*DataAvg,size(DiffPh,2)/DataAvg);
  121. Datarx = zeros(size(DiffPh));
  122. PhInc = 360/(2^wordsize); %Find the increment between the phase locations
  123. DiffPhRx = rem(DiffPh/(PhInc)+0.5,(2^wordsize))*(PhInc)-(PhInc/2);
  124. Datarx = floor(rem(DiffPh/(360/(2^wordsize))+0.5,(2^wordsize)));
  125. if NoData == 0,
  126. %Stip back the length of Datarx so it is a multiple of the
  127. %OutWordSize/wordsize.
  128. Datarx = Datarx(1:floor(length(Datarx)/(OutWordSize/wordsize))*(OutWordSize/wordsize));
  129. else
  130. if (NoData*(OutWordSize/wordsize) > length(Datarx)),
  131. disp('WARNING : Received Data Shorter than expected');
  132. disp(['Expected = ', num2str(NoData*(OutWordSize/wordsize))]);
  133. disp(['Received = ', num2str(length(Datarx))]);
  134. else
  135. Datarx = Datarx(1:NoData*(OutWordSize/wordsize));
  136. DiffPhRx = DiffPhRx(1:NoData*(OutWordSize/wordsize));
  137. end
  138. end