NS73M Controller - FM Transmitter
by languer , 1st October 2011 at 09:37 AM (2148 Views)
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:
The following things helped properly setup the IC for proper operation:
- 16F690 - quite overkill for this
- std breadboard
- PICKIT2 for programming and debugging
- NS73M breakout board
- Oshonsoft PIC Basic
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.
- 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.
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