大致要求:設(shè)計(jì)一個(gè)FSK調(diào)制解調(diào)器,基帶信號(hào)碼速率為2000B/s,載波速率為4khz和8khz,解調(diào)信號(hào)要能完整還原基帶信號(hào)。實(shí)現(xiàn)方法多種多樣,通信領(lǐng)域內(nèi)調(diào)制解調(diào)器的設(shè)計(jì)大多數(shù)用的都是硬件電路,鑒于筆者對(duì)編程情有獨(dú)鐘(其實(shí)筆者還是懂一點(diǎn)電路設(shè)計(jì)知識(shí)的~),所以最終決定用stm32來設(shè)計(jì),純編程實(shí)現(xiàn)。看起來高大上,但實(shí)際做起來不難,不過有挺多東西要考慮的。
總的設(shè)計(jì)思路如下:
首先是基帶信號(hào)的產(chǎn)生,它也是我們要調(diào)制和解調(diào)的目標(biāo)。基帶信號(hào)由一連串隨機(jī)的碼元序列構(gòu)成,為了模擬隨機(jī)的碼元序列,筆者用定時(shí)器設(shè)計(jì)8位的PN碼序列,碼元速率為2000B/s。定時(shí)器3定時(shí)0.5ms,每進(jìn)入一次中斷,變量num加一,設(shè)置一次IO引腳電平,8位PN碼只需設(shè)置8次,然后num清零。
TIM3_Init(499,71); ? ? ? ? ? ? ? ? ? ? ? ?//基帶信號(hào)
u8 num=0;
void TIM3_IRQHandler(void) ??
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
{
num++;
switch (num)
{
case 1: Base_Signal = 1; ? ? ? ?break;
case 2: Base_Signal = 0; ? ? ? ?break;
case 3: Base_Signal = 0; ? ? ? ?break;
case 4: Base_Signal = 0; ? ? ? ?break;
case 5: Base_Signal = 1; ? ? ? ?break;
case 6: Base_Signal = 0; ? ? ? ?break;
case 7: Base_Signal = 1; ? ? ? ?break;
case 8: Base_Signal = 0; ? ? ? ?break; ? ? ? ? ? ? ? ?//pn碼序列
}
if(num == 8)
num = 0; ? ? ? ? ? ? ? ?
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); ?
}
}
接下來要產(chǎn)生載波,載波就是正弦波無疑。這里筆者的載波頻率要求是4khz和8khz。正弦波的產(chǎn)生用的是stm32的DMA+DAC+TIM2。正弦波的數(shù)據(jù)用正弦波數(shù)據(jù)發(fā)生器產(chǎn)生,采樣點(diǎn)數(shù)64,精度12位,保存在Sine12bit[]數(shù)組,但是傳送給DMA的正弦波數(shù)據(jù)不是這些原始的數(shù)據(jù),而是將這些數(shù)據(jù)進(jìn)行了進(jìn)一步的處理:
uint16_t Sine12bit[64] = {
0x7FF,0x8C8,0x98E,0xA51,0xB0F,0xBC4,0xC71,0xD12,0xDA7,0xE2E,0xEA5,0xF0D,0xF63,0xFA6,0xFD7,0xFF5
,0xFFE,0xFF5,0xFD7,0xFA6,0xF63,0xF0D,0xEA5,0xE2E,0xDA7,0xD12,0xC71,0xBC4,0xB0F,0xA51,0x98E,0x8C8
,0x7FF,0x736,0x670,0x5AD,0x4EF,0x43A,0x38D,0x2EC,0x257,0x1D0,0x159,0x0F1,0x09B,0x058,0x027,0x009
,0x000,0x009,0x027,0x058,0x09B,0x0F1,0x159,0x1D0,0x257,0x2EC,0x38D,0x43A,0x4EF,0x5AD,0x670,0x736
};
uint32_t Idx = 0;
int main(void)
{
評(píng)論