• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

NS73M Controller - FM Transmitter

    Blog entry posted in 'Electronics and Other Ramblings...', October 01, 2011.

    Working on a few things here and there I came across the NS73M. It is a pretty nifty FM transmitter, which when used with the breakout board seems to have quite a bit of potential. Looking around the web there are a few examples for using these IC:


    These, and the Sparkfun example, were my starting points. First shots at it were not really successful, mainly I did not really wire the stuff right; and the code wasn't really correct. So I re-read the code examples, read the datasheet (it's not the best piece of documentation out there - so it's a bit of a read) and attempted to talk to the IC again. The setup I used was:

    • 16F690 - quite overkill for this
    • std breadboard
    • PICKIT2 for programming and debugging
    • NS73M breakout board
    • Oshonsoft PIC Basic

    The following things helped properly setup the IC for proper operation:

    • Set IIC input to zero/gnd - this sets the NS73M for serial communications similar to SPI (note that I say similar and not identical)
    • Make sure the communication to the NS73M follows the correct format: address first (LSB first), followed by data (LSB first)
    • Make sure to drive the audio inputs with a high enough level.

    Originally I setup the NS73M to require 200mV for 100%modulation - why? Because I quickly scanned the datasheet without really understanding how the part works. What this truly meant was that I had to drive the NS73M inputs harder to get the modulator to work. Driving the inputs from a small MP3 player was not helping the case. So I changed the NS73M setup so that the modulator would operate at 100mV audio inputs; what a difference that made. It went from not working (i.e. not hearing anything) to wow, it works. Granted this is nothing to write your mom or grandma about, but it's a start. The following figure shows what the controller looks like.



    The code defaults to 93.9MHz, and it is capable tuning the radio in 200kHz steps from 87.5MHz to 107.9MHz. Adding amplification to the audio input would surely help drive the modulator, but it does not seem to be required.

    Code:

    'General Configuration
    'for internal 8MHz
    Define CONF_WORD = 0x33c4
    OSCCON = 0x71 'set for internal 8MHZ oscillator
    Define CLOCK_FREQUENCY = 8

    'Variable Declarations
    'i/o states
    Const trisa1 = %11111110
    Const trisb1 = %11111111
    Const trisc1 = %11111000
    'ns73m frequency definitions
    Const freq_default = 93900000 '93.9 MHz (half way into the U.S. FM band)
    Const freq_low = 87500000 '87.5 MHz
    Const freq_high = 107900000 '107.9 MHz
    Const freq_incr = 200000 '200 KHz steps
    'i/o definition
    Symbol ns73m_ck = RC0
    Symbol ns73m_da = RC1
    Symbol ns73m_la = RC2
    Symbol button_up = RA4
    Symbol button_dn = RA5
    Symbol rs232_out = RA0
    'global variables
    Dim frequency As Long
    Dim frequency_old As Long
    'global bit logic
    Dim _true As Bit
    Dim _false As Bit
    _true = True
    _false = False

    'Main Program
    main:
    WaitMs 2500

    Call init()

    Call init_ns73m()

    While _true
    Call check_button()
    Wend
    End

    Proc init()
    AllDigital
    TRISA = trisa1
    TRISB = trisb1
    TRISC = trisc1

    'enable internal pull-ups for RA5 and RA4
    OPTION.NOT_RABPU = 0
    WPUA.WPUA5 = 1
    WPUA.WPUA4 = 1

    Low ns73m_la
    Low ns73m_ck
    Low ns73m_da
    Serout rs232_out, 9600, "Init MCU...", CrLf
    WaitMs 1000
    frequency = freq_default
    End Proc

    Proc init_ns73m()
    Call ns73m_serial(0x0e, 0x05) 'Software reset
    Call ns73m_serial(0x01, 0xb4) 'Pilot on, forced subcarrier
    Call ns73m_serial(0x02, 0x07) '2mW power, Unlock detect on
    Call ns73m_serial(0x03, 0xea) 'Lower byte frequency (93.9 megahertz)
    Call ns73m_serial(0x04, 0x2c) 'Upper byte frequency (93.9 megahertz)
    Call ns73m_serial(0x08, 0x1a) 'CEX = Band 2
    Call ns73m_serial(0x00, 0x21) 'Pwr on, 100mV audio for 100% modulation, 75us pre-emphasis
    Call ns73m_serial(0x0e, 0x05) 'Software reset
    Call ns73m_serial(0x06, 0x1e) 'Set internal charge pumps
    Serout rs232_out, 9600, "Init FM Radio...", CrLf
    Serout rs232_out, 9600, "FREQ = ", #frequency, CrLf
    End Proc

    Proc check_button()
    frequency_old = frequency
    'Increase Frequency on Up Button
    If button_up = 0 Then 'check button_up state
    'debounce switch
    WaitMs 200
    If button_up = 0 Then 'check button_up state again
    frequency = frequency + freq_incr
    Endif
    Endif

    'Decrease Frequency on Dn Button
    If button_dn = 0 Then 'check button_dn state
    WaitMs 200
    If button_dn = 0 Then 'check button_dn state again
    frequency = frequency - freq_incr
    Endif
    Endif

    'CheckFreq for Min/Max values
    Select Case frequency
    Case < freq_low
    frequency = freq_low
    Case > freq_high
    frequency = freq_high
    Case Else
    'frequency stays at calculated
    EndSelect
    If frequency_old <> frequency Then
    Call update_ns73m()
    Endif
    End Proc

    Proc update_ns73m()
    Dim band As Byte
    Dim temp As Long

    'Set Frequency Band
    Select Case frequency
    Case <= 91720000
    band = %00011011 'Band 3
    Case <= 9280000
    band = %00011010 'Band 2
    Case <= 104000000
    band = %00011001 'Band 1
    Case Else
    band = %00011000 'Band 0
    EndSelect

    Call ns73m_serial(0x08, band)

    'Set Frequency Word
    temp = (frequency + 304000) / 8192 'from datasheet
    Call ns73m_serial(0x03, temp.LB) 'Low byte of frequency
    Call ns73m_serial(0x04, temp.HB) 'High byte of frequency
    Call ns73m_serial(0x0e, 0x05) 'Software reset
    Call ns73m_serial(0x00, 0x21) 'Pwr on, 100mV audio for 100% modulation, 75us pre-emphasis
    'Update Frequency Display
    Serout rs232_out, 9600, "FREQ = ", #frequency, CrLf
    End Proc

    Proc ns73m_serial(address As Byte, data As Byte)
    Dim cnt As Byte
    Low ns73m_la
    'send register address (nibble)
    For cnt = 0 To 3
    Low ns73m_ck
    ns73m_da = address.0
    address = ShiftRight(address, 1)
    High ns73m_ck
    ASM: nop
    ASM: nop
    ASM: nop
    ASM: nop
    ASM: nop
    ASM: nop
    Next cnt
    Low ns73m_ck
    Low ns73m_da
    'send register data (byte)
    For cnt = 0 To 7
    Low ns73m_ck
    ns73m_da = data.0
    data = ShiftRight(data, 1)
    High ns73m_ck
    ASM: nop
    ASM: nop
    ASM: nop
    ASM: nop
    ASM: nop
    ASM: nop
    Next cnt
    Low ns73m_ck
    Low ns73m_da
    High ns73m_la
    WaitMs 1
    Low ns73m_la
    End Proc

    Comments
 

EE World Online Articles

Loading

 
Top