RDA5807M收音机调试教程

本博文通过解析RDA FM原厂驱动RDA_FM5807P_drv_V3.3代码来进行讲解,实现RDA5807N系列收音机,可以通过读ID的方式兼容RDA5807P、RDA5807SP、RDA5807SS、RDA5807H系列、RDA5807N系列。

以RDA5807M为例,使用I2C通讯方式



一、RDA5807M

1、RDA5807M简介

功能特点:
A、 采用通用的102BC模块的封装,用户可直接替换使用,无需更改电路设计。
B、 灵敏度高、噪声小、抗干扰能力强、外接元件极少、体积小(11*11.2MM Max)、使用极其简单。
C、 76-108MHz全球FM频段兼容(包括日本76-91MHz和欧美87.5-108.5MHz)。
D、 I2C串行数据总线接口通讯,支持外部基准时钟输入方式。
E、 完全整合的COMS工艺单晶片集成电路,功耗极小。
F、 内置高精度A/D(模数转换器)及数字频率合成器。
G、 内置LDO调整、低功耗、超宽电压使用范围(2.7-3.6VDC)。
H、 内置噪声消除、软静音、低音增强电路设计。
I、 高功率32Ω负载音频输出,直接耳机驳接,无需外接音频驱动放大。
J、 应用简便、成本低,性价比高。

本次实验所用到的RDA5807M模块,如下图:
在这里插入图片描述
模块引脚图,如下图:
在这里插入图片描述

2、RDA5807M通讯时序图

RDA5807M通讯,datasheet给出的是I2C连续读写的方式。
RDA5807M 的 I2C 接口中寄存器的地址是不可见的。RDA5807M 的 I2C 接口有一个固定的起始寄存器地址(写操作时为 02H,读操作时为 0AH),并有一个内部递增计数器。

在这里插入图片描述


3、RDA5807M寄存器

RDA5807M每个寄存器都是16位的寄存器,高位在前,低位在后。
这里只介绍需要用到的几个寄存器。

RDA5807M 的 I2C 接口中寄存器的地址是不可见的。RDA5807M 的 I2C 接口有一个固定的起始寄存器地址(写操作时为 02H,读操作时为 0AH),并有一个内部递增计数器。


①、00H寄存器

在这里插入图片描述


②、02H寄存器

在这里插入图片描述

③、03H寄存器

在这里插入图片描述


④、04H寄存器

在这里插入图片描述


⑥、05H寄存器

在这里插入图片描述


⑦、0AH寄存器

在这里插入图片描述


⑧、0BH寄存器

在这里插入图片描述



二、程序编写

1、软件模拟I2C代码

相关宏定义,数据类型重定义

#define 	ACK		0
#define 	NACK	1

sbit SDA = P3^2;
sbit SCL = P3^3;

typedef unsigned char           uint8;
typedef unsigned short int      uint16;
typedef short int               int16;
typedef unsigned int      		uint32;
typedef int						int32;
typedef int						bool;

软件模拟I2C

//产生START信号
void IIC_Start(void)
{
    SDA = 1;        //需在SCL之前设定
    SCL = 1;        //硬件进入SDA检测状态
    delay_5us();    //延时至少4.7us
    SDA = 0;        //SDA由1->0,产生开始信号
    delay_5us();    //延时至少4us
    SCL = 0;        //SCL变为无效
}

//产生STOP信号
void IIC_Stop(void)
{
    SDA = 0;        //在SCL之前拉低
    SCL = 1;        //硬件进入SDA检测状态
    delay_5us();    //至少延时4us
    SDA = 1;        //SDA由0->1,产生结束信号
    delay_5us();    //延时至少4.7us
}
//由主向从发送应答码
//0-ACK,1-NAK
void IIC_Send_ACK(bit ack)
{
    SDA = ack;      //产生应答电平
	delay_5us();
    SCL = 1;        //发送应答信号
    delay_5us();    //延时至少4us
    SCL = 0;        //整个期间保持应答信号
}

//取得由从到主的应答码
bit IIC_Get_ACK(void)
{
    bit ret;        //用来接收返回值
    SDA = 1;        //电阻上拉,进入读
	delay_5us();
    SCL = 1;        //进入应答检测
    delay_5us();    //至少延时4us
    ret = SDA;      //保存应答信号
    SCL = 0;
    return ret;
}

//写IIC总线写1个字节
bit IIC_Write_Byte(uint8 dat)
{
	bit ack;
    uint8 loop = 8;     //必须为一个字节
    while(loop--){
        // 高在前低在后
		if (dat & 0x80)
			SDA = 1;
		else
			SDA = 0;
        delay_5us();
		SCL = 1;
        delay_5us();    //延时至少4us
        SCL = 0;
        dat <<= 1;      //低位向高位移动
    }
	
	ack = IIC_Get_ACK();
	
	return ack;
}

//从IIC总线读取1个字节
uint8 IIC_Read_Byte(bit ack)
{
    uint8 loop = 8;     //必须为一个字节
    uint8 ret = 0;
	// SDA 设置输入方向
    SDA = 1;
    while(loop--){
		ret <<= 1;
		SCL = 1;
		delay_5us();
        // 高在前低在后
        if(SDA){
			ret++;
		}
        SCL = 0;
        delay_5us();
    }
	
	IIC_Send_ACK(ack);
	
    return ret;
}

2、RDA5807M功能代码

①、相关宏定义

#define TRUE			1
#define FALSE			0

#define READ	        1   
#define WRITE	        0   
                            
#define ADRW 	        0x20	//RDA5807P写寄存器地址
#define ADRR 	        0x21	//RDA5807P读寄存器地址

//本实验所用到的RDA5807M模块,使用的是32KHz晶振,需要打开相关宏
//#define                 _SHARE_CRYSTAL_24MHz_   //共用24MHz晶振,请打开此宏
//#define                 _SHARE_CRYSTAL_12MHz_   //共用12MHz晶振,请打开此宏
#define                 _SHARE_CRYSTAL_32KHz_   //共用32KHz晶振,请打开此宏
//#define                 _FM_STEP_50K_           //50K步进,请打开此宏

②、全局变量,初始化寄存器的值

//全局变量,用于存储读ID和读寄存器的值
uint16 gChipID = 0;			//芯片ID号
uint8  RDA5807P_REGW[10];	//寄存器


//通过读ID的方式兼容RDA5807P、RDA5807SP、RDA5807SS、RDA5807H系列、RDA5807N系列
//RDA5807P
uint8 code RDA5807P_initialization_reg[]={
#if defined(_SHARE_CRYSTAL_24MHz_)
    0xC0, 0x51, //02H:
#elif defined(_SHARE_CRYSTAL_12MHz_)
    0xC0, 0x11, //02H:
#elif defined(_SHARE_CRYSTAL_32KHz_)
    0xC0, 0x01, //02H:
#else
    0xC0, 0x01,
#endif

#if defined(_FM_STEP_50K_)
    0x00, 0x12,        
#else
    0x00, 0x10,
#endif
    0x04, 0x00,        
    0x88, 0xAF, //05H: 
    0x00, 0x00,        
    0x5E, 0xC6,        
    0x50, 0x96,        
    0x00, 0x00,        
    0x40, 0x00, //0AH: 
    0x00, 0x8F,        
    0x00, 0x00,        
    0x00, 0x00,        
    0x00, 0x00,        
    0x00, 0x00,        
    0xF0, 0x05, //10H: 
    0x90, 0x00,        
    0xF4, 0x84,        
    0x70, 0x01,        
    0x40, 0xF0,        
    0x21, 0x80, //15H: 
    0x7A, 0xD0,        
    0x3E, 0x40,        
    0x55, 0xA9,        
    0xE8, 0x48,        
    0x50, 0x80, //1AH: 
    0x00, 0x00,        
    0x37, 0xB6,        
    0x40, 0x0C,        
    0x07, 0x9B,        
    0x4C, 0x1D,        
    0x81, 0x11, //20H: 
    0x45, 0xC0,        
};

uint8 code RDA5807PE_initialization_reg[]={
#if defined(_SHARE_CRYSTAL_24MHz_)
    0xc4, 0x51, //02H:
#elif defined(_SHARE_CRYSTAL_12MHz_)
    0xc4, 0x11, //02H:
#elif defined(_SHARE_CRYSTAL_32KHz_)
    0xc4, 0x01, //02H:
#else
    0xC0, 0x01,
#endif

#if defined(_FM_STEP_50K_)
    0x1b, 0x92,
    0x0C, 0x00,
#else       //Step 100K
    0x00, 0x10,
    0x04, 0x00,
#endif

    0x86, 0xad, //05H:
    0x80, 0x00,
    0x5F, 0x1A, //07H
    0x5e, 0xc6,
    0x00, 0x00,
    0x40, 0x6e, //0AH: 
    0x2d, 0x80,
    0x58, 0x03,
    0x58, 0x04,
    0x58, 0x04,
    0x58, 0x04,
    0x00, 0x47, //10H: 
    0x90, 0x00,
    0xF5, 0x87,
    0x7F, 0x0B, //13H:
	0x04, 0xF1,
	0x5E, 0xc0, //15H: 0x42, 0xc0
    0x41, 0xe0,
    0x50, 0x6f,
    0x55, 0x92,
    0x00, 0x7d,
    0x10, 0xC0,//1AH
    0x07, 0x80,
    0x41, 0x1d,//1CH,
    0x40, 0x06,
    0x1f, 0x9B,
    0x4c, 0x2b,//1FH. 
    0x81, 0x10, //20H: 
    0x45, 0xa0,// 21H

#if defined(_FM_STEP_50K_)
    0x55, 0x3F, //22H
#else
    0x19, 0x3F, //22H
#endif

    0xaf, 0x40, 
	0x06, 0x81,
    0x1b, 0x2a, //25H
    0x0D, 0x04,
	0x80, 0x9F, //0x80, 0x2F, 
    0x17, 0x8A,
    0xD3, 0x49,
    0x11, 0x42,
    0xA0, 0xC4, //2BH
	0x3E, 0xBB,
    0x00, 0x00,
    0x58, 0x04,
    0x58, 0x04, //2FH
    0x58, 0x04,
    0x00, 0x74,
    0x3D, 0x00,
    0x03, 0x0C,
    0x2F, 0x68,
    0x38, 0x77, //35H
};

uint8 code RDA5807PH_initialization_reg[]={
#if defined(_SHARE_CRYSTAL_24MHz_)
    0xC4, 0x51, //02H:
#elif defined(_SHARE_CRYSTAL_12MHz_)
    0xC4, 0x11, //02H:
#elif defined(_SHARE_CRYSTAL_32KHz_)
    0xC4, 0x01, //02H:
#else
    0xC0, 0x01,
#endif
#if defined(_FM_STEP_50K_)
    0x00,0x12,
#else
    0x00,0x10,
#endif
    0x04,0x00,
    0x86,0xBF,  //05H   
    0x40,0x00,
    0x56,0xC6,
    0x00,0x00,
    0x00,0x00,
    0x00,0x00,  //0AH
    0x00,0x00,
    0x00,0x00,
    0x00,0x00,
    0x00,0x00,
    0x00,0x00,
    0x00,0x06,  //10H
    0x00,0x19, //
    0x2A,0x11,
    0x00,0x2E,
    0x2A,0x30,
    0xB8,0x3C,  //15H
    0x90,0x00,
    0x2A,0x91,
    0x84,0x12,
    0x00,0xA8,
    0xC4,0x00,  //1AH
    0xE0,0x00,
    0x30,0x1D,//0x24,0x9D,1cH
    0x81,0x6A,
    0x46,0x08,
    0x00,0x86,  //1FH
    0x06,0x61,  //20H
    0x00,0x00,
    0x10,0x9E,
    0x24,0xC9,//   0x24,0x47,//0830//23H
    0x04,0x08,//0830
    0x06,0x08,  //0x06,0x08,//0830  //0X25H
    0xE1,0x05,
    0x3B,0x6C,
    0x2B,0xEC,
    0x09,0x0F,
    0x34,0x14,  //2AH
    0x14,0x50,
    0x09,0x6D,
    0x2D,0x96,
    0x01,0xDA,
    0x2A,0x7B,
    0x08,0x21,   //30H
    0x13,0xD5,
    0x48,0x91,
    0x00,0xbc,
    0x08,0x96,   //34H
    0x15,0x3C,  //35H
    0x0B,0x80,   //36H
    0x25,0xC7,   //37H
    0x00,0x00,   //38H
	0x3C,0x58,
	0x2A,0x50,
	0x26,0x2C,
	0x06,0x08,
	0x02,0x00,
	0x00,0x00,
};

uint8 code RDA5807N_initialization_reg[]={
#if defined(_SHARE_CRYSTAL_24MHz_)
    0xC0, 0x51, //02H:
#elif defined(_SHARE_CRYSTAL_12MHz_)
    0xC0, 0x11, //02H:
#elif defined(_SHARE_CRYSTAL_32KHz_)
    0xC0, 0x01, //02H:			//02H寄存器第10位必须为1
	//0xD0, 0x01, //02H:	//开启增强低音
#else
    0xC0, 0x01,
#endif
    0x00, 0x00,
    0x04, 0x00,
    0xC6, 0xad, //05h
    0x60, 0x00,
    0x42, 0xC6,
    0x00, 0x00,
    0x00, 0x00,
    0x00, 0x00,  //0x0ah
    0x00, 0x00,
    0x00, 0x00,
    0x00, 0x00,
    0x00, 0x00,
    0x00, 0x00,
    0x00, 0x00,  //0x10h
    0x00, 0x19,
    0x2a, 0x11,
    0xB0, 0x42,  
    0x2A, 0x11,  
    0xb8, 0x31,  //0x15h 
    0xc0, 0x00,
    0x2a, 0x91,
    0x94, 0x00,
    0x00, 0xa8,
    0xc4, 0x00,  //0x1ah
    0xF7, 0xcF,   
    0x2A, 0xDC,  //0x1ch
    0x80, 0x6F, 
    0x46, 0x08,
    0x00, 0x86,
    0x06, 0x61, //0x20H
    0x00, 0x00,
    0x10, 0x9E,
    0x23, 0xC8,
    0x04, 0x06,
    0x0E, 0x1C, //0x25H
};

③、I2C连续读/写代码

RDA5807M 的 I2C 接口中寄存器的地址是不可见的。
RDA5807M 的 I2C 接口有一个固定的起始寄存器地址(写操作时为 02H,读操作时为 0AH),并有一个内部递增计数器。所以连续读/写操作时,写入I2C地址后,然后直接读/写数据,不用再写入寄存器地址

对 RDA5807M进行写操作时,MCU 写入寄存器的顺序如下:02H 的高字节,02H 的低字节,03H 的高字节,……,直到结束。RDA5807M在 MCU 写入每个字节后都会返回一个ACK。MCU 会给出 STOP 来结束操作。
对 RDA5807M进行读操作时,在 MCU 给出命令字节后,RDA5807M会送出数据字节,顺序如下:0AH 高字节,0AH 低字节,0BH 高字节,……,直到 RDA5807M接收到从 MCU 发出的 NACK, MCU 送出 STOP,读操作结束。

//读或者写数据到RDA5807P 
//operation功能选择:读READ,写WRITE
//datas:读或者写的数据指针
//numBytes:需要读或者写numBytes个字节
uint8 OperationRDAFM_2w(uint8 operation, uint8 *datas, uint8 numBytes)
{
	uint8 j;
	uint8 acknowledge = 0;
	
	IIC_Start();
	if(operation == READ){
		acknowledge = IIC_Write_Byte(ADRR);//写IIC读地址
	}
	else{
		acknowledge = IIC_Write_Byte(ADRW);//写IIC写地址
	}
	for(j = 0; j < numBytes; j++, datas++){
		//对 RDA5807 MODE 进行读操作时,在 MCU 给出命令字节后,RDA5807 MODE 会送出数据字
		//节,MCU 收到数据后产生 ACK 信号.除了最后一个字节,MCU 在读到每个字节后都要给出 ACK,
		//在读到最后一个字节后,MCU 给出 NACK,使 RDA5807 MODE 把总线交给 MCU,然后 MCU 发出
		//STOP,结束整个操作。
		if(operation == READ){
			if(j == (numBytes -1)){
				*datas = IIC_Read_Byte(NACK);
			} 
			else{
				*datas = IIC_Read_Byte(ACK);
			} 
		}
		//对 RDA5807 MODE 进行写操作时,MCU 写入寄存器, RDA5807 MODE 在 MCU 写入每个字节后
		//都会返回一个 ACK。MCU 会给出 STOP 来结束操作。
		else{
			acknowledge = IIC_Write_Byte(*datas); 
		}
	}
	IIC_Stop();
	return acknowledge;
}

④、RDA5807M初始化代码

通过读ID的方式兼容RDA5807P、RDA5807SP、RDA5807SS、RDA5807H系列、RDA5807N系列

//初始化RDA5807P,返回1初始化成功
bool RDA5807P_Intialization(void)
{
	uint8 error_ind = 0;
	uint8 RDA5807P_REGR[10]={0x0};
    uint8 i = 0;

    RDA5807P_REGW[0] = 0x00;//软件复位指令
    RDA5807P_REGW[1] = 0x02;

	/*对 RDA5807M进行写操作时,MCU 写入寄存器的顺序如下:02H 的高字节,02H 的低字节,03H 的高字节,……,直到结束。RDA5807M在 MCU 写入每个字节后都会返回一个ACK。MCU 会给出 STOP 来结束操作*/
	error_ind = OperationRDAFM_2w(WRITE, (uint8 *)&RDA5807P_REGW[0], 2);
	Delay50ms();

	/*对 RDA5807M进行读操作时,在 MCU 给出命令字节后,RDA5807M会送出数据字节,顺序如下:0AH 高字节,0AH 低字节,0BH 高字节,……,直到 RDA5807M接收到从 MCU 发出的 NACK, MCU 送出 STOP,读操作结束。*/
	error_ind = OperationRDAFM_2w(READ, (uint8 *)&RDA5807P_REGR[0], 10);
	Delay50ms();

	//连续读10个字节
	//0→0AH 15:8        1→0AH  7:0
	//2→0BH 15:8        3→0BH  7:0
	//4→
	//6→
	//8→00H 15:8        9→00H  7:0
    gChipID = RDA5807P_REGR[8];
    gChipID = ((gChipID << 8) | RDA5807P_REGR[9]);

    if(gChipID == 0x5808){  //RDA5807N
        for (i = 0; i < 8; i++){
            RDA5807P_REGW[i] = RDA5807N_initialization_reg[i];
		}
        error_ind = OperationRDAFM_2w(WRITE, (uint8 *)&RDA5807N_initialization_reg[0], 2);
        Delay600ms(); 
	    error_ind = OperationRDAFM_2w(WRITE, (uint8 *)&RDA5807N_initialization_reg[0], sizeof(RDA5807N_initialization_reg));
    }
    else if(gChipID == 0x5804){     //RDA5807PE,RDA5807SP
        for (i=0;i<8;i++){
            RDA5807P_REGW[i] = RDA5807PE_initialization_reg[i];
		}
        error_ind = OperationRDAFM_2w(WRITE, (uint8 *)&RDA5807PE_initialization_reg[0], 2);
        Delay600ms();
	    error_ind = OperationRDAFM_2w(WRITE, (uint8 *)&RDA5807PE_initialization_reg[0], sizeof(RDA5807PE_initialization_reg));
    }
    else if(gChipID == 0x5801){     //RDA5807H,RDA5807HP
        for (i=0;i<8;i++){
            RDA5807P_REGW[i] = RDA5807PH_initialization_reg[i];
		}
        error_ind = OperationRDAFM_2w(WRITE, (uint8 *)&RDA5807PH_initialization_reg[0], 2);
        Delay600ms();
	    error_ind = OperationRDAFM_2w(WRITE, (uint8 *)&RDA5807PH_initialization_reg[0], sizeof(RDA5807PH_initialization_reg));
        Delay50ms();
		Delay50ms();

		do{
			i++;
			if(i>10){
				return 0; 
			}
			RDA5807P_SetFreq(8750);
			Delay10ms();
			OperationRDAFM_2w(READ, &(RDA5807P_REGR[0]), 4);
			if((RDA5807P_REGR[3] & 0x80) == 0){
				RDA5807P_REGW[1] &= 0xFE;	
				error_ind = OperationRDAFM_2w(WRITE, (uint8 *)&RDA5807P_REGW[0], 2);
				Delay50ms();
				RDA5807P_REGW[1] |= 0x01;
				error_ind = OperationRDAFM_2w(WRITE, (uint8 *)&RDA5807P_REGW[0], 2);
				Delay50ms();
			}
		}while((RDA5807P_REGR[3]&0x80)==0);
    }
    else{
        gChipID = RDA5807P_REGR[4];
        gChipID = ((gChipID<<8) | RDA5807P_REGR[5]);
    }
    
    if((gChipID == 0x5802) || (gChipID == 0x5803)){
        gChipID = 0x5802;
        for (i=0;i<8;i++){
            RDA5807P_REGW[i] = RDA5807P_initialization_reg[i];
		}
        error_ind = OperationRDAFM_2w(WRITE, (uint8 *)&RDA5807P_initialization_reg[0], 2);
        Delay600ms();
        error_ind = OperationRDAFM_2w(WRITE, (uint8 *)&RDA5807P_initialization_reg[0], sizeof(RDA5807P_initialization_reg));
    }

	Delay50ms();        //Dealy 50 ms
	
	if(error_ind){	//ACK=0, NACK=1
	   return 0;
	}
	else{
	   return 1;
	}
}

⑤、设置当前FM频道的音量

//设置FM音量,0~15
void RDA5807P_SetVolumeLevel(uint8 level)
{
    uint8 RDA5807P_reg_data[8];
    uint8 i = 0;
	//uint16 temp;

    for(i = 0; i < 8; i++){
        RDA5807P_reg_data[i] = RDA5807P_REGW[i];
	}

    RDA5807P_reg_data[7] = (( RDA5807P_reg_data[7] & 0xf0 ) | (level & 0x0f)); 
    
    RDA5807P_reg_data[3] &= (~(0x10));

	OperationRDAFM_2w(WRITE, &(RDA5807P_reg_data[0]), 8);
    Delay50ms();    //Dealy 50 ms
	
	//获取当前设置的音量值
	//temp = RDA5807P_reg_data[7] & 0x0f;
}

⑥、返回当前FM频道的信号强度

//返回当前频率信号强度,0~127
uint16 RDA5807P_GetSigLvl(void)
{    
    uint8 RDA5807P_reg_data[4]={0};	
	uint16 rssi;
	
	OperationRDAFM_2w(READ, &(RDA5807P_reg_data[0]), 4);
	Delay50ms();    //Dealy 50 ms
	
	rssi = (RDA5807P_reg_data[2] >> 1) & 0x7F;
    return rssi;  //返回RSSI
}

⑦、判断当前频率是否是一个电台

//判断当前频率是否是一个电台,返回0当前频率不是一个电台,返回1当前频率是一个电台
//例如:设置频率107.3MHz,curFreq = 10730
bool RDA5807P_ValidStop(int16 freq)
{
	uint8 RDA5807P_reg_data[4] = {0};
	uint8 RDA5807P_REGR[10]={0x0};
	uint8 falseStation = 0;
	uint8 i = 0;
	
	//读取芯片ID号
	OperationRDAFM_2w(READ, (uint8 *)&RDA5807P_REGR[0], 10);
	Delay50ms();
    gChipID = RDA5807P_REGR[8];
    gChipID = ((gChipID << 8) | RDA5807P_REGR[9]);
	
    if(0x5808 == gChipID){
        OperationRDAFM_2w(READ, &(RDA5807P_reg_data[0]), 4);
	}		
    else{
    	do{
			i++;
    		if(i>5){
				return 0; 
			}
    		Delay30ms();
			OperationRDAFM_2w(READ,&(RDA5807P_reg_data[0]), 4);	
		}while((RDA5807P_reg_data[0] & 0x40)==0);
	}
	//检查0BH寄存器 FM_TURE 位,0 = 当前频率不是一个电台
	if((RDA5807P_reg_data[2] & 0x01)==0){
		falseStation = 1;
	}
	if(freq == 9600){
		falseStation = 1;
	}
	if(falseStation == 1){
		return 0;
	}
	else{
		return 1;
	}
}

⑧、设置频率

//设置频率
//例如:设置频率107.3MHz,curFreq = 10730
void RDA5807P_SetFreq(int16 curFreq)
{   
	uint16 curChan;
	
	curChan = RDA5807P_FreqToChan(curFreq);
	
	//SetNoMute
	RDA5807P_REGW[0] |=	1 << 7;
	RDA5807P_REGW[2] = curChan >> 2;
	RDA5807P_REGW[3] = (((curChan & 0x0003) << 6) | 0x10) | (RDA5807P_REGW[3] & 0x0f);	//调谐启用
	
	OperationRDAFM_2w(WRITE, &(RDA5807P_REGW[0]), 4);
	Delay50ms();     //Delay 50 ms
}

⑨、把信道值转换成频率值

//把信道值转换成频率值
//例如:信道203,chan = 203,转换成频率值为10730
uint16 RDA5807P_ChanToFreq(uint16 chan) 
{
	uint8 channelSpacing;
	uint16 bottomOfBand;
	uint16 freq;

	if ((RDA5807P_REGW[3] & 0x0c) == 0x00){ //03H寄存器低八位第2、3位都为0,波段选择 = 87~108MHz
		bottomOfBand = 8700;
	}
	else if ((RDA5807P_REGW[3] & 0x0c) == 0x04){	
		bottomOfBand = 7600;
	}
	else if ((RDA5807P_REGW[3] & 0x0c) == 0x08){	
		bottomOfBand = 7600;	
	}
	if ((RDA5807P_REGW[3] & 0x03) == 0x00){ //03H寄存器低八位第0、1位都为0,频率间距 = 100KHz
		channelSpacing = 10;
	}
	else if ((RDA5807P_REGW[3] & 0x03) == 0x01){
		channelSpacing = 10;
	}
	else if ((RDA5807P_REGW[3] & 0x03) == 0x02){
		channelSpacing = 5;
	}
	freq = bottomOfBand + chan * channelSpacing;

	return (freq);
}

⑩、把频率值转换成信道值

//把频率值转换成信道值
//例如:频率107.3MHz,frequency = 10730,转换成信道值为203
uint16 RDA5807P_FreqToChan(uint16 frequency) 
{
	uint8 channelSpacing;
	uint16 bottomOfBand;
	uint16 channel;

	if ((RDA5807P_REGW[3] & 0x0c) == 0x00){ //03H寄存器低八位第2、3位都为0,波段选择 = 87~108MHz
		bottomOfBand = 8700;
	}
	else if ((RDA5807P_REGW[3] & 0x0c) == 0x04){
		bottomOfBand = 7600;
	}
	else if ((RDA5807P_REGW[3] & 0x0c) == 0x08){
		bottomOfBand = 7600;	
	}
	if ((RDA5807P_REGW[3] & 0x03) == 0x00){ //03H寄存器低八位第0、1位都为0,频率间距 = 100KHz
		channelSpacing = 10;
	}
	else if ((RDA5807P_REGW[3] & 0x03) == 0x01){
		channelSpacing = 10;
	}
	else if ((RDA5807P_REGW[3] & 0x03) == 0x02){ 
		channelSpacing = 5;
	}
	channel = (frequency - bottomOfBand) / channelSpacing;
	return (channel);
}

⑪、设置静音模式

//将RDA5807P设置为静音模式,TRUE开启静音,FALSE关闭静音
void RDA5807P_SetMute(bool mute)
{
	if(mute == TRUE){
	 	RDA5807P_REGW[0] &=  ~(1<<6);//使能02H寄存器第14位为0,开启静音
	}
	else{
		RDA5807P_REGW[0] |=	1<<6;
	}

	OperationRDAFM_2w(WRITE, &(RDA5807P_REGW[0]), 2);
    Delay50ms();    //Dealy 50 ms
}

⑫、关机功能

//RDA5807P关机功能
void RDA5807P_PowerOffProc(void)
{
	RDA5807P_REGW[1] &= (~1);		//使能02H寄存器第0位为0,上电不启用
	OperationRDAFM_2w(WRITE, &(RDA5807P_REGW[0]), 2);

}

⑬、从0AH寄存器中读取当前频率

//从0AH寄存器中读取当前频率
uint16 RDA5807P_RegToInt(void)
{
	uint8 RDA5807P_REGR[10] = {0x0};
	uint16 temp;
	
	OperationRDAFM_2w(READ, (uint8 *)&RDA5807P_REGR[0], 10);
	
	temp = RDA5807P_REGR[0];
    temp = ((temp << 8) | RDA5807P_REGR[1]);
	temp = (temp & 0x03FF) * 10 + 8700;
	
	return temp;
}

3、主函数

这里给出一个调谐模式范例主函数

//K1--- 向上搜索电台  K2--- 向下搜索电台                         *
//K3--- 音量加        K4--- 音量减  
//波段选择,87-108MHz

int16  fre = 10730;
uint16 rssi = 0;
uint8  vol = 8;
uint8  disfre[6] = {0};

sbit K1   = P2^6;
sbit K2   = P2^7;
sbit K3   = P2^4;
sbit K4   = P2^5;


void Key()           //按键判断程序
{
	if(K1 == 0){ 
		Delay20us();
		if(K1 == 0){
			fre += 10;
			if(fre >= 10800){
				fre = 10800;
			}
			//设置频率
			RDA5807P_SetFreq(fre);
			
			//切换频率后要设置音量
			RDA5807P_SetVolumeLevel(vol);
			
		}
		while(!K1); //等待 按起   
	}
	if(K2 == 0){ 
		Delay20us();
		if(K2 == 0){
			fre -= 10;
			if(fre <= 8700){
				fre = 8700;
			}
	
			//设置频率
			RDA5807P_SetFreq(fre);
			
			//设置音量
			RDA5807P_SetVolumeLevel(vol);
			
		}
		while(!K2); //等待 按起   
	}
	if(K3 == 0){ 
		Delay20us();
		if(K3 == 0){
			vol++;
			if(vol >= 15){
				vol = 15;
			}
			//设置音量
			RDA5807P_SetVolumeLevel(vol);
		}
		while(!K3); //等待 按起   
	}
	if(K4 == 0){ 
		Delay20us();
		if(K4 == 0){
			vol--;
			if(vol <= 1){
				vol = 1;
			}
			//设置音量
			RDA5807P_SetVolumeLevel(vol);
		}
		while(!K4); //等待 按起   
	}
}


void main(void)
{
	
	if(!RDA5807P_Intialization()){
		while(1);
	}
	
	//设置初始频率
	RDA5807P_SetFreq(fre);
	
	//获取当前频率信号强度
	rssi = RDA5807P_GetSigLvl();
	
	//设置音量
	RDA5807P_SetVolumeLevel(vol);
	
	while(1){
		Key();
	}
}

完整代码在这里
FM模块RDA5807M

  • 31
    点赞
  • 152
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 20
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菠萝蚊鸭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值