RDA5807M收音机调试教程
本博文通过解析RDA FM原厂驱动RDA_FM5807P_drv_V3.3代码来进行讲解,实现RDA5807N系列收音机,可以通过读ID的方式兼容RDA5807P、RDA5807SP、RDA5807SS、RDA5807H系列、RDA5807N系列。
以RDA5807M为例,使用I2C通讯方式
RDA5807M调试教程
一、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
下一篇: 子窗口给父窗口赋值实现思路及案例演示