欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

RDA5807M收音机调试教程

程序员文章站 2024-03-04 10:51:17
...

本博文通过解析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模块,如下图:
RDA5807M收音机调试教程
模块引脚图,如下图:
RDA5807M收音机调试教程

2、RDA5807M通讯时序图

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

RDA5807M收音机调试教程


3、RDA5807M寄存器

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

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


①、00H寄存器

RDA5807M收音机调试教程


②、02H寄存器

RDA5807M收音机调试教程

③、03H寄存器

RDA5807M收音机调试教程


④、04H寄存器

RDA5807M收音机调试教程


⑥、05H寄存器

RDA5807M收音机调试教程


⑦、0AH寄存器

RDA5807M收音机调试教程


⑧、0BH寄存器

RDA5807M收音机调试教程



二、程序编写

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

相关标签: 笔记 单片机