R820T芯片内部结构:
R820T配合RTL2832U的RTL-SDR:
软件无线电通过数字信号处理来实现无线信号的调制解调。在RTL-SDR中通过调谐芯片(R820T、E4000)将无线信号下变频至低中频信号,由RTL2832U中的ADC采样得到数字信号,再进行数字下变频得到基带信号,由USB传送给计算机。RTL-SDR得到的基带信号是I/Q信号交错排列的形式,计算机对基带信号进行分离得到两路信号即I/Q信号进行解调。
其简易电路图:
R820T寄存器配置:
在tuner_r82xx.c文件中,可以找到配置的默认值:
- /* Those initial values start from REG_SHADOW_START */
- static const uint8_t r82xx_init_array[NUM_REGS] = {
- 0x83, 0x32, 0x75, /* 05 to 07 */
- 0xc0, 0x40, 0xd6, 0x6c, /* 08 to 0b */
- 0xf5, 0x63, 0x75, 0x68, /* 0c to 0f */
- 0x6c, 0x83, 0x80, 0x00, /* 10 to 13 */
- 0x0f, 0x00, 0xc0, 0x30, /* 14 to 17 */
- 0x48, 0xcc, 0x60, 0x00, /* 18 to 1b */
- 0x54, 0xae, 0x4a, 0xc0 /* 1c to 1f */
- };
根据R820T芯片手册,部分寄存器解释如下:
- ------------R5=0x83---------------
- [7]Loop through ON/OFF = off
- [5]LNA 1 power control = on
- [4]LNA gain mode switch = on
- [3:0]LNA manual gain control = 0011
- ------------R6=0x32--------------
- [7]Power detector 1 on/off = on
- [6]Power detector 3 on/off = off
- [5]Filter gain 3db = +3db
- [2:0]LNA power control = 010
- ------------R7=0x75---------------
- [6]Mixer power = on
- [5]Mixer current control = normal current
- [4]Mixer gain mode = auto mode
- [3:0]Mixer manual gain control = 0101
- ------------R8=0xc0---------------
- [7]Mixer buffer power on/off = on
- [6]Mixer buffer current setting = low current
- [5:0]Image Gain Adjustment = 0
- ------------R9=0x40----------------
- [7]IF Filter power on/off = filter on
- [6]IF Filter current = low current
- [5:0]Image Phase Adjustment = 0
- ------------R10=0xd6--------------
- [7]Filter power on/off = on
- [6:5]Filter power control = 10
- [4] 1
- [3:0]Filter bandwidth manual fine tune = 0110
- ------------R11=0x6c----------------
- [7] 0
- [6:5]Filter bandwidth manual course tunnel = middle
- [4] 0
- [3:0]High pass filter corner control = 1100
- ------------R12=0xf5-------------
- [6]VGA power control = vga power on
- [4]VGA GAIN manual / pin selector = IF vga gain controlled by vagc pin
- [3:0]IF vga manual gain control = 0101
- ------------R13=0x63--------------
- [7:4]LNA agc power detector voltage threshold high setting = 0110
- [3:0]LNA agc power detector voltage threshold low setting = 0011
- ------------R14=0x75--------------
- [7:4]MIXER agc power detector voltage threshold high setting = 0111
- [3:0]MIXER agc power detector voltage threshold low setting = 0110
- ------------R15=0x68---------------
- [4]Clock out pin control = clk output on
- [1]AGC clk control = internal agc clock on
- ------------R16=0x6c----------------
- [7:5]PLL to Mixer divider number control = mixer in = vco out
- [4]PLL Reference frequency Divider = fref=xtal_freq
- [1:0]Internal xtal cap setting = no cap
- ------------R17=0x83--------------
- [7:6]PLL analog low drop out regulator switch = 2.0V
- ------------R18=0x80---------------
- [7:6]PLL integer divider number input Si2c = 10
- [5:0]PLL integer divider number input Ni2c = 0
- --------------------------------------
- ------------R30=0x4a------------------
- [5:0]Power detector timing control = 001010
- [6]Filter extension under weak signal = Enable
librtlsdr.c文件修改较多,其中rtlsdr_read_array函数和rtlsdr_write_array函数需要重新配置为ZYNQ的I2C。
- int rtlsdr_read_array(rtlsdr_dev_t *dev, uint8_t block, uint16_t addr, uint8_t *array, uint8_t len)
- {
- int r;
- uint16_t index = (block << 8);
-
- // r = libusb_control_transfer(dev->devh, CTRL_IN, 0, addr, index, array, len, CTRL_TIMEOUT);
- r = test_i2c_read(dev->devh, addr, array, len);
- #if 0
- if (r < 0)
- fprintf(stderr, "%s failed with %d\n", __FUNCTION__, r);
- #endif
- return r;
- }
-
- int rtlsdr_write_array(rtlsdr_dev_t *dev, uint8_t block, uint16_t addr, uint8_t *array, uint8_t len)
- {
- int r;
- if(IICB != block)
- return 0;
- // uint16_t index = (block << 8) | 0x10;
- // r = libusb_control_transfer(dev->devh, CTRL_OUT, 0, addr, index, array, len, CTRL_TIMEOUT);
- r = test_i2c_write(dev->devh, addr, array, len);
- #if 0
- if (r < 0)
- fprintf(stderr, "%s failed with %d\n", __FUNCTION__, r);
- #endif
- return r;
- }
在ZYNQ的main中执行如下,R820T即可输出波形:
- #include <stdio.h>
- #include "xparameters.h"
- #include "xil_cache.h"
- #include "xiic.h"
- #include "axi_reg.h"
- #include "xil_io.h"
- #include "xgpio.h"
- #include "tuner_r82xx.h"
- #include "rtl-sdr2.h"
-
-
- #define DEFAULT_FREQUENCY (98*1000*1000)
- #define DEFAULT_SAMPLE_RATE 2048000
- XGpio gpio0, gpio1;
- XIic IIC;
- static rtlsdr_dev_t *rtlsdr_dev = NULL;
-
- /*****************************************************************************/
- unsigned test_i2c_write(void *dev, u8 i2c_addr, u8 *buf, u16 len)
- {
- volatile unsigned SentByteCount;
- SentByteCount = XIic_Send(XPAR_IIC_0_BASEADDR, (i2c_addr>>1),
- buf, len, XIIC_STOP);
- return SentByteCount;
- }
-
- unsigned test_i2c_read(void *dev, u8 i2c_addr, u8 *buf, u16 len)
- {
- volatile unsigned ReceivedByteCount;
- ReceivedByteCount = XIic_Recv(XPAR_IIC_0_BASEADDR, (i2c_addr>>1),
- buf, len, XIIC_STOP);
- return ReceivedByteCount;
- }
-
- int interface_init() {
- int i;
- i = XIic_Initialize(&IIC, XPAR_IIC_0_DEVICE_ID);
- if (i != XST_SUCCESS) {
- return XST_FAILURE;
- }
- i = XGpio_Initialize(&gpio0, XPAR_GPIO_0_DEVICE_ID);
- if (i != XST_SUCCESS) {
- return XST_FAILURE;
- }
- XGpio_SetDataDirection(&gpio0, 1, 0xFF);
- return 1;
- }
-
- int main ()
- {
- int r = 0;
- int gain = 0;
- int ppm_error = 0;
- uint32_t frequency = DEFAULT_FREQUENCY;//Hz
- uint32_t samp_rate = DEFAULT_SAMPLE_RATE;
-
- r = interface_init();
- r = rtlsdr_open(&rtlsdr_dev, (uint32_t)0);
- r = rtlsdr_set_sample_rate(rtlsdr_dev, samp_rate);
- r = rtlsdr_set_center_freq(rtlsdr_dev, frequency);
-
- if (0 == gain) {
- /* Enable automatic gain */
- r = rtlsdr_set_tuner_gain_mode(rtlsdr_dev, 0);
- } else {
- /* Enable manual gain */
- gain = nearest_gain(rtlsdr_dev, gain);
- r = rtlsdr_set_tuner_gain_mode(rtlsdr_dev, 1);
- r = rtlsdr_set_tuner_gain(rtlsdr_dev, gain);
- }
-
- r = rtlsdr_set_freq_correction(rtlsdr_dev, ppm_error);
-
- while(1);
- return 0;
- }
使用示波器抓取波形: