关于RDA1846,RDA1846是一种用于V/U段的调频收发机芯片,与AT1846S兼容,可互换使用。支持DTMF和亚音等功能。可用于2米,1.25米或0.7米的业余频段。

The RDA1846 is a highly integrated single-chip

transceiver for Walkie Talkie applications. It totally

realizes the translation from RF carrier to voice in

the RX path and from voice to RF carrier in the TX

path, requiring only one micro controller.

官方参考电路图:

头文件

/******************** (C) COPYRIGHT www.iotman.link ***************************
* File Name          : RDA1846.h
* Author             : glassine.zhang   www.iotman.link
* Email              : glassine@sina.com
* Version            : V0.0.1
* Date               : 2019/09/01
* Description        : RDA1846.c的头文件。
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __RDA1846_H
#define __RDA1846_H
/* Includes ------------------------------------------------------------------*//* Exported define -----------------------------------------------------------*///#define Channel_25K_Hz
#define RF_Freq     422995000
#define Chn_25K     0x01
#define Chn_12K5    0x00
#define SQ_On       On
#define SQ_Off      Off/*lq 1846 MR_ID */
#define RDA1846_MRID_RDA1846    0x0007
#define RDA1846_MRID_AT1846S    0x003F/* Exported types ------------------------------------------------------------*/
typedef struct tagRDA1846Freq
{U32 TX_Freq;       /* 发射频点 */U32 RX_Freq;      /* 接收频点 */
}stRDA1846Freq; typedef struct tagRDA1846SQ
{U8     SQ_OnOff;U16 SQ_Open_Threhold;      /* 发射频点 */U16 SQ_Shut_Threhold;     /* 接收频点 */
}stRDA1846SQ;typedef enum Rda1846TypeEnum
{RDA1846TYPE_OTHER = 0,RDA1846TYPE_RDA1846 = 1,RDA1846TYPE_AT1846S = 2,
}Rda1846TypeEnum;typedef struct Rda1846SelfCheckStruct
{U8  PdnOkFlg;U8  SenOkFlg;U8  DataCommOkFlg;              //lq clk and SDI/SDOU8  TypeOkFlg;Rda1846TypeEnum Rda1846Type;    //lq... 暂时未用        U8  StartFlg;U8  CompleteFlg;
}Rda1846SelfCheckStruct;typedef struct Rda1846Struct
{Rda1846TypeEnum Rda1846Type;        //lq 程序运行使用的1846类型Rda1846TypeEnum Rda1846TypeReal;    //lq 实际的1846类型
}Rda1846Struct;#ifndef On
#define On 1
#endif#ifndef Off
#define Off 0
#endif
/* Exported variables --------------------------------------------------------*/
extern stRDA1846Freq RDA1846Freq;
extern stRDA1846SQ RDA1846SQ;
extern Rda1846Struct Rda1846Instance;/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */extern void Init_RDA1846(void);void Init_RDA1846_Rx(U32 Hz);
void Init_RDA1846_Tx(U32 Hz);
void Init_RDA1846_SQ(U16 SQ_Open_threshold, U16 SQ_Shut_threshold);U16 Rd_RDA1846reg(U8 address);   //读寄存器值函数void RDA1846_Sleep(void);              //RF soc睡眠
void RDA1846_Wakeup(void);          //RF soc唤醒
void RDA1846_Reset(void);               //RF soc复位
#endif

程序内容

/******************** (C) COPYRIGHT www.iotman.link ***************************
* File Name          : RDA1846.c
* Author             : glassine.zhang   www.iotman.link
* Email              : glassine@sina.com
* Version            : V0.0.1
* Date               : 2019/09/01
* Description        : 这个文件对RDA1846进行配置,实现射频的控收/控发。
*******************************************************************************//* Includes ------------------------------------------------------------------*/
#include "stm32f10x_lib.h"
#include "def.h"
#include "RDA1846.h"
#include "sys.h"
#include "common.h"
#include "config.h"/* Public variables ---------------------------------------------------------*/
Rda1846Struct Rda1846Instance;/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
//SPI端口定义
#define SCLK PBout(11)  // PG12
#define SEN PBout(1)        // PG14
#define SDI PBout(10)       // PG13
#define SDO PBin(10)        // PG13
//RDA1846 模式设置管脚
#define PDN PBout(12)       // PG11/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
u16 Reg29_2A[2] = {0x0000, 0x0000};                //用于计算1846寄存器0x29 0x2A的值
u16 Reg30 = 0x0000;                                                //记录睡眠时 收发的状态
stRDA1846Freq RDA1846Freq = {0, 0};
stRDA1846SQ RDA1846SQ = {Off, 0, 0};/* Private function prototypes -----------------------------------------------*/
void WriteRda1846(u8 address, u16 data);            //往Rda1846寄存器里写数据,子函数,通过IO口模拟的方式
void Wr_RDA1846reg(u8 address, u16 data);           //写寄存器值函数
u16 ReadRda1846(u8 address);                                    //读数据从Rda1846寄存器,子函数,通过IO口模拟的方式
void Cal_TxRx_Freq(u32 Hz,u16 *Reg29_2A);           //计算发送和接收的频点
void RDA1846_SetRegVal(u8 address, u16 data);   //向1846寄存器打入数据
void RDA1846_Port_Init(void);                                   //RDA1846控制管脚初始化
void RDA1846_ConfigTxPower(void);/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name  : RDA1846_Port_Init
* Description    : RDA1846控制管脚初始化
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RDA1846_Port_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  //使能PORTB时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);SEN = 1;   //cs 无效SCLK = 0;   //在不用的时候,将时钟信号拉低SDI = 1;    //数据输出,在不用的时候拉高 PDN = 1;
}/*******************************************************************************
* Function Name  : WriteRda1846
* Description    : 往Rda1846寄存器里写数据,子函数,通过IO口模拟的方式
* Input          : 8bit address, 16bit data
* Output         : None
* Return         : None
*******************************************************************************/
void WriteRda1846(u8 address, u16 data)
{u8 i;u32 tmp_rda;GPIO_InitTypeDef GPIO_InitStructure;// SDIO (O)RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  //使能PORTG时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //PG13推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);tmp_rda = (((u32)address << 16) | data); // 写标志 + 地址 + 数据SEN = 0;   //cs 有效for(i=0; i<24; i++){SCLK = 0;if((tmp_rda & 0x800000) == 0x800000){SDI = 1;}else{SDI = 0;}SCLK = 1;tmp_rda <<=1;}SCLK = 0;SEN = 1;   //cs 无效SDI = 1;
}/*******************************************************************************
* Function Name  : Wr_RDA1846reg
* Description    : 往Rda1846寄存器里写数据
* Input          : 8bit address, 16bit data
* Output         : None
* Return         : None
*******************************************************************************/
void Wr_RDA1846reg(u8 address, u16 data)    //写函数
{if(address>0x7F)    //如果地址大于0x7F{WriteRda1846(0x7F,0x0001);WriteRda1846((address-0x80),data);WriteRda1846(0x7F,0x0000);}else                //正常情况下{WriteRda1846(address,data);}
}/*******************************************************************************
* Function Name  : ReadRda1846
* Description    : 读数据从Rda1846寄存器,子函数,通过IO口模拟的方式
* Input          : 8bit address
* Output         : 16bit data
* Return         : None
*******************************************************************************/
u16 ReadRda1846(u8 address)
{u8 i;u16 data;GPIO_InitTypeDef GPIO_InitStructure;// SDIO (O)RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PORTG时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //PG13推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);//=====地址byte中的第一个bit代表读(1)或者写(0)====address |= 0x80;   // 读标志 + 地址SEN = 0;       //cs 有效for(i=0; i<8; i++){SCLK = 0;if((address & 0x80) == 0x80){SDI = 1;}else{SDI = 0;}address <<=1;SCLK = 1;}SCLK = 0;// SDIO (I)RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PORTG时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //PG13浮空输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);data = 0x0000;  //将变量清零for(i=0; i<16; i++)    //获取数据{SCLK = 1;data <<= 1;if(SDO){data += 1;}SCLK = 0;}SEN = 1;    //cs 无效SDI = 1;return data;
}/*******************************************************************************
* Function Name  : Rd_RDA1846reg
* Description    : 读数据从Rda1846寄存器
* Input          : 8bit address
* Output         : 16bit data
* Return         : None
*******************************************************************************/
u16 Rd_RDA1846reg(u8 address)   //读函数
{u16 temp=0x0000;if(address>0x7F)       //如果地址大于0x7F{WriteRda1846(0x7F,0x0001);temp=ReadRda1846(address-0x80);WriteRda1846(0x7F,0x0000);}else                  //正常情况下{temp=ReadRda1846(address);}return temp;
}/*******************************************************************************
* Function Name  : Cal_TxRx_Freq
* Description    : 计算发送和接收的频点
* Input          : 32bit XX Hz,16bit 数组指针
* Output         : 16bit 数组值
* Return         : None
*******************************************************************************/
void Cal_TxRx_Freq(u32 Hz,u16 *Reg29_2A)
{
#if CONFIG_RDA1846
#if (CONFIG_RDA1846 && CONFIG_AT1846S)if (Rda1846Instance.Rda1846Type == RDA1846TYPE_RDA1846){
#endif    /*lq 写入寄存器的数据的单位为 1kHz/8 */*(Reg29_2A++)=((u32)(Hz/125))>>16;*Reg29_2A=((u32)(Hz/125))&0xFFFF;
#if (CONFIG_RDA1846 && CONFIG_AT1846S)}
#endif
#endif#if CONFIG_AT1846S
#if (CONFIG_RDA1846 && CONFIG_AT1846S)if (Rda1846Instance.Rda1846Type == RDA1846TYPE_AT1846S){
#endif    /*lq 写入寄存器的数据的单位为 1kHz/16 */*(Reg29_2A++) = ((u32)(Hz * 2 / 125)) >> 16;*Reg29_2A = ((u32)(Hz * 2 / 125)) & 0xFFFF;
#if (CONFIG_RDA1846 && CONFIG_AT1846S)}
#endif
#endif
}/*******************************************************************************
* Function Name  : RDA1846_SetRegVal
* Description    : 输入寄存器值,再读回来 验证读写正确 测试版程序使用 正式版只使用Wr_RDA1846reg函数
* Input          : u8 address, u16 data
* Output         : 打印返回值
* Return         : None
*******************************************************************************/
void RDA1846_SetRegVal(u8 address, u16 data)
{Wr_RDA1846reg(address,data);
}/*******************************************************************************
* Function Name  : Init_RDA1846
* Description    : 初始化RDA1846函数
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void Init_RDA1846(void)
{U16 regVal;RDA1846_Port_Init();/*lq 复位并开启1846 */RDA1846_SetRegVal(0x30, 0x0001);    //lq reset registerDelay_ms(50);RDA1846_SetRegVal(0x30, 0x0004);    //lq poweron 1846/*lq 判断1846型号 */regVal = Rd_RDA1846reg(0x01); if (regVal == RDA1846_MRID_RDA1846){Rda1846Instance.Rda1846TypeReal = RDA1846TYPE_RDA1846;Rda1846Instance.Rda1846Type = RDA1846TYPE_RDA1846;}else if (regVal == RDA1846_MRID_AT1846S){Rda1846Instance.Rda1846TypeReal = RDA1846TYPE_AT1846S;Rda1846Instance.Rda1846Type = RDA1846TYPE_AT1846S;}else{Rda1846Instance.Rda1846TypeReal = RDA1846TYPE_OTHER;Rda1846Instance.Rda1846Type = RDA1846TYPE_AT1846S;      //lq 默认为AT1846S    }#if CONFIG_RDA1846
#if (CONFIG_RDA1846 && CONFIG_AT1846S)if (Rda1846Instance.Rda1846Type == RDA1846TYPE_RDA1846){
#endif//25kRDA1846_SetRegVal(0x02,0x0698);RDA1846_SetRegVal(0x04,0x0FD0);RDA1846_SetRegVal(0x08,0x02A0);RDA1846_SetRegVal(0x0B,0x1A10);RDA1846_SetRegVal(0x2B,0x32C8);RDA1846_SetRegVal(0x2C,0x1964);RDA1846_SetRegVal(0x32,0x627C);RDA1846_SetRegVal(0x33,0x0AF2);RDA1846_SetRegVal(0x47,0x2C2F);RDA1846_SetRegVal(0x4E,0x293A);RDA1846_SetRegVal(0x54,0x1D4C);RDA1846_SetRegVal(0x56,0x0652);RDA1846_SetRegVal(0x6E,0x062D);RDA1846_SetRegVal(0x70,0x1029);//If 0x85 is  0x001F, Rfoutput power is 8dBm , ACP is -63dB in 12.5KHz and -65dB in 25KHz//If 0x85 is  0x0018, Rfoutput power is 6dBm , ACP is -64dB in 12.5KHz and -66dB in 25KHz//If 0x85 is  0x0017, Rfoutput power is -3dBm , ACP is -68dBc in 12.5KHz and -68dBc in 25KHzRDA1846_SetRegVal(0x85,0x0018);
#if 1   //高通normal  voice lpf bypass == normalRDA1846_SetRegVal(0x58,0x03CF);
#else   //高通旁路RDA1846_SetRegVal(0x58,0x03FF);
#endifRDA1846_SetRegVal(0x1F,0x1000);   //set gpio sq onRDA1846_SetRegVal(0x30,0x30A4);Delay_ms(50);RDA1846_SetRegVal(0x30,0x30A6);Delay_ms(100);RDA1846_SetRegVal(0x30,0x3006);Delay_ms(100);RDA1846_SetRegVal(0x0F,0x00E4);Init_RDA1846_Tx(161975000);RDA1846_Sleep();#if (CONFIG_RDA1846 && CONFIG_AT1846S)}
#endif#endif#if CONFIG_AT1846S
#if (CONFIG_RDA1846 && CONFIG_AT1846S)if (Rda1846Instance.Rda1846Type == RDA1846TYPE_AT1846S){
#endif  /*lq initial */RDA1846_SetRegVal(0x04, 0x0FD0);    //lq select crystal frequency,26MHzRDA1846_SetRegVal(0x31, 0x0031);RDA1846_SetRegVal(0x33, 0x44A5);    //lq agc numberRDA1846_SetRegVal(0x34, 0x2B87);    //lq rx digital gainRDA1846_SetRegVal(0x41, 0x470F);    //lq digital gain for TxRDA1846_SetRegVal(0x44, 0x0DFF);    //lq digital gain for TxRDA1846_SetRegVal(0x47, 0x7FFF);    //lq soft muteRDA1846_SetRegVal(0x4F, 0x2C62);RDA1846_SetRegVal(0x53, 0x0094);RDA1846_SetRegVal(0x55, 0x0081);RDA1846_SetRegVal(0x56, 0x0B22);    //lq SQ detection time(SQ setting)RDA1846_SetRegVal(0x57, 0x1C00);    //lq bypass rssi_lpfilterRDA1846_SetRegVal(0x5A, 0x0EDB);    //lq SQ detection time(SQ setting)RDA1846_SetRegVal(0x60, 0x101E);    //lq noise2_th(SQ setting)RDA1846_SetRegVal(0x63, 0x16AD);    //lq Pre_emphasis bypass thRDA1846_SetRegVal(0x30, 0x40A4);    //lq calibrationDelay_ms(50);RDA1846_SetRegVal(0x30, 0x40A6);Delay_ms(100);RDA1846_SetRegVal(0x30, 0x4006);Delay_ms(10);/*lq initial mode 25kHz */RDA1846_SetRegVal(0x15, 0x1F00);    //lq tuning_bitRDA1846_SetRegVal(0x32, 0x7564);    //lq agc target power
#if 0RDA1846_SetRegVal(0x3A, 0x44C3);    //lq modu_det_sel(SQ setting )
#elseRDA1846_SetRegVal(0x3A, 0x04C3);    //lq TX Voice Channel Select = Tx nothing
#endifRDA1846_SetRegVal(0x3C, 0x172C);    //lq Pk_det_th(SQ setting )RDA1846_SetRegVal(0x3F, 0x29D2);    //lq Rssi3_th(SQ setting )RDA1846_SetRegVal(0x48, 0x2141);    //lq noise1_th(SQ setting )RDA1846_SetRegVal(0x59, 0x0A50);    //lq Tx FM devitation RDA1846_SetRegVal(0x62, 0x2346);    //lq modu_det_th(SQ setting )RDA1846_SetRegVal(0x65, 0x248A);    //lq setting th_sif for SQ rssi detectRDA1846_SetRegVal(0x66, 0xFF2E);    //lq rssi_comp and afc rangeRDA1846_SetRegVal(0x86, 0x0024);    //lq agc gain talbeRDA1846_SetRegVal(0x87, 0x0214);RDA1846_SetRegVal(0x88, 0x0224);RDA1846_SetRegVal(0x89, 0x0314);RDA1846_SetRegVal(0x8A, 0x0324);RDA1846_SetRegVal(0x8B, 0x0344);RDA1846_SetRegVal(0x8C, 0x0384);RDA1846_SetRegVal(0x8D, 0x1384);RDA1846_SetRegVal(0x8E, 0x1B84);RDA1846_SetRegVal(0x8F, 0x3F84);RDA1846_SetRegVal(0x92, 0xE0EB);RDA1846_ConfigTxPower();Init_RDA1846_Tx(161975000);RDA1846_Sleep();#if (CONFIG_RDA1846 && CONFIG_AT1846S)}
#endif
#endif
}/*******************************************************************************
* Function Name  : Init_RDA1846_Rx
* Description    : 控收
* Input          : 32bit Hz
* Output         : None
* Return         : None
*******************************************************************************/
void Init_RDA1846_Rx(u32 Hz)
{U16 RegVal;Cal_TxRx_Freq(Hz,Reg29_2A);RDA1846_SetRegVal(0x29,Reg29_2A[0]); RDA1846_SetRegVal(0x2A,Reg29_2A[1]);    #if CONFIG_RDA1846
#if (CONFIG_RDA1846 && CONFIG_AT1846S)if (Rda1846Instance.Rda1846Type == RDA1846TYPE_RDA1846){
#endif    //25k, AutoSQ offRDA1846_SetRegVal(0x30,0x3006);RDA1846_SetRegVal(0x30,0x3026);
#if (CONFIG_RDA1846 && CONFIG_AT1846S)}
#endif
#endif#if CONFIG_AT1846S
#if (CONFIG_RDA1846 && CONFIG_AT1846S)if (Rda1846Instance.Rda1846Type == RDA1846TYPE_AT1846S){
#endif    /*lq 13MHz/26MHzcrystal frequency, 25kHz mode */RDA1846_SetRegVal(0x30, 0x7006);RDA1846_SetRegVal(0x30, 0x7026);Delay_ms(10);/*lq 查看PLL是否锁定 */RegVal = Rd_RDA1846reg(0x0d);RegVal = ((RegVal >> 15) & 0x01);/*lq 若未锁定,则重新校准PLL*/if(RegVal == 0)  {/*lq 检测到失锁 */RDA1846_SetRegVal(0x27, 0x74A4);Delay_ms(1);                      //wait 1ms(时间可调) RDA1846_SetRegVal(0x27, 0x7CA4);RDA1846_SetRegVal(0x27, 0x6CA4);}
#if (CONFIG_RDA1846 && CONFIG_AT1846S)}
#endif
#endif}/*******************************************************************************
* Function Name  : Init_RDA1846_Tx
* Description    : 控发
* Input          : 32bit Hz
* Output         : None
* Return         : None
*******************************************************************************/
void Init_RDA1846_Tx(u32 Hz)
{U16 RegVal;Cal_TxRx_Freq(Hz,Reg29_2A);RDA1846_SetRegVal(0x29,Reg29_2A[0]); RDA1846_SetRegVal(0x2A,Reg29_2A[1]);#if CONFIG_RDA1846
#if (CONFIG_RDA1846 && CONFIG_AT1846S)if (Rda1846Instance.Rda1846Type == RDA1846TYPE_RDA1846){
#endif    //25k, AutoSQ offRDA1846_SetRegVal(0x30,0x3006);RDA1846_SetRegVal(0x30,0x3046);Delay_ms(10);//等待10ms//查看是否锁定RegVal = Rd_RDA1846reg(0x5c);RegVal = ((RegVal>>11) & 0x01);if(RegVal == 0)  //重新校准PLL{//检测到失锁RDA1846_SetRegVal(0x27,0x14A0);// 0x27H=0x14A0Delay_ms(1);                  //wait 1ms(时间可调) RDA1846_SetRegVal(0x27,0x1CA0);//0x27H=0x1CA0RDA1846_SetRegVal(0x27,0x04A0);//0x27H=0x04A0 }
#if (CONFIG_RDA1846 && CONFIG_AT1846S)}
#endif
#endif#if CONFIG_AT1846S
#if (CONFIG_RDA1846 && CONFIG_AT1846S)if (Rda1846Instance.Rda1846Type == RDA1846TYPE_AT1846S){
#endif    /*lq 13MHz/26MHzcrystal frequency, 25kHz mode */RDA1846_SetRegVal(0x30, 0x7006);RDA1846_SetRegVal(0x30, 0x7046);Delay_ms(10);/*lq 查看PLL是否锁定 */RegVal = Rd_RDA1846reg(0x0d);RegVal = ((RegVal >> 15) & 0x01);/*lq 若未锁定,则重新校准PLL*/if(RegVal == 0)  {/*lq 检测到失锁 */RDA1846_SetRegVal(0x27, 0x74A4);Delay_ms(1);                      //wait 1ms(时间可调) RDA1846_SetRegVal(0x27, 0x7CA4);RDA1846_SetRegVal(0x27, 0x6CA4);}
#if (CONFIG_RDA1846 && CONFIG_AT1846S)}
#endif
#endif
}/*******************************************************************************
* Function Name  : Init_RDA1846_SQ
* Description    : 初始化RDA1846的静噪
* Input          : u16 SQ_Open_threshold, u16 SQ_Shut_threshold
* Output         : None
* Return         : None
*******************************************************************************/
void Init_RDA1846_SQ(u16 SQ_Open_threshold, u16 SQ_Shut_threshold)
{RDA1846_SetRegVal(0x48,SQ_Open_threshold);RDA1846_SetRegVal(0x49,SQ_Shut_threshold);
}/*******************************************************************************
* Function Name  : RDA1846_Sleep
* Description    : 休眠RDA1846
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RDA1846_Sleep(void)
{u16 temp;Reg30 = Rd_RDA1846reg(0x30);temp = Reg30 & 0xFF9F;  //30H[5..6] == 00RDA1846_SetRegVal(0x30, temp);PDN = 0;
}/*******************************************************************************
* Function Name  : RDA1846_Wakeup
* Description    : 唤醒RDA1846
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RDA1846_Wakeup(void)
{PDN = 1;                                                                    //lq 唤醒RDA1846#if CONFIG_RDA1846
#if (CONFIG_RDA1846 && CONFIG_AT1846S)if (Rda1846Instance.Rda1846Type == RDA1846TYPE_RDA1846){
#endif    Delay_ms(10);       //延时10ms
#if (CONFIG_RDA1846 && CONFIG_AT1846S)}
#endif
#endif#if CONFIG_AT1846S
#if (CONFIG_RDA1846 && CONFIG_AT1846S)if (Rda1846Instance.Rda1846Type == RDA1846TYPE_AT1846S){
#endif    Delay_ms(100);      //lq 延时100ms
#if (CONFIG_RDA1846 && CONFIG_AT1846S)}
#endif
#endifRDA1846_SetRegVal(0x30, Reg30);
}/*******************************************************************************
* Function Name  : RDA1846_Reset
* Description    : 复位RDA1846寄存器
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RDA1846_Reset(void)
{RDA1846_SetRegVal(0x30,0x0001);    //软件复位
}/*******************************************************************************
* Function Name  : RDA1846_ConfigTxPower
* Description    : 配置AT1846S发射功率
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RDA1846_ConfigTxPower(void)
{U16 regVal;regVal = Rd_RDA1846reg(0x0A);regVal &= (0x87FF);             //lq reset power bitsregVal |= (0x000C << 11);       //lq config power bits, Tx power = 6.2dBmRDA1846_SetRegVal(0x0A, regVal);
}/*******************************************************************************
* Function Name  : WriteRda1846
* Description    : 往Rda1846寄存器里写数据,子函数,通过IO口模拟的方式
* Input          : 8bit address, 16bit datacsFlg - 片选是否使能
* Output         : None
* Return         : None
*******************************************************************************/
void WriteRda1846SelfCheck(u8 address, u16 data, u8 csFlg)
{u8 i;u32 tmp_rda;GPIO_InitTypeDef GPIO_InitStructure;// SDIO (O)RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  //使能PORTG时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //PG13推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);tmp_rda = (((u32)address << 16) | data); // 写标志 + 地址 + 数据if (csFlg == TRUE)    {SEN = 0;  //cs 有效    }else{SEN = 1;  //cs 无效        }for(i=0; i<24; i++){SCLK = 0;if((tmp_rda & 0x800000) == 0x800000){SDI = 1;}else{SDI = 0;}SCLK = 1;tmp_rda <<=1;}SCLK = 0;SEN = 1;  //cs 无效SDI = 1;
}/*******************************************************************************
* Function Name  : ReadRda1846SelfCheck
* Description    : 读数据从Rda1846寄存器,子函数,通过IO口模拟的方式
* Input          : address - 8bit addresscsFlg - 片选是否使能
* Output         : 16bit data
* Return         : None
*******************************************************************************/
u16 ReadRda1846SelfCheck(u8 address, u8 csFlg)
{u8 i;u16 data;GPIO_InitTypeDef GPIO_InitStructure;// SDIO (O)RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PORTG时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //PG13推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);//=====地址byte中的第一个bit代表读(1)或者写(0)====address |= 0x80;   // 读标志 + 地址if (csFlg == TRUE){SEN = 0;      //cs 有效    }else{SEN = 1;  //cs 无效        }for (i=0; i<8; i++){SCLK = 0;if ((address & 0x80) == 0x80){SDI = 1;}else{SDI = 0;}address <<=1;SCLK = 1;}SCLK = 0;// SDIO (I)RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  //使能PORTG时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //PG13浮空输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);data = 0x0000;  //将变量清零for (i=0; i<16; i++)   //获取数据{SCLK = 1;data <<= 1;if (SDO){data += 1;}SCLK = 0;}SEN = 1;   //cs 无效SDI = 1;return data;
}/*******************************************************************************
* Function Name  : Rd_RDA1846reg
* Description    : 读数据从Rda1846寄存器
* Input          : address - 8bit addresscsFlg - 片选是否使能
* Output         : 16bit data
* Return         : None
*******************************************************************************/
u16 Rd_RDA1846regSelfCheck(u8 address, u8 csFlg)    //读函数
{u16 temp = 0x0000;if(address > 0x7F)       //如果地址大于0x7F{WriteRda1846SelfCheck(0x7F, 0x0001, csFlg);temp = ReadRda1846SelfCheck(address - 0x80, csFlg);WriteRda1846SelfCheck(0x7F, 0x0000, csFlg);}else                    //正常情况下{temp = ReadRda1846SelfCheck(address, csFlg);}return temp;
}/*******************************************************************************
* Function Name  : RDA1846_SelfCheck
* Description    : RDA1846自检
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RDA1846_SelfCheck(Rda1846SelfCheckStruct *pRda1846SelfCheckStruct)
{U16 regVal;if (pRda1846SelfCheckStruct->StartFlg == TRUE){/*lq PDN使能 */RDA1846_Wakeup();/*lq SEN使能 */regVal = Rd_RDA1846regSelfCheck(0x00, TRUE);if (regVal == 0x1846){pRda1846SelfCheckStruct->DataCommOkFlg = TRUE;/*lq 读芯片型号 */regVal = Rd_RDA1846regSelfCheck(0x01, TRUE);if (regVal == RDA1846_MRID_RDA1846){pRda1846SelfCheckStruct->Rda1846Type = RDA1846TYPE_RDA1846;pRda1846SelfCheckStruct->TypeOkFlg = TRUE;}else if (regVal == RDA1846_MRID_AT1846S){pRda1846SelfCheckStruct->Rda1846Type = RDA1846TYPE_AT1846S;pRda1846SelfCheckStruct->TypeOkFlg = TRUE;}else{pRda1846SelfCheckStruct->Rda1846Type = RDA1846TYPE_OTHER;pRda1846SelfCheckStruct->TypeOkFlg = FALSE;}/*lq SEN失能 */regVal = Rd_RDA1846regSelfCheck(0x00, FALSE);if (regVal == 0x1846){pRda1846SelfCheckStruct->SenOkFlg = FALSE;           }else{pRda1846SelfCheckStruct->SenOkFlg = TRUE;}
#if 0    /*lq PDN失能 */RDA1846_Sleep();    //lq RDA1846即使sleep,仍可进行数据通信,无法验证PDN/*lq SEN使能 */regVal = Rd_RDA1846regSelfCheck(0x00, TRUE);if (regVal == 0x1846){pRda1846SelfCheckStruct->PdnOkFlg = FALSE;           }else{pRda1846SelfCheckStruct->PdnOkFlg = TRUE;}
#endif}else{/*lq 无法进一步确定问题的准确原因 */pRda1846SelfCheckStruct->PdnOkFlg = FALSE;pRda1846SelfCheckStruct->SenOkFlg = FALSE;pRda1846SelfCheckStruct->DataCommOkFlg = FALSE;pRda1846SelfCheckStruct->TypeOkFlg = FALSE;pRda1846SelfCheckStruct->Rda1846Type = RDA1846TYPE_OTHER;}RDA1846_Sleep(); pRda1846SelfCheckStruct->CompleteFlg = TRUE;               pRda1846SelfCheckStruct->StartFlg = FALSE;}
}/*******************************************************************************
* 名称  : EEPROM_EepromSelfCheckStructInit
* 描述  : 初始化结构体
* 输入  : pEepromSelfCheckStruct - EepromSelfCheckStruct结构体指针
* 输出  : 无
* 返回  : 无
*******************************************************************************/
void RDA1846_Rda1846SelfCheckStructInit(Rda1846SelfCheckStruct *pRda1846SelfCheckStruct)
{pRda1846SelfCheckStruct->PdnOkFlg = FALSE;pRda1846SelfCheckStruct->SenOkFlg = FALSE;pRda1846SelfCheckStruct->DataCommOkFlg = FALSE;pRda1846SelfCheckStruct->TypeOkFlg = FALSE;pRda1846SelfCheckStruct->Rda1846Type = RDA1846TYPE_OTHER;pRda1846SelfCheckStruct->StartFlg = TRUE;       pRda1846SelfCheckStruct->CompleteFlg = FALSE;
}

RDA1846的驱动程序和频率设定相关推荐

  1. linux 系统频率,Linux下CPU的手动频率设定

    众所周知的是,CPU的频率和它的实际性能特别是整数运算能力上有着相当强的关联性.但同时CPU的频率也跟它的功耗成正比,而功耗是有一个TDP的热功耗上限.根据当下多核CPU.多任务的趋势我们很容易就联想 ...

  2. 台达DVP ES系列plc与3台台达MS300变频器通讯程序 实现频率设定,启停控制,实际频率读取等

    台达DVP ES系列plc与3台台达MS300变频器通讯程序 器件:台达DVP ES系列的PLC,3台台达MS300系列变频器,昆仑通态 功能:实现频率设定,启停控制,实际频率读取等. 资料:带注释P ...

  3. 欧姆龙CJ2M 与海利普变频器通讯 协议宏方式 欧姆龙通讯模块协议宏 功能:通过触摸屏进行启停和点动,频率设定,加减速时间,点动频率设定

    欧姆龙CJ2M 与海利普变频器通讯 协议宏方式可直接拿来实用了,欧姆龙CJ2M PLC与变频器协议宏通讯 采用器件:欧姆龙CJ2M的PLC,1个CJ1W SCU21 V1通讯模块,1台海利普HLP-B ...

  4. 信捷PLC与7台三菱变频器485通讯案例 对7台变频器进行单独频率设定,启停控制,频率读取

    信捷PLC与7台三菱变频器485通讯案例功能:用信捷PLC与7台三菱变频器modbus通讯,自由通讯协议 配件:信捷XC系列PLC,三菱E740变频器,昆仑通态触摸屏 功能:对7台变频器进行单独频率设 ...

  5. 三菱FX1N 或2N 与台达VFD M变频器modbus RTU通讯程序 进行频率设定,频率读取,正反转启停,点动控制。

    三菱FX1N 或2N 与台达VFD M变频器modbus RTU通讯程序 可直接拿来实用了,三菱FX PLC与台达变频器modbus RTU通讯 采用器件:三菱FX1N 24MT PLC,1个FX1N ...

  6. 三菱FX1N PLC 485与三菱变频器modbus通讯 对变频器进行频率设定,加减速时间设置,正反转,启停控制

    三菱FX1N PLC 485与三菱变频器modbus通讯可直接拿来实用了,三菱FX PLC与三菱变频器通讯 采用器件:三菱FX1N PLC,FX1N485BD板,1台三菱E740变频器,三菱FX2N ...

  7. 三菱FX3U与台达变频器通讯 采用485方式,modbus RTU协议,对台达变频器频率设定

    三菱FX3U与台达变频器通讯器件:三菱FX3U PLC+FX3U 485BD板,台达VFD变频器,昆仑通态触摸屏 功能:采用485方式,modbus RTU协议,对台达变频器频率设定,正反转,点动控制 ...

  8. 三菱fx3u+485ADP-MB与3台台达变频器modbus通讯程序 通过三菱fx3u 485ADP-MB板对3台台达变频器进行modbus通讯,实现频率设定,启停控制,输出频率读取,输出电压读取

    三菱fx3u+485ADP-MB与3台台达变频器modbus通讯程序 功能:通过三菱fx3u 485ADP-MB板对3台台达变频器进行modbus通讯,实现频率设定,启停控制,输出频率读取,输出电压读 ...

  9. 三菱FX3U与台达MS300变频器modbus通讯 采用485方式,modbus RTU协议,对台达变频器频率设定

    三菱FX3U与台达MS300变频器modbus通讯案例 配件要求:三菱FX3U PLC+FX3U 485BD板,台达MS300变频器,昆仑通态触摸屏 功能:采用485方式,modbus RTU协议,对 ...

最新文章

  1. Python调用茉莉机器人API接口
  2. 中科大计算机学院的保研率,中科大2021届保研率44.7%,少年班83.4%,物理计算机人数最多...
  3. HttpServletRequest看这篇文章就够了
  4. RoRoWoBlog 开源博客系统介绍
  5. Linux版本配置环境变量,如何linux环境下配置环境变量过程图解
  6. Linux下Keepalived 安装与配置 此博文包含图片
  7. [WebApp开发]基础教程-Web App开发入门
  8. JAVA初学者推荐《Java开发实战经典》李兴华著
  9. 怎么做真人qq秀_【假期怎么过】看完这8部真人秀,再去英国留学!
  10. matlab2010b无法启动,MATLAB2010b simulink 启动警告问题
  11. html发布机制tacat,序列分析一般程序中的一个实例
  12. Matlab 保存TXT文件 打开乱码 (解决)
  13. Congestion问题怎么解决?
  14. 马王堆版《道德经》--原原本本的帛书版(转载)
  15. 神经管理学告诉你:学了管理学就能运筹帷幄吗?
  16. 宏碁暗影骑士擎2022-重装系统-扬声器无声音
  17. Ubuntu设置屏幕分辨率
  18. 爬虫网易云音乐,热评,词云,prettytable。
  19. Android手机GPS卫星定位与通过WLAN与移动网络定位的区别?
  20. 垃圾分类里有哪些淘金机会?​

热门文章

  1. matlab非线性优化求解,用MATLAB求解非线性优化问题
  2. ZYNQ上无DDR加载应用
  3. 蓝懿学习之tableView
  4. 小程序源码:2022强大的修复版趣味心理测试小程序源码,趣味测试引流裂变神器
  5. 面对封号潮,跨境收款如何做到不受牵连?
  6. linux桌面图标不见_Ubuntu系统桌面任务栏和启动器全部消失解决方案
  7. 迅雷起死回生背后的男人,竟然是雷军
  8. MySQL如何判断日期(datetime)是否是同一天
  9. 带上紧箍咒,特斯拉辅助驾驶系统即将更新
  10. 小孔成像总结_初中物理解题技巧+方法总结,可以说很到位了!