Basic AM/FM Receiver
Description
The purpose of this project is to design a standard AM/FM radio receiver using an Si4735 breakout board.
Functionality
- I^2C communication was utilized to exchange data between the mbed microcontroller and the Si4735.
- Station scanning done using a SPST push-button normally open momentary switch. Stations increase using increments of 100 kHz in FM mode and 5 kHz in AM mode. The stations will rollover to the beginning of the frequency range in both modes once the maximum frequency is reached. The FM range for this system is 88MHz to 108MHz. The AM range is 535 kHz to 1700 kHz.
- Mode selection between AM and FM is accomplished by using a SPST DIP toggle switch.
Initializations prior to operation
- AM/FM Device must be reset prior to activating AM or FM mode using the timing parameters provided by the datasheet.
- The required Rclock (32.768 kHz) oscillator signal is provided to the Si4735 using a PWM pin with a duty cycle of 50%.
Bill of Materials
- Mbed microcontroller
- Si4735 AM/FM Receiver breakout board
- Audio jack breakout board
- Push button SPST momentary switch
- SPST DIP toggle switch
- Text LCD Display
- 200uH AM Ferrite Loop Antenna
- 0.47uF Capacitor
- Whip Antenna
- Two 10kohm resistors
- PC Speakers
Wiring Block Diagram
Code
Main Program
// My AM/FM Radio, Lab 3 Main
// Jammie Proctor
// 03/02/2013
#include "mbed.h"
#include "TextLCD.h"
I2C radio(p28, p27); // sda, scl
TextLCD lcd(p15, p16, p17, p18, p19, p20); // rs, e, d4-d7
DigitalIn AM_FM(p22); // Radio mode AM/FM
DigitalIn station(p23); // Station seek/scan
DigitalOut reset(p21); // Radio reset
DigitalOut lock(LED1); // Station active
PwmOut rclock(p24); // Rclock generation
//====================================== Global Variables =============================================
const int write_addr=0x22;
int fm_pwr_up[3]={0x01, 0x00, 0x05}; // FM power-up command
int am_pwr_up[3]={0x01, 0x01, 0x05}; // AM power-up command
int fm_station[4]={0x20, 0x00, 0x22, 0x60}; // Set FM station
int am_station[6]={0x40, 0x00, 0x02, 0x17, 0x00, 0x00}; // Set AM station
float lcd_station=88.0;
int reg_station=8800, reg_am_station=535, i=0, Response, ack=0, pwr_down=0x11, tune=0x31;
int* p_pwr_down = &pwr_down;
int* p_tune = &tune;
bool last_mode=0;
//===================================== Support Functions =============================================
void SendCommand(int* array, int length) { /* Send Command to Si4735 */
radio.start();
ack=radio.write(write_addr);
for(i=0; i<length; i++) ack=radio.write(array[i]);
Response=radio.read(ack);
radio.stop();
wait(.2);
}
void Reset(void) { /* Reset AM/FM Radio */
reset=0;
wait(.2);
reset=1;
wait(.2);
}
void AM_Restart(void) { /* Reinitialize AM receiver */
SendCommand(p_tune, 1); // Disable carrier
wait(.2);
SendCommand(p_pwr_down, 1); // Power down sequence
wait(.2);
Reset();
SendCommand(am_pwr_up, 3); // Launch AM
SendCommand(am_station, 6); // Play current AM station
}
void FM_Restart(void) { /* Reinitialize FM receiver */
SendCommand(p_tune, 1); // Disable carrier
wait(.2);
SendCommand(p_pwr_down, 1); // Power down sequence
wait(.2);
Reset();
SendCommand(fm_pwr_up, 3); // Launch FM
SendCommand(fm_station, 4); // Play current FM station
}
//================================================ Main Code =======================================================
int main() {
AM_FM.mode(PullUp);
station.mode(PullUp);
lock=0;
rclock.period(.000030518); // Set rclock oscillator to 32.768kHz
rclock=0.5; // 50% Duty Cycle for rclock
radio.frequency(100000); // I^2C frequency setting 100kHz
Reset();
SendCommand(fm_pwr_up, 3); // Initialize FM
SendCommand(fm_station, 4); // Play default fm station
last_mode=AM_FM;
while(1) {
if(AM_FM) { // FM selected (SW1 in the off position)
if(AM_FM!=last_mode) FM_Restart();
last_mode=AM_FM;
if(!station) { // SW2 pressed? Go to next station
lock=0;
while(!station);
if(reg_station<10800) reg_station+=10;
else reg_station=8800;
lcd_station=reg_station/100.0;
fm_station[3]=reg_station&0x00FF;
fm_station[2]=reg_station>>8;
SendCommand(fm_station, 4);
lock=1;
}
lcd.printf("Station:\n %3.1fMHz FM", lcd_station);
wait(.1);
lcd.cls();
}
else { // AM selected (SW1 in the on position)
if(AM_FM!=last_mode) AM_Restart();
last_mode=AM_FM;
if(!station) { // SW2 pressed? Go to next station
lock=0;
while(!station);
if(reg_am_station<1700) reg_am_station+=5;
else reg_am_station=530;
am_station[3]=reg_am_station&0x00FF;
am_station[2]=reg_am_station>>8;
SendCommand(am_station, 6);
lock=1;
}
lcd.printf("Station:\n %ukHz AM", reg_am_station);
wait(.1);
lcd.cls();
}
}
}
Program Link
Import programLab_3
AM FM Radio Receiver
Video
1 comment on Basic AM/FM Receiver:
Please log in to post comments.

Pretty cool! I like the the use of I2C comms between mbed and the Si4735 breakout. Wouldn't mind trying this out myself as a project. Many thanks.