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.