Возможно, что если тот код для 1200бод переложить на ассемблер современного Cortex-M примерно на 200МГц, то он вытянул-бы. biggrin.gif
Не хочу Вас расстраивать, но делал я как-то как раз гидроакустический модем, там была OFDM, скорость данных порядка 140кбит/с, полный дуплекс с несущими 500кГц и 1МГц (аплинк и даунлинк соответственно). Ну справедливости ради там перемножители были внешние. И внешний АЦП (банальный аудио-АЦП двухканальный), цифровать квадратуры уже после смесителя.
Работало это на 100МГц Cortex-M3 без особых проблем, без всякой плавающей точки, с загрузкой проца где-то в 30-40 процентов. Да-да, с Фурье вперед и назад, с эквалайзером и прочими необходимыми для OFDM пирогами.
А еще был другой, там именно GMSK был, на канале управления жил. Тоже, правда, с внешним АЦП, прямо цинично пьезокерамика на дифференциальный вход AK5384 была подключена. И несущая как раз была в районе 40кГц. Цифровал себе спокойно всю полосу, и дальше все по классике. Ну совсем же смешное было
#define F_CPU (100000000ULL)
#define RXLS_SAMPLE_RATE (97655ULL)
#pragma inline=forced
static long long QMULL(REG32 a, REG32 b, REG32 c, REG32 d)
{
long long r;
asm("SMULL %L0,%H0,%1,%2":"=Rp"®:"r"(a),"r"(
);
asm("SMLAL %L0,%H0,%1,%2":"+Rp"®:"r"©,"r"(d));
//return ((long long)a *
+ ((long long)c * d);
return r;
}
static long long FMULADD64(long long r, long long a, UREG32 k)
{
asm("SMLAL %L0,%H0,%H1,%2":"+Rp"®:"Rp"(a),"r"(k));
asm("UMULL %L0,%H0,%L0,%1":"+Rp"(a):"r"(k));
a+=0x80000000;
asm("ADDS %L0,%L0,%H1":"+Rp"®:"r"(a):"cc");
asm("ADC %H0,%H0,#0":"+Rp"®);
return r;
}
static long long FMULSUB64(long long r, long long a, UREG32 k)
{
asm("SMLAL %L0,%H0,%H1,%2":"+Rp"®:"Rp"(a),"r"(-k));
asm("UMULL %L0,%H0,%L0,%1":"+Rp"(a):"r"(k));
a+=0x80000000;
asm("SUBS %L0,%L0,%H1":"+Rp"®:"r"(a):"cc");
asm("SBC %H0,%H0,#0":"+Rp"®);
return r;
}
#pragma inline=forced
static inline REG32 EXPDIVfast(long long f, unsigned long long a)
{
UREG ea;
UREG32 a32=a>>32;
REG32 f32=f>>32;
if (a32)
{
ea=__CLZ(a32);
a32=(a32<<ea)|((unsigned long)a>>(32-ea));
ea--;
f32=(f32<<ea)|((unsigned long)f>>(32-ea));
}
else
{
a32=a;
f32=f;
ea=__CLZ(a32);
a32=a32<<ea;
ea--;
f32=f32<<ea;
}
a32>>=16+1;
if (a32)
return (f32/(REG32)a32)<<8;
else
return 0;
}
#define DEFAULT_FREQ_HZ (32010ULL)
#define DEFAULT_FREQ ((DEFAULT_FREQ_HZ<<32)/RXLS_SAMPLE_RATE)
UINT32 freq_a=DEFAULT_FREQ;
UINT32 phase_a;
#define CHLPF_SHIFT (27)
#define CHLPF_PREGAIN_SHIFT (27)
//1.5kHz, 1dB, 5 poles, Z-transform
#define CHLPF_K0 ( 961)
#define CHLPF_K1 ( 98213853)
#define CHLPF_K2 ( 521724849)
#define CHLPF_K3 ( 1109599598)
#define CHLPF_K4 ( 1181066974)
#define CHLPF_K5 ( 629195138)
void I2S_IRQHandler(void)
{
REG32 rxsig;
rxsig=I2SRXFIFO;
REG32 I;
REG32 Q;
UREG32 vo=phase_a;
I=rxsig*SIN8[(vo+0x00000000)>>24];
Q=rxsig*SIN8[(vo+0x40000000)>>24];
phase_a=vo+freq_a;
//Filter I
{
static signed long long y1,y2,y3,y4,y5;
signed long long result;
result=(long long)I*CHLPF_K0;
result=FMULADD64(result, y1,CHLPF_K1);
result=FMULSUB64(result,y1=y2,CHLPF_K2);
result=FMULADD64(result,y2=y3,CHLPF_K3);
result=FMULSUB64(result,y3=y4,CHLPF_K4);
result=FMULADD64(result,y4=y5,CHLPF_K5);
y5=result<<(32-CHLPF_SHIFT);
I=(INT32)(result>>(CHLPF_SHIFT-1));
}
//Filter Q
{
static signed long long y1,y2,y3,y4,y5;
signed long long result;
result=(long long)Q*CHLPF_K0;
result=FMULADD64(result, y1,CHLPF_K1);
result=FMULSUB64(result,y1=y2,CHLPF_K2);
result=FMULADD64(result,y2=y3,CHLPF_K3);
result=FMULSUB64(result,y3=y4,CHLPF_K4);
result=FMULADD64(result,y4=y5,CHLPF_K5);
y5=result<<(32-CHLPF_SHIFT);
Q=(INT32)(result>>(CHLPF_SHIFT-1)); //Без одного защитного бита
}
//Demodulation
{
static INT32 I1,Q1;
REG32 id,qd;
id=I-I1; I1=I;
qd=Q-Q1; Q1=Q;
long long f=QMULL(-I,qd,Q,id);
unsigned long long a=QMULL(I,I,Q,Q);
lsrx_lvl_a=a;
//Qdata=-EXPDIVfast(f,a);
Qdata=f>0?-0x200000:0x200000;
}
... все, тут уже разбор чисто с цифровым потоком, 0/1 это Qdata<0 или >0
}
Передатчик лучше ЦАП-ом.
Нафиг он там не нужен. Делаются таблички для для плавного по Гауссу изменения фазы ШИМ в вариантах переходов бит 0->1 и 1->0 и все.
И 12 бит разрядности АЦП (которая обычно бывает в МК) может не хватить для обеспечения динамического диапазона и чувствительности.