element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Test & Tools
  • Technologies
  • More
Test & Tools
Blog Using a MAX2870 Frequency Synthesizer / Signal Generator
  • Blog
  • Forum
  • Documents
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Test & Tools to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: shabaz
  • Date Created: 19 Feb 2024 9:20 PM Date Created
  • Views 9704 views
  • Likes 13 likes
  • Comments 18 comments
  • signal generator
  • MAX2870
  • frequency_generator
  • frequency synthesizer
  • rf
  • MAX2871
Related
Recommended

Using a MAX2870 Frequency Synthesizer / Signal Generator

shabaz
shabaz
19 Feb 2024

Table of Contents

  • Introduction
  • What Is It?
  • Is it a Sine Wave?
  • Using It
  • Measurements
  • Problems
  • Recommended or Not?
  • Summary

Introduction

I have a few simple tools for generating RF signals, and they all have benefits and disadvantages. I recently decided to give a frequency synthesizer a shot. Could it be used as a crude RF signal generator tool? Time to investigate! This blog post shows the key findings.

image

As will be seen, the results are generally very good, however, there are some problems too, and in terms of price-performance, I have alternative suggestions that I think are much better.

What Is It?

It’s a board based around a MAX2870 frequency synthesizer chip (PDF datasheet), which generates a signal at a chosen frequency in the range of 23.5 MHz to 6 GHz. That’s it, pretty much! The touch-screen menu allows users to choose a fixed frequency or perform a sweep operation. Several output power levels are selectable (four settings, supposedly in steps of 3 dB). The device is powered via USB. It should be possible to control the device frequency via USB, but I could not figure that out.

Internally, the MAX2870 uses a phase-locked loop (PLL) and it contains an integrated oscillator (VCO), so that very little external parts are needed; the main external thing that is required is the PLL loop filter (a network of resistors and capacitors).

image

The underside of the device has a removable PCB cover. In the photo below, the right side of the board contains the MAX2870 chip. Underneath the LCD flat-flex, is a GD32F103 chip (near-identical to STM32F103).

image

Is it a Sine Wave?

It is not. And that’s quite normal. It is closer to a square wave. Sometimes, you might actually want a square wave, for instance, if you’re driving some RF mixers. Furthermore, it’s often not such a big deal to convert to a sine wave by filtering off the harmonics. What can be more important is where the ‘spurs’ are, which are spurious unwanted signals that could be more difficult to filter out easily. Unfortunately most frequency synthesizers will generate spurs, and often the desire is to try to aim to have the spurs at frequencies that matter less.

Using It

It’s ultra simple to operate. I plugged a USB Type A to USB-C cable into a phone charger, and used it to power up the board (Note: a USB-C to USB-C cable will not work; the board is not wired up for that unfortunately).

Immediately, a menu appears, and it’s all self-explanatory. This is an instrument that can be learned and operated within seconds.

image

Measurements

I connected the output of the MAX2870 board to the spectrum analyzer (through a 20 dB attenuator since it’s good to be overly cautious when connecting something unknown; the measurements are compensated for that, so you don’t need to add 20dB to the values!).

The board has a 25 MHz crystal, and there is undoubtedly noticeable drift as expected while the board warms up, so it’s best not to use it for ten minutes or so.

First off, I decided to look at things from a distance, i.e., across a very wide frequency spectrum, to observe the level of harmonics where possible and just to see if there was anything too unusual going on! All looked good.

image

image

Next, it was time to zoom in and see things close-up; I used the same spot frequencies. The charts below show 100 kHz of spectrum, apart from the last trace, which shows 200 kHz of spectrum.

image

image

As can be seen from those spectrum traces, the fundamental output is quite constant. There isn’t much variation (about 1 dB) across almost the entire range of the frequency synthesizer. There’s only slightly more drop beyond 4 GHz, but it’s not much. For these measurements, I used a 0.6 m length of double-shielded RG316 coax, so there will be some loss there too. The visible spurs are quite low, they don't have a lot of power, especially for the low frequencies, and VHF. 

For all the measurements above, I used the maximum output setting on the board, which is labeled +5 dBm, which isn’t actually the case, as can be seen. I’m not sure of the reason (the MAX2870 datasheet is confusing; it suggests that the single-ended output power is the same as the differential configuration). The four overlaid traces show the effect of the four configurable output levels at four close-together spot frequencies. At this frequency range ballpark, the output measured from -6 dBm to +0.25 dBm across the four configurable levels.

image

Problems

I think these are the main problems with the device:

1. From the menu, frequencies can be entered in steps of 10 kHz, however, beyond some point past a GHz (I didn’t try to narrow it down) only 20 kHz steps are supported, even though the user can still enter values with 10 kHz steps. For those keen to use the board as a frequency synthesizer for radio communication, the 10 kHz minimum granularity could be an issue (it depends on whether the demodulation method will be analog, or software-defined).

2. The sweep function (see the photo below to see how part of the configuration is set) isn’t as useful as it could have been. It only works in steps of 1 MHz, even though the user can enter values with 10 kHz granularity. It’s also buggy, for instance, the start and stop frequencies are never reached, just the in-between values, and sometimes I needed to restart the unit when reconfiguring the settings. If 1 MHz or higher sweep steps are acceptable, then the MAX2870 is quite fast at switching frequencies. It was possible to step across large frequency ranges (hundreds of MHz) with steps of just a few milliseconds.

3. The output could have been much better. The design uses a single-ended output. It would have improved the signal quality if there had been a transformer on the differential output.

4. The lack of documentation about the USB control!

5. Not a top-quality design. If you tap the device, it affects the output slightly. The loop filter capacitors could be upgraded to NP0/C0G, perhaps.


There are a few minor issues, too; for instance, there was a typo on the main menu! The button to stop the output was labeled ‘Quite’. There’s actually a quick fix for that; the microcontroller isn’t protected, and it is possible to read the contents (using any 'SWD' programming tool), and edit the text string in the binary data, and then re-write it to the chip. Mine is now labelled ‘Halt ‘.

image

There are also a few minor software bugs, but powering off/on solves that. Incidentally, the device remembers the previous settings, so they are stored in non-volatile memory.

image

Recommended or Not?

For the above reasons, I’d have to say no. While it is a very convenient-to-use device, with actually very decent signal quality, and with a nice simple user interface, I don’t think it is worth the 45 GBP asking price. I think it would be far better to buy a MAX2870 board (or just the chip, but availability isn’t always good) and add your own microcontroller to it. The photo below shows there's really not much to it. Another benefit of doing that is then the frequency selection granularity can be increased, rather than be restricted to 10 kHz steps. If a custom board was to be made, then the MAX2871 is pin and software compatible, but with better performance.

image

There are also other options. For low frequencies, up to a few tens of MHz, direct digital synthesis is low-cost. Typical ICs to check out are AD9850 and AD9834. The AD995x series (e.g. AD9954) are great for up to 100 MHz or so.

For frequencies up to about 200 MHz, the Si5351 is usually an excellent choice. There’s some maths involved to control it, but it’s a solved problem, with plenty of open source code available.

Summary

The MAX2870 board that I tried had decent signal quality, and had an easy-to-use touchscreen interface, but it doesn’t justify the cost. It’s great to be able to have the access to signals across a huge range (21.5 to 6000 MHz), but there are better ways to get this capability. Personally I think it’s more worthwhile to buy a MAX2870 IC or a breakout board for it, and then add your own microcontroller and user interface.

Thanks for reading!

  • Sign in to reply

Top Comments

  • shabaz
    shabaz over 1 year ago +1
    I figured it is possible to do much better than that design, with some teamwork.. It would be awesome to have 10 GHz or so (there is a ham band of interest there!), but the freq synth chips for that…
  • shabaz
    shabaz over 1 year ago in reply to Jan Cumps

    Very good! I'll read up on it tonight, and move the pin assignments so we have that capability. Also thinking maybe the 5V input can be potential divided and put into an ADC pin since that's also a monitoring type of thing, and can just flash a different pattern or have a third LED for that.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps over 1 year ago in reply to shabaz

    Non-interrupt alternative: I'm reading up on the generic timer peripherals of the CH32. If one of them can be used to validate if an input (the LD output) has been pulsing.

    They support input capture mode, that could (maybe?) be used to check if an edge has occurred at the input, in the super-loop instead of with an interrupt.

    If the current counter value <> previous, then there was at least one LD pulse...

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • shabaz
    shabaz over 1 year ago

    Reading up a bit more, both the MAX2870 and the ADF4001 have a configurable lock-detect (LD) output pin. which can be set in two modes; digital, and analog-sourced (the output is digital in both cases, but the analog lock detect is supposedly more accurate). I wanted to have an LED that would indicate both out-of-lock, and unconfigured state (i.e. board powered up but no SPI config done), which is hard to do without using the analog detected version, which outputs narrow pulses when locked.

    I figure it is a nice opportunity to learn how to use interrupts and try to use the CH32V003, as a 'monitor' chip. It will be programmed to detect pulses, and if it finds them, then the LED will be turned off. If the pulses disappear, then the LED blinks fast as a warning that something is wrong. This will be optional functionality, since it is only monitoring and not controlling anything other than the LEDs.

    I've tested this source code (just with pulses from a sig-gen, I've no idea how narrow the pulses will be in real life, but if it doesn't work, then I can always switch it to the (perhaps less accurate) digital lock detect with just a code change.

    /********************************
     * main.c
     * synth_monitor
     * rev 1 - shabaz - Feb 2024
     ********************************/
    
    /*****************************************************
     * Connections
     * PC0 - ADF4001 MUX pin (Lock Detect) input
     * PC1 - MAX2870 LD pin (Lock Detect) input
     * PC3 - AD_OOL (ADF4001 Out of Lock LED output)
     * PC4 - AD_OOL (MAX2870 Out of Lock LED output)
     *****************************************************/
    
    // ************ includes *************************
    #include "debug.h"
    
    // ************ defines **************************
    #define FOREVER 1
    #define TIMER_START_VAL 10
    #define LED_PC3_ON GPIO_SetBits(GPIOC, GPIO_Pin_3);
    #define LED_PC3_OFF GPIO_ResetBits(GPIOC, GPIO_Pin_3);
    #define LED_PC4_ON GPIO_SetBits(GPIOC, GPIO_Pin_4);
    #define LED_PC4_OFF GPIO_ResetBits(GPIOC, GPIO_Pin_4);
    
    // ************ global variables *****************
    uint16_t hold_timer_0 = 0;
    uint16_t hold_timer_1 = 0;
    uint8_t led_pc3_state = 0;
    uint8_t led_pc4_state = 0;
    
    // ************ function prototypes ***************
    void EXTI7_0_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
    
    
    // ****************** functions *******************
    void pc3_toggle_led(void) {
        led_pc3_state ^= 1;
        if (led_pc3_state) {
            LED_PC3_ON;
        } else {
            LED_PC3_OFF;
        }
    }
    
    void pc4_toggle_led(void) {
        led_pc4_state ^= 1;
        if (led_pc4_state) {
            LED_PC4_ON;
        } else {
            LED_PC4_OFF;
        }
    }
    
    void out_gpio_init(void) {
        GPIO_InitTypeDef GPIO_InitStructure = {0};
    
        // enable periph clock for GPIOC
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    
        // configure PC3 as output
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_Init(GPIOC, &GPIO_InitStructure);
    
        // configure PC4 as output
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_Init(GPIOC, &GPIO_InitStructure);
    }
    
    void ext_int_init(void) {
        GPIO_InitTypeDef GPIO_InitStructure = {0};
        EXTI_InitTypeDef EXTI_InitStructure = {0};
        NVIC_InitTypeDef NVIC_InitStructure = {0};
    
        // enable periph clock for AFIO and GPIOC
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOC, ENABLE);
    
        // configure PC0 as input with pull-up
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_Init(GPIOC, &GPIO_InitStructure);
    
        // configure PC1 as input with pull-up
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_Init(GPIOC, &GPIO_InitStructure);
    
        // enable EXTI0 interrupt for PC0
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource0);
        EXTI_InitStructure.EXTI_Line = EXTI_Line0;
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
        EXTI_InitStructure.EXTI_LineCmd = ENABLE;
        EXTI_Init(&EXTI_InitStructure);
    
        // enable EXTI1 interrupt for PC1
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource1);
        EXTI_InitStructure.EXTI_Line = EXTI_Line1;
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
        EXTI_InitStructure.EXTI_LineCmd = ENABLE;
        EXTI_Init(&EXTI_InitStructure);
    
        NVIC_InitStructure.NVIC_IRQChannel = EXTI7_0_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
    
    }
    
    // **************** interrupt handlers *************
    void EXTI7_0_IRQHandler(void) {
        // PC0
        if(EXTI_GetITStatus(EXTI_Line0)!=RESET) // PC0 interrupt occurred
        {
            hold_timer_0 = TIMER_START_VAL;
            LED_PC3_OFF;
            EXTI_ClearITPendingBit(EXTI_Line0);  // clear interrupt flag
        }
        // PC1
        if (EXTI_GetITStatus(EXTI_Line1)!=RESET) // PC1 interrupt occurred
        {
            hold_timer_1 = TIMER_START_VAL;
            LED_PC4_OFF;
            EXTI_ClearITPendingBit(EXTI_Line1);  // clear interrupt flag
        }
    }
    
    // *************************************************************
    // ********************* main function *************************
    // *************************************************************
    
    int
    main(void)
    {
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        SystemCoreClockUpdate();
        Delay_Init();
    
        out_gpio_init(); // configure PC3 and PC4 as outputs (LEDs)
        ext_int_init(); // configure PC0 and PC1 as external interrupts
    
        // set hold timers to 0, i.e. assume both PLLs are out of lock
        hold_timer_0 = 0;
        hold_timer_1 = 0;
    
        while(FOREVER)
        {
            Delay_Ms(100);
            if (hold_timer_0) {
                hold_timer_0--;
            } else {
                pc3_toggle_led();
            }
            if (hold_timer_1) {
                hold_timer_1--;
            } else {
                pc4_toggle_led();
            }
        }
    
        return(0); // warning on this line is fine!
    }
    

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • shabaz
    shabaz over 1 year ago

    The proposed block diag.. it grew to three PLLs! This is the flow:

    * On-board 10 MHz oscillator module, plus the capability to attach an external reference

    * First PLL is used to generate a 27 MHz clock.

    * Second PLL is a Si5351 combined PLL+VCO which can be configured with decent granularity to anything up to around 150.000MHz. This PLL is optional, it can be omitted and bypassed if desired.

    * The output from the Si5351 (or the 27 MHz clock if the Si5351 is bypassed) clocks the MAX2870. The advantage of the Si5351 stage is that since it can be adjusted, that means we can achieve extremely high granularity (in the order of Hz or less). 

    image

    Although the design is now three times the size! I think it's worth it, since it allows very high granularity, suitable for any radio application, plus it can be locked to an external reference.

    Regarding the PLL loop filter for the ADF4001, I wasn't looking forward to trying to figure it out, but I used the ADIsimPLL software, it is very neat, it generates the circuit plus provides lots of useful info. Really impressed. This was its output:

    image

    image

    Putting it all together, here's the circuit. Very cramped! I might have to move to additional sheets, but I wanted to keep it to a single page if possible.

    I think everything is there, apart from the connector to be able to attach to a microcontroller. Anyway, I'll leave it in this state for a week or so, in case there are any errors or suggestions.

    image

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • shabaz
    shabaz over 1 year ago

    Been refreshing myself on PLL intricacies by reading up and writing some notes.

    image

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube