Nödvändig bandbredd för FSK?

Elektronikrelaterade (på komponentnivå) frågor och funderingar.
Användarvisningsbild
AndersG
EF Sponsor
Inlägg: 8477
Blev medlem: 25 februari 2008, 17:10:58
Ort: Mariehamn
Kontakt:

Re: Nödvändig bandbredd för FSK?

Inlägg av AndersG »

Tack. Jag har inte matlab, men tydligen gör fir() funktionen i Octaber samma sak, räknar ut värdena.
guckrum
Inlägg: 1686
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: Nödvändig bandbredd för FSK?

Inlägg av guckrum »

Jag tycker att mycket av mecket med mottagare är att synkronisera i tid och frekvens. Det kan ibland vara klurigare än själva demoduleringen.
Här kommer ett exempel som, trots sin längd, är ganska enkelt, och kan användas till flera saker, tror jag. Programmet räknar ut var centerfrekvensen ligger.

Centerfrekvensen tas fram genom att filtrera ut varje symbol, kvadrera dess amplitud för att få energin, och summera energin över alla symboler i din samplade fil. (I verkligheten kanske man tar de senaste N symbolerna eller liknande.) Om centerfrekvensen är F, summerar den energierna vid frekvenserna F-85Hz och F+85Hz. Dessutom summerar den energin vid frekvens F separat, som jämförelse. Här är en plot
channel_center.jpg
Den svarta kurvan visar symbolenergin för en frekvens (den visar alltså var de två frekvenserna finns), medan den blå visar summan av två symboler offsetade 170Hz. För summan blir det alltså tre pucklar, en hög i mitten när man "kör med båda hjulen i hjulspåren", och två lägre på sidorna när man bara träffar den ena frekvensen och den andra är helt utanför. Jag får centerfrekvensen till 1385Hz.

Här kommer då programmet. Tyvärr är matlab inget bra språk på flera sätt. Matlabkod blir typiskt effektivare av att använda mycket matrisoperationer och lite for-loopar, typ, så för den som är van vid mera "vanliga" språk ser då väldigt svårbegripligt ut. Jag har gjort en mix här. En annan sak som är svår är subrutiner.

Först deklarerar vi lite konstanter som relaterar till standarden respektive din sampling, och så läser vi in filen. Notera att den också räknar ut antalet sampel per symbol, N, som i detta fallet blir 80. Vi skapar också en vektor "frange" som innehåller alla de frekvenser vi vill testa med. Från 800Hz till 2000Hz i steg om 10Hz. Öka steglängden till exempelvis 100 för snabbare exekvering.

Kod: Markera allt

# NAVTEX parameters
Fdelta =  170;  # BFSK frequency difference
Fsym =    100;  # Symbol rate

# Receiver parameters
Fs =     8000;  # sample frequency
N =   Fs/Fsym;  # Samples per symbol

# Read input signal.  The prim (') transposes from row to line vector
r = audioread('rost.wav')';

# Run all frequencies in this range (low:stepsize:high)
frange = 800:10:2000;
Allokera tomma vektorer för resultaten

Kod: Markera allt

# allocate output vectors
output1 = zeros(1, length(frange));
output2 = zeros(1, length(frange));
Och sedan loopen. Yttre loopen itererar frekvensen F. Vi testar en frekvens i taget. Inre loopen plockar ut N sampel i taget ur indatan i en variabel jag kallar "fifo". De tre exp(j...) är bandpassfilter som är konstanta för varje F. FIR-filterna är "fifo .* wx" som skapar en vektor "[fifo[0] * wx[0], fifo[1] * wx[1], ...]". Summan av detta är filtrets utsignal. Denna kvadreras, och ackumuleras till acc1 eller acc2, där acc1 är för F-85Hz och F+85Hz, och acc2 är för F.

Kod: Markera allt

ix = 1;
for F = frange
  # For each frequency F, define three bandpass filters with
  # centers at (F-Fdelta/2), F, and (F+Fdelta/2).
  wh = exp(j*2*pi*(F+Fdelta/2)/Fs*(0:N-1));
  wl = exp(j*2*pi*(F-Fdelta/2)/Fs*(0:N-1));
  wc = exp(j*2*pi*(F         )/Fs*(0:N-1));

  # Accumulate the energy of all "symbols" in the sampled vector
  acc1 = 0;
  acc2 = 0;
  for n = 0:floor(length(r)/N)-2
    fifo = r(1+n*N:(n+1)*N);
    acc1 = acc1 + ...
          abs(sum(fifo .* wl))^2  + ...
          abs(sum(fifo .* wh))^2;
    acc2 = acc2 + ...
          abs(sum(fifo .* wc))^2;
  end
  output1(ix) = acc1;
  output2(ix) = acc2;
  ix = ix + 1;
end
Så som svar på en tidigare fråga är här exempel på hur man kan göra bandbassfilter. Filterna skall vara precis lika långa som symbolerna, dvs av längd N. Är de kortare tar man inte alla sampel i beaktande (suboptimalt), och är de längre får man intersymbolinterferens.

Notera att detta exempel inte har synkroniserat i tidsled. Vi vet inte ännu exakt när en symbol slutar och nästa börjar. För detta exempel funkar det ändå, men jag hoppas återkomma till det ämnet senare.

En annan grej är att dessa filter kan implementeras mycket effektivare om man ser det som ren mixning med en komplex svängning. Man behöver bara en komplex mulitplikation per insampel och filter, det blir också senare.

EDIT: Hade fel tecken i exponentialfunktionerna, resultaten blir desamma.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
AndersG
EF Sponsor
Inlägg: 8477
Blev medlem: 25 februari 2008, 17:10:58
Ort: Mariehamn
Kontakt:

Re: Nödvändig bandbredd för FSK?

Inlägg av AndersG »

OK. Intressant. Jo i det allmäna fallet vill man säkert först hitta mittfrekvensen, sedan filtrera +/- 85 Hz om denna. Skall dock se om jag får en så stabil LO att jag helt kallt kan räkna med att min frekvens alltid är konstant.

Sedan har jag ju en annan begränsning: Tänkte göra detta i realtid och med en relativt strömsnål processor. Om jag antar att jag samplat med 4kHz så har jag sisådär 250us att spela med, tiden per sampel.
Filterna skall vara precis lika långa som symbolerna, dvs av längd N.
Nu får du förklara så jag förstår :) Om jag samplar 1kHz med 4kHz och datahastigheten är 100baud, vad är då symbollängden? Om vi har 100 baud, har vi 100 symboler/sek och symbollängden 1/100s eller 10ms? Skall då filtret vara 10ms/250us = 40? 40 "taps"??

Motsvarar antalet "taps" "ordningen" på ett konventionellt filter?
Användarvisningsbild
AndersG
EF Sponsor
Inlägg: 8477
Blev medlem: 25 februari 2008, 17:10:58
Ort: Mariehamn
Kontakt:

Re: Nödvändig bandbredd för FSK?

Inlägg av AndersG »

Det finns ett filterverktyg från Microchip som direkt genererar kod för deras DSP-rutiner:
DSPTool.png
Är ganska kul att labba med. Jobbar med heltal så det är litet snabbare än Octave.

Tror knappast att C-koden hänger med så långt dock. Får väl kika på att göra vissa bitar i assembler.- dsPIC har en assemblerfunktion som heter MAC, Multiply and accumulate. Den gör följande:
Multiplicerar två 16-bits tal med teckenbit (17nde biten)
Adderar produkten till en 40-bitars ackumulator
Ökar eller minskar två pekare med valfritt värde

Allt detta i en instruktionscykel (100ns vid 40MHz klocka)
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
YD1150
Inlägg: 1944
Blev medlem: 29 oktober 2010, 22:41:10

Re: Nödvändig bandbredd för FSK?

Inlägg av YD1150 »

Filtreringen i C-programmet till dsPIC sker väldigt lätt:

FIR(BLOCK_LENGTH, &FilterOut[0], &A_D_value[0], &Bandpassfilter_Coeffs);

BLOCK_LENGTH kan vara 1 om man vill filtrera ett "sampel" i taget, och då
trillar det ut ett ur filtret.

199-tap FIR vid fs=10kHz är inga problem alls finns gott om tid till annat.
Då är klockkristallen på 5MHz ( x 16 i PLL ger 80MHz som delas ner till 20MHz / 50ns som är cykeltiden)
Användarvisningsbild
AndersG
EF Sponsor
Inlägg: 8477
Blev medlem: 25 februari 2008, 17:10:58
Ort: Mariehamn
Kontakt:

Re: Nödvändig bandbredd för FSK?

Inlägg av AndersG »

Det beror iofs på vilken dsPIC man väljer. Tänkte ta en litet mindre, men faktum är att då jag testar i simulatorn så får jag 96 cykler för anropet till FIR() nedan:

Kod: Markera allt

#include <p30f2011.h>

#include <dsp.h>
#define BLOCK_LENGTH  1;
// http://www.microchip.com/forums/m152177.aspx
float raw_coef[25] =	{0.015591488063, 0.027520971951, 0.000000000000, -0.033636743495, -0.023387232095,
 						0.026728265251, 0.050455115243, 0.000000000000, -0.075682672864, -0.062365952253,
 						0.093548928379, 0.302730691456, 0.400000000000, 0.302730691456, 0.093548928379,
 						-0.062365952253, -0.075682672864, 0.000000000000, 0.050455115243, 0.026728265251,
 						-0.023387232095, -0.033636743495, 0.000000000000, 0.027520971951, 0.015591488063};

fractional delay1[25] __attribute__ ((space(ymemory), aligned (32)));
fractional coeffs1[25] __attribute__ ((space(xmemory), aligned (32)));

FIRStruct filter1;


int main(void) {
    
    int i;
 	//convert float coefficients to fract
 	for(i=0;i<25;i++)
 		coeffs1[i]=Float2Fract(raw_coef[i]);
 	//init filter
    FIRStructInit(&filter1,25,coeffs1,0xFF00,delay1);
    FIRDelayInit(&filter1);
    FIR(1, &FilterOut[0], &A_D_value[0], &filter1);

    return 0;
}

Slutar läsa assemblermanualen nu och läser docsen för DSP-biblioteken :) Misstänker att "CE001 Using dsPIC30F A/D Converters and the DSP library for Signal Filtering" kan inehålla en hel del matnyttigt :)

Edit:

Kod: Markera allt

For dsPIC30F/33F:
Program words (24-bit instructions):
61
 
Cycles (including C-function call and return overheads):
61 + N*(4 + M) if coefficients are in data memory, or
68 + N*(9 + M) if coefficients in program memory.
M = Koefficienter, N = Samples
Senast redigerad av AndersG 23 augusti 2017, 07:33:51, redigerad totalt 2 gånger.
guckrum
Inlägg: 1686
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: Nödvändig bandbredd för FSK?

Inlägg av guckrum »

Det rullar ju på bra det här, du är ju snart i hamn!
Nu får du förklara så jag förstår :) Om jag samplar 1kHz med 4kHz och datahastigheten är 100baud, vad är då symbollängden? Om vi har 100 baud, har vi 100 symboler/sek och symbollängden 1/100s eller 10ms? Skall då filtret vara 10ms/250us = 40? 40 "taps"??
Ursäkta om jag var lite slarvig där, N relaterade just då till variabeln N i programmet ovan. Du har räknat helt rätt, 40 tappar skall det vara i ditt exempel. Och 100 baud är 100 symboler/s vilket motsvarar en symboltid på 10ms.
Motsvarar antalet "taps" "ordningen" på ett konventionellt filter?
Ja ungefär. Antalet tappar är hur mycket minne systemet har, vilket påminner om antalet tillstånd i en analog krets som är typiskt likamed antalet reaktiva element (kondingar och spolar).
Ett annat sätt att se det är att det finns lika många tappar som nollor i "frekvensplanet".
Kan du förklara hur jag enklast gör ett bandpassfilter för 1462 och ett för 1292Hz, dvs mittfrekvensen 1377 +/-85hz?
Här är ett par filter som du kan använda nästan rakt av

Kod: Markera allt

# NAVTEX parameters
Fdelta =  170;  # BFSK frequency difference
Fsym =    100;  # Symbol rate
F =      1385;  # Center frequency
# Receiver parameters
Fs =     8000;  # sample frequency
N =   Fs/Fsym;  # Samples per symbol

h_low = cos(2*pi*(F-Fdelta/2)/Fs*(0:N-1));
h_high = cos(2*pi*(F+Fdelta/2)/Fs*(0:N-1));
Justera paramertrarna efter dina värden. Ut kommer reella filterkoefficienter. Exempel på hur överföringsfunktionerna ser ut:
bandpass.jpg
(Och jag undrar om inte din centerfrekvens är 1385Hz :wink: )
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
AndersG
EF Sponsor
Inlägg: 8477
Blev medlem: 25 februari 2008, 17:10:58
Ort: Mariehamn
Kontakt:

Re: Nödvändig bandbredd för FSK?

Inlägg av AndersG »

Och jag undrar om inte din centerfrekvens är 1385Hz
Det jag spelar in från HF3an kommer ju att bero på hur jag rattat BFOn. Jag avstämmer den till 517kHz så då borde jag få 1000Hz, men sedan skruvar man ju på BFOn (Clarify) så det låter bra :)

I den egna mottagaren borde jag ha en kristallstyrd LO på 517 eller 519 så där bör jag hamna rätt nära 1kHz.
Användarvisningsbild
AndersG
EF Sponsor
Inlägg: 8477
Blev medlem: 25 februari 2008, 17:10:58
Ort: Mariehamn
Kontakt:

Re: Nödvändig bandbredd för FSK?

Inlägg av AndersG »

@YD1150
BLOCK_LENGTH kan vara 1 om man vill filtrera ett "sampel" i taget, och då
trillar det ut ett ur filtret.
OK. Så det är i det fallet att man tex har ADn att plocka 16 samples och lägga i en buffert. Jag antar att det är effektivare än att ta ett sampel åt gången?

När jag kikade i koden (FIR är skrivet i Assembler och använder dsPICens funktioner för multiply and accumulate samt modulo-adressering för ringbufferten så noterar jag att man definierar ett "delayminne" i filterstrukturen. Jag antar att det är det minnet som hanterar multiplikationen mot a, a-1, a-2 etc?

Skall koppla upp en dsPIC på labplatta och med en MCP4822 D/A som utgång så jag kan testa litet mera i realtid.
Användarvisningsbild
YD1150
Inlägg: 1944
Blev medlem: 29 oktober 2010, 22:41:10

Re: Nödvändig bandbredd för FSK?

Inlägg av YD1150 »

Ja det ska gå bra och filtrera dem i en klump åt gången.
Sen gäller det att mata ut dem i rätt takt till D/A-omvandlaren, blir något buffert-aktigt där.
Jag använde ett sampel i taget för det vart enklast för det jag gjorde.

Jag använde MCP4821 och den fungerar bra ihop med dsPIC.
Användarvisningsbild
AndersG
EF Sponsor
Inlägg: 8477
Blev medlem: 25 februari 2008, 17:10:58
Ort: Mariehamn
Kontakt:

Re: Nödvändig bandbredd för FSK?

Inlägg av AndersG »

4822 är väl identisk, men har två kanaler.
Användarvisningsbild
AndersG
EF Sponsor
Inlägg: 8477
Blev medlem: 25 februari 2008, 17:10:58
Ort: Mariehamn
Kontakt:

Re: Nödvändig bandbredd för FSK?

Inlägg av AndersG »

Justera paramertrarna efter dina värden. Ut kommer reella filterkoefficienter.
Snyyyyyyggggt! :)

Edit:
Om jag skulle få önska en sak till är en omvandling från decimaltal till "fractional" (1.15)
Användarvisningsbild
AndersG
EF Sponsor
Inlägg: 8477
Blev medlem: 25 februari 2008, 17:10:58
Ort: Mariehamn
Kontakt:

Re: Nödvändig bandbredd för FSK?

Inlägg av AndersG »

OK. Det tar sig. Två filter med mittfrekvens 1300 och 1470 puttas ut på D/A-omvandlarens båda kanaler.

Återstår envelopp och logik, typ att hi != lo annars är signalen ogiltig.

Om jag skulle få filtervärdena direkt i fract-format skulle jag slippa lagra dem som flyttal och sedan flytta över dem.

Kod: Markera allt

/*
 * File:   main.c
 *
 * Created on den 21 augusti 2017, 19:46
 */

//
// DSPTest for 28-pin dsPIC 30f2011
//
// 20170821
//

// DSPIC30F2011 Configuration Bit Settings

// 'C' source line config statements

// FOSC
#pragma config FOSFPR = XT_PLL8         // Oscillator (XT w/PLL 48)
#pragma config FCKSMEN = CSW_FSCM_OFF   // Clock Switching and Monitor (Sw Disabled, Mon Disabled)

// FWDT
#pragma config FWPSB = WDTPSB_16        // WDT Prescaler B (1:16)
#pragma config FWPSA = WDTPSA_512       // WDT Prescaler A (1:512)
#pragma config WDT = WDT_OFF            // Watchdog Timer (Disabled)

// FBORPOR
#pragma config FPWRT = PWRT_64          // POR Timer Value (64ms)
#pragma config BODENV = BORV20          // Brown Out Voltage (Reserved)
#pragma config BOREN = PBOR_ON          // PBOR Enable (Enabled)
#pragma config MCLRE = MCLR_EN          // Master Clear Enable (Enabled)

// FGS
#pragma config GWRP = GWRP_OFF          // General Code Segment Write Protect (Disabled)
#pragma config GCP = CODE_PROT_OFF      // General Segment Code Protection (Disabled)

// FICD
#pragma config ICS = ICS_PGD            // Comm Channel Select (Use PGC/EMUC and PGD/EMUD)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include "common.h"
#include <xc.h>

#include <p30f2011.h>

#include <dsp.h>

#include "spi_dspic30.h"
#include "ADC.h"


#define BLOCK_LENGTH  1
#define TAPS          80
// http://www.microchip.com/forums/m152177.aspx


__psv__ float __attribute__ ((space(psv))) raw_coef_lo[80] = {
    1.0000e+000, 5.2250e-001, -4.5399e-001, -9.9692e-001, -5.8779e-001, 3.8268e-001, 9.8769e-001,
  6.4945e-001, -3.0902e-001, -9.7237e-001, -7.0711e-001, 2.3345e-001, 9.5106e-001, 7.6041e-001,
  -1.5643e-001, -9.2388e-001, -8.0902e-001, 7.8459e-002, 8.9101e-001, 8.5264e-001, -9.8036e-016,
  -8.5264e-001, -8.9101e-001, -7.8459e-002, 8.0902e-001, 9.2388e-001, 1.5643e-001, -7.6041e-001,
  -9.5106e-001, -2.3345e-001, 7.0711e-001, 9.7237e-001, 3.0902e-001, -6.4945e-001, -9.8769e-001,
  -3.8268e-001, 5.8779e-001, 9.9692e-001, 4.5399e-001, -5.2250e-001, -1.0000e+000, -5.2250e-001,
  4.5399e-001, 9.9692e-001, 5.8779e-001, -3.8268e-001, -9.8769e-001, -6.4945e-001, 3.0902e-001,
  9.7237e-001, 7.0711e-001, -2.3345e-001, -9.5106e-001, -7.6041e-001, 1.5643e-001, 9.2388e-001,
  8.0902e-001, -7.8459e-002, -8.9101e-001, -8.5264e-001, -4.1643e-015, 8.5264e-001, 8.9101e-001,
  7.8459e-002, -8.0902e-001, -9.2388e-001, -1.5643e-001, 7.6041e-001, 9.5106e-001, 2.3345e-001,
  -7.0711e-001, -9.7237e-001, -3.0902e-001, 6.4945e-001, 9.8769e-001, 3.8268e-001, -5.8779e-001
  -9.9692e-001, -4.5399e-001, 5.2250e-001
};

__psv__ float __attribute__ ((space(psv))) raw_coef_hi[80] = {
    1.000000,  0.404344, -0.673013, -0.948600, -0.094108,  0.872496,  0.799685, -0.225801,
  -0.982287, -0.568562,  0.522499,  0.991100,  0.278991, -0.765483, -0.898028,  0.039260,
   0.929776,  0.712639, -0.353475, -0.998489, -0.453990,  0.631353,  0.964557,  0.148672,
  -0.844328, -0.831470,  0.171929,  0.970506,  0.612907, -0.474856, -0.996917, -0.331338,
   0.728969,  0.920845,  0.015707, -0.908143, -0.750111,  0.301538,  0.993961,  0.502266,
  -0.587785, -0.977600, -0.202787,  0.813608,  0.860742, -0.117537, -0.955793, -0.655400,
   0.425779,  0.999722,  0.382683, -0.690251, -0.940881, -0.070627,  0.883766,  0.785317,
  -0.248690, -0.986429, -0.549023,  0.542442,  0.987688,  0.256289, -0.780430, -0.887413,
   0.062791,  0.938191,  0.695913, -0.375416, -0.999507, -0.432873,  0.649448,  0.958073,
   0.125333, -0.856718, -0.818150,  0.195090,  0.975917,  0.594121, -0.495459, -0.994792 

};
fractional inputSignal[NUMSAMP];
fractional outputSignal[NUMSAMP];
fractional outputSignal2[NUMSAMP];
fractional* oPtr;
fractional* iPtr;
unsigned int doFilterFlag;

fractional delay1[TAPS] __attribute__ ((space(ymemory), aligned (32)));
fractional coeffs1[TAPS] __attribute__ ((space(xmemory), aligned (32)));
fractional delay2[TAPS] __attribute__ ((space(ymemory), aligned (32)));
fractional coeffs2[TAPS] __attribute__ ((space(xmemory), aligned (32)));

FIRStruct filter1;
FIRStruct filter2;

int main(void) {

    int i;
    float x;
    //
    TRISDbits.TRISD0 = 0;
    LATBbits.LATB0 = 1;
    //
    outputSignal[0] = 0;
    spi_setup();
    
 	//convert float coefficients to fract
 	for(i=0;i<TAPS;i++)
    {
        x = raw_coef_hi[i];
        coeffs1[i]=Float2Fract(x);
        x = raw_coef_lo[i];
        coeffs2[i]=Float2Fract(x);
    }
 	//init filter
    FIRStructInit(&filter1,TAPS,coeffs1,0xFF00,delay1);
    FIRStructInit(&filter2,TAPS,coeffs2,0xFF00,delay2);
    FIRDelayInit(&filter1);
    FIRDelayInit(&filter2);
    //
    ADC_Init();             //Initialize the A/D converter, last!
    while(1)
    {
        if (doFilterFlag)
        {
                //Filter a block of NUMSAMP samples using FIR
                //
                FIR(1, &outputSignal[0], &inputSignal[0], &filter1);
                FIR(1, &outputSignal2[0], &inputSignal[0], &filter2);
                spi_send((outputSignal[0]^0x8000)>>4);
                spi_send2((outputSignal2[0]^0x8000)>>4);  // Data it 10-bit, left adjusted
                //
                doFilterFlag = 0;
                iPtr = &inputSignal[0];
        }
    }
    return 0;
}
Användarvisningsbild
YD1150
Inlägg: 1944
Blev medlem: 29 oktober 2010, 22:41:10

Re: Nödvändig bandbredd för FSK?

Inlägg av YD1150 »

Några rader Matlab-kod levereras "as-is".

h_low och h_high är filterkoefficienterna typ 80st eller så, bara reella tal.

Funktionen 16int_to_hex var något jag tankade hem nån gång.

Kod: Markera allt


Bits=16;

Navtex_16bit_Coeffs_lo = round(2*(((2^Bits)-1)*h_low)/sum(abs(h_low)));
Navtex_16bit_Coeffs_hi = round(2*(((2^Bits)-1)*h_low)/sum(abs(h_high)));

% Write to file
F_ID=fopen('Navtex_filter_coefficients.txt','w+');
fprintf(F_ID, '// ***** MPLAB Navtex filter coefficients for dsPIC *****\n\n');
fprintf(F_ID,'\n');


fprintf(F_ID,'// No of coefficients %i \n\n\n', length(Navtex_16bit_Coeffs_lo));


stopp=0;

fprintf(F_ID,'// Low tone coefficients\n');

for j=1:length(Navtex_16bit_Coeffs_lo)
    
    if ( stopp==0 )
        fprintf(F_ID, '.hword ');
    end
       
     if ( stopp==7 )
        fprintf(F_ID, '0x'); 
        fwrite(F_ID, int16_to_hex(Navtex_16bit_Coeffs_lo(j)) );
        fprintf(F_ID, ' \n');
        stopp=0;
    else
        fprintf(F_ID, '0x');
        fwrite(F_ID, int16_to_hex(Navtex_16bit_Coeffs_lo(j)) );
        if (j==length(Navtex_16bit_Coeffs_lo))
            fprintf(F_ID, ' ');
        else
            fprintf(F_ID, ', ');
        end    
        stopp=stopp+1;     
    end
   
end

fprintf(F_ID,'\n\n\n\n\n');

fprintf(F_ID,'// High tone coefficients\n');


for j=1:length(Navtex_16bit_Coeffs_hi)
    
    if ( stopp==0 )
        fprintf(F_ID, '.hword ');
    end
      
     if ( stopp==7 )
        fprintf(F_ID, '0x'); 
        fwrite(F_ID, int16_to_hex(Navtex_16bit_Coeffs_hi(j)) );
        fprintf(F_ID, ' \n');
        stopp=0;
    else
        fprintf(F_ID, '0x');
        fwrite(F_ID, int16_to_hex(Navtex_16bit_Coeffs_hi(j)) );
        if (j==length(Navtex_16bit_Coeffs_hi))
            fprintf(F_ID, ' ');
        else
            fprintf(F_ID, ', ');
        end    
        stopp=stopp+1;     
    end
   
end


fprintf(F_ID,'// End of file');
fprintf(F_ID,'\n');
fclose(F_ID);


Nu ska det ha trillat ut en textfil i andra änden.
Som ser ut så här:

Kod: Markera allt

// ***** MPLAB Navtex filter coefficients for dsPIC *****


// No of coefficients 80 


// Low tone coefficients
.hword 0x09f5, 0x077f, 0x0153, 0xfa80, 0xf665, 0xf70a, 0xfc1e, 0x031d 
.hword 0x0892, 0x09ca, 0x062a, 0xff7e, 0xf912, 0xf613, 0xf7fd, 0xfdde 
.hword 0x04cc, 0x095b, 0x094a, 0x04a0, 0xfdad, 0xf7e0, 0xf618, 0xf936 
.hword 0xffb0, 0x0651, 0x09d3, 0x0879, 0x02ee, 0xfbf0, 0xf6f5, 0xf673 
.hword 0xfaaa, 0x0185, 0x07a0, 0x09f5, 0x075e, 0x0122, 0xfa56, 0xf658 
.hword 0xf720, 0xfc4c, 0x034d, 0x08ab, 0x09c0, 0x0603, 0xff4c, 0xf8ee 
.hword 0xf610, 0xf81b, 0xfe0f, 0x04f8, 0x096c, 0x0937, 0x0474, 0xfd7c 
.hword 0xf7c3, 0xf61d, 0xf95b, 0xffe2, 0x0678, 0x09db, 0x085e, 0x02be 
.hword 0xfbc2, 0xf6e0, 0xf681, 0xfad4, 0x01b6, 0x07bf, 0x09f3, 0x073c 
.hword 0x00f0, 0xfa2e, 0xf64c, 0xf738, 0xfc7b, 0x037c, 0x08c4, 0x09b6 





// High tone coefficients
.hword 0x0a09, 0x078e, 0x0156, 0xfa75, 0xf652, 0xf6f8, 0xfc16, 0x0323 
.hword 0x08a3, 0x09dd, 0x0637, 0xff7d, 0xf904, 0xf600, 0xf7ed, 0xfdd9 
.hword 0x04d6, 0x096e, 0x095c, 0x04a9, 0xfda8, 0xf7d0, 0xf604, 0xf929 
.hword 0xffaf, 0x065e, 0x09e6, 0x0889, 0x02f3, 0xfbe8, 0xf6e3, 0xf660 
.hword 0xfa9f, 0x0188, 0x07af, 0x0a09, 0x076c, 0x0124, 0xfa4b, 0xf645 
.hword 0xf70f, 0xfc45, 0x0353, 0x08bd, 0x09d4, 0x060f, 0xff4b, 0xf8e0 
.hword 0xf5fc, 0xf80c, 0xfe0b, 0x0502, 0x097f, 0x0949, 0x047c, 0xfd77 
.hword 0xf7b3, 0xf60a, 0xf94e, 0xffe2, 0x0684, 0x09ee, 0x086e, 0x02c3 
.hword 0xfbba, 0xf6ce, 0xf66e, 0xfaca, 0x01ba, 0x07cf, 0x0a07, 0x074a 
.hword 0x00f2, 0xfa22, 0xf639, 0xf726, 0xfc74, 0x0383, 0x08d5, 0x09c9 
// End of file

Bara att klippa och klistra in i MPLAB som jag använder till dsPIC.
Går så oerhört mycket snabbare än att manuellt översätta varenda tal.
Samt risken att skriva fel, som ger något filter med okänt passband. :)
xxargs
Inlägg: 10183
Blev medlem: 23 september 2006, 14:28:27
Ort: Södertälje

Re: Nödvändig bandbredd för FSK?

Inlägg av xxargs »

AndersG skrev:OK. Det tar sig. Två filter med mittfrekvens 1300 och 1470 puttas ut på D/A-omvandlarens båda kanaler.

Återstår envelopp och logik, typ att hi != lo annars är signalen ogiltig.

Det är väl snarare att du skall jämför av värdet på hi och och lo och den som har mest värde (= mest signalenergi samlad) bestämmer om signalen skall gå mot plus (hi är högst) eller mot minus (lo är högst) - precis som en komparator - dvs. ingången med högst värde 'vinner' - är det plusingången högre än minusingången så driver det utgången hög, är det minus ingången högre än plusingången så drivs utgången mot låg.

på en analog komparator så är intervallet för Hi==Lo extremt litet i och med väldigt hög förstärkning så för det mesta så har det valt utgången hög eller låg även om spänningsskillnaden mellan ingångarna kan räknas i delar av µV (i verkligheten så brusar det friskt när det slår mellan ändlägena på utgången pga termiska bruset in på signalen och i själva komparatorn)

Försöker du 'digitalisera' det här innan beslut (komparatorn) så förlorar du mycket av vinsten som du gör med den här 'analoga' mottagningsmodellen.
Skriv svar