Electronic Circuits and Projects Forum



languer

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:
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
Attached Thumbnails Attached Images

Comments

Electronic Circuits  |  Learning Electronics

Join our community with over 100,000 Members! It's free, easy and when you're logged in you have many more features! Click to register.
Page Time: 0.07561 seconds      Memory: 7,819 KB      Queries: 25      Templates: 0