搜索
bottom↓
回复: 2

分享一个RDA5807驱动程序!!!

[复制链接]

出0入0汤圆

发表于 2013-9-22 17:42:18 | 显示全部楼层 |阅读模式
RDA5807的版本很多,寄存器也不大一样,我看了datasheeet 好多遍了,不明白其中的道理哦
  1. /*--------------------------------------------------------------------------*/
  2. /**@file RDA5807P.C
  3.    @brief FM模块RDA5807P驱动
  4.    @details FM模块RDA5807P的驱动函数
  5.    @author LZZ
  6.    @date 2010-08-17
  7.    @note 本驱动支持模块,支持32K共晶振,支持P05输出时钟,三种方式时钟的程序一样
  8.          通过识别ID来区别各种版本
  9. */
  10. /*----------------------------------------------------------------------------*/

  11. #include "include.h"
  12. #include "I2C_OTP.h"
  13. #include "RDA5807P.h"
  14. #include "fm_rx_api.h"
  15. #include "key.h"

  16. #define USE_P05_AS_FM_CLOCK           1
  17. #define USE_CRYSTAL_AS_FM_CLOCK       2  //共用晶振
  18. #define USE_MODULE                    3  //使用模块,FM芯片自起振32.768K晶振的情况都属于这个模式

  19. /*
  20.   此项宏定义说明是使用何种FM驱动方式
  21.   USE_P05_AS_FM_CLOCK,指使用P05作为时钟信号
  22.   USE_CRYSTAL_AS_FM_CLOCK,使用外部32K作为驱动信号
  23.   USE_MODULE,使用模块,FM芯片自起振晶振的情况都属于这个模式
  24. */
  25. #define FM_CLOCK USE_CRYSTAL_AS_FM_CLOCK


  26. //#define CS1000_MUTE      dat[0]|=0x80;     //mute
  27. #define CS1000_RD_CTRL    0x21
  28. #define CS1000_WR_CTRL   0x20

  29. bool fm_rx_stereo;
  30. u16 rda5807_chipID;
  31. u8 dat[24];   //RDA5807与CL6017共用
  32. u8 readdata[10]; //RDA5807与CL6017共用

  33. void FM_Write_3(u8 size);
  34. void FM_Write_2(u8 size);
  35. void FM_Read_2(u8 size);


  36. #pragma constseg = RDA5807_RX_TABLE
  37. #if 0
  38. /*此初始化支持 RDA5807PE  RDA5807SP 版本*/
  39. const u8 rad5807_init_tbl[104] =           //    原来的5807SP
  40. {
  41. #if(SYS_CRY == CRY_24M)
  42.     0x84, 0x51,
  43. #elif(SYS_CRY == CRY_12M)
  44.     0xc4, 0x11,
  45. #elif(SYS_CRY == CRY_32K)
  46.     0xC0, 0x01,
  47. #endif
  48.     0x00, 0x10,
  49.     0x04, 0x00,
  50.     0x86, 0xad, //05H:
  51.     0x80, 0x00,
  52.     0x5F, 0x1A, //07H
  53.     0x5e, 0xc6,
  54.     0x00, 0x00,
  55.     0x40, 0x6e, //0AH:
  56.     0x2d, 0x80,
  57.     0x58, 0x03,
  58.     0x58, 0x04,
  59.     0x58, 0x04,
  60.     0x58, 0x04,
  61.     0x00, 0x47, //10H:
  62.     0x90, 0x00,
  63.     0xF5, 0x87,
  64.     0x7F, 0x0B, //13H:
  65.     0x04, 0xF1,
  66.     0x5E, 0xc0, //15H: 0x42, 0xc0
  67.     0x41, 0xe0,
  68.     0x50, 0x6f,
  69.     0x55, 0x92,
  70.     0x00, 0x7d,
  71.     0x10, 0xC0,//1AH
  72.     0x07, 0x80,
  73.     0x41, 0x1d,//1CH,
  74.     0x40, 0x06,
  75.     0x1f, 0x9B,
  76.     0x4c, 0x2b,//1FH.
  77.     0x81, 0x10, //20H:
  78.     0x45, 0xa0,// 21H
  79.     0x19, 0x3F, //22H
  80.     0xaf, 0x40,
  81.     0x06, 0x81,
  82.     0x1b, 0x2a, //25H
  83.     0x0D, 0x04,
  84.     0x80, 0x9F, //0x80, 0x2F,
  85.     0x17, 0x8A,
  86.     0xD3, 0x49,
  87.     0x11, 0x42,
  88.     0xA0, 0xC4, //2BH
  89.     0x3E, 0xBB,
  90.     0x00, 0x00,
  91.     0x58, 0x04,
  92.     0x58, 0x04, //2FH
  93.     0x58, 0x04,
  94.     0x00, 0x74,
  95.     0x3D, 0x00,
  96.     0x03, 0x0C,
  97.     0x2F, 0x68,
  98.     0x38, 0x77, //35H
  99. };

  100. /*此初始化支持 RDA5807HS  RDA5807HP 版本*/
  101. const u8 rad5807H_init_tbl[110] =      //更新后的5807,型号5807HP
  102. {
  103. #if(SYS_CRY == CRY_24M)
  104.     0x84, 0x51,
  105. #elif(SYS_CRY == CRY_12M)
  106.     0xc4, 0x11,
  107. #elif(SYS_CRY == CRY_32K)
  108.     0xc0,0x01,
  109. #endif

  110.     0x00,0x10,
  111.     0x04,0x00,
  112.     0x88,0xB0, //05h://86    如打开20H寄存器,可在此调搜台个数,与SP版一样,0X80搜台最多
  113.     0x40,0x00,
  114.     0x7E,0xc6,                                        //以下寄存器配置不可省去
  115.     0x00,0x00,
  116.     0x00,0x00,
  117.     0x00,0x00,  //0x0ah
  118.     0x00,0x00,
  119.     0x00,0x00,
  120.     0x00,0x00,
  121.     0x00,0x00,
  122.     0x00,0x00,
  123.     0x00,0x06,  //0x10h
  124.     0x00,0x19,// //0x00,0x09,//0830
  125.     0x2a,0x11,
  126.     0x00,0x2e,
  127.     0x2a,0x30,
  128.     0xb8,0x3c,  //0x15h
  129.     0x90,0x00,
  130.     0x2a,0x91,
  131.     0x84,0x12,
  132.     0x00,0xa8,
  133.     0xc4,0x00,  //0x1ah
  134.     0xe0,0x00,
  135.     0x30,0x1d,//0x24,0x9d,1ch
  136.     0x81,0x6a,
  137.     0x46,0x08,
  138.     0x00,0x86,  //0x1fh
  139.     0x06,0x61,// 0x16,0x61, 20h  //0X16为打开第05H寄存器,可在05H调搜台数
  140.     0x00,0x00,
  141.     0x10,0x9e,
  142.     0x25,0x4A,//0x24,0Xc9台多  //   0x23,0x46 //0x25,0x4a //0x25,0xCB  //0x26,0x4c台相对少,但清楚台更多,根据客户需求选择  //23h  搜台门限值调整
  143.     0x04,0x08,//0830
  144.     0x0c,0x16,//0x06,0x08,  //0x06,0x08,//0830  //0x25h
  145.     0xe1,0x05,
  146.     0x3b,0x6c,
  147.     0x2b,0xec,
  148.     0x09,0x0f,
  149.     0x34,0x14,  //0x2ah
  150.     0x14,0x50,
  151.     0x09,0x6d,
  152.     0x2d,0x96,
  153.     0x01,0xda,
  154.     0x2a,0x7b,
  155.     0x08,0x21,   //0x30h
  156.     0x13,0xd5,
  157.     0x48,0x91,
  158.     0x00,0xbc,
  159.     0x08,0x96,//0830  0x34h
  160.     0x15,0x3c,
  161.     0x0b,0x80,
  162.     0x25,0xc7,
  163.     0x00,0x00,
  164. };
  165. #endif
  166. /*此初始化支持 RDA5807MP  RDA5807M 版本*/
  167. #if(SYS_CRY == CRY_12M)
  168. const u8 rad5807M_init_tbl[72] =    //更新后的5807,型号5807MP
  169. #else
  170. const u8 rad5807M_init_tbl[70] =    //更新后的5807,型号5807MP
  171. #endif
  172. {
  173. #if(SYS_CRY == CRY_24M)
  174.     0x84, 0x51,
  175. #elif(SYS_CRY == CRY_12M)
  176.     0xc4, 0x11,
  177. #elif(SYS_CRY == CRY_32K)
  178.     0xC0, 0x05,
  179. #endif
  180.     0x00, 0x00,
  181.     0x04, 0x00,
  182.     0xC3, 0xab, //05h
  183.     0x60, 0x00,
  184.     0x42, 0x16,
  185.     0x00, 0x00,
  186.     0x00, 0x00,
  187.     0x00, 0x00,  //0x0ah
  188.     0x00, 0x00,
  189.     0x00, 0x00,
  190.     0x00, 0x00,
  191.     0x00, 0x00,
  192.     0x00, 0x00,
  193.     0x00, 0x00,  //0x10h
  194.     0x00, 0x19,
  195.     0x2a, 0x11,
  196.     0xB0, 0x42,
  197.     0x2A, 0x11,
  198.     0xb8, 0x31,  //0x15h
  199.     0xc0, 0x00,
  200.     0x2a, 0x91,
  201.     0x94, 0x00,
  202.     0x00, 0xa8,
  203.     0xc4, 0x00,  //0x1ah
  204.     0xF7, 0xcF,
  205.     0x2A, 0xDC,  //0x1ch
  206.     0x80, 0x6F,
  207.     0x46, 0x08,
  208.     0x00, 0x86,
  209.     0x06, 0x61, //0x20H
  210.     0x00, 0x00,
  211.     0x10, 0x9E,
  212.     0x23, 0xC8,
  213.     0x04, 0x06,
  214. #if(SYS_CRY == CRY_12M)
  215.      0x0E, 0x1C, //0x25H
  216. #endif
  217. };

  218. #pragma constseg=default

  219. /*----------------------------------------------------------------------------*/
  220. /**@brief FM模块RDA5807P初始化
  221.    @param 无
  222.    @return 无
  223.    @note
  224. */
  225. /*----------------------------------------------------------------------------*/
  226. void rda5807p_init(void)@"RDA5807_RX"
  227. {
  228.     u8 i;
  229. #if 0
  230.     if (0x5804 == rda5807_chipID)
  231.     {
  232.         for(i=0;i<=11;i++)
  233.             dat[i] = rad5807_init_tbl[i];
  234.         //power on

  235. #if((SYS_CRY == CRY_24M) || (SYS_CRY == CRY_12M))
  236.     #if(FM_CLOCK != USE_CRYSTAL_AS_FM_CLOCK) //模块或独立晶振,P05使用的时钟还是32.768K
  237.     {
  238.         dat[0] = 0xC0;
  239.         dat[1] = 0x01;
  240.     }
  241.     #endif
  242. #endif

  243.         FM_Write_2(2);
  244.         Delay5Ms(120);
  245.         //init
  246.         FM_Write_3(104);
  247.         Delay5Ms(1);
  248.     }
  249.     else if(0x5801 == rda5807_chipID)
  250.     {
  251.         for(i=0;i<=11;i++)
  252.           dat[i] = rad5807H_init_tbl[i];
  253.         //power on

  254. #if((SYS_CRY == CRY_24M) || (SYS_CRY == CRY_12M))
  255.     #if(FM_CLOCK != USE_CRYSTAL_AS_FM_CLOCK)
  256.     {
  257.         dat[0] = 0xC0;
  258.         dat[1] = 0x01;
  259.     }
  260.     #endif
  261. #endif

  262.         FM_Write_2(2);
  263.         Delay5Ms(120);
  264.         //init
  265.         FM_Write_3(110);
  266.         Delay5Ms(1);
  267.     }
  268.     else if (0x5808 == rda5807_chipID)
  269.     {
  270.         for(i=0;i<=11;i++)
  271.           dat[i] = rad5807M_init_tbl[i];
  272.         //power on

  273. #if((SYS_CRY == CRY_24M) || (SYS_CRY == CRY_12M))
  274.     #if(FM_CLOCK != USE_CRYSTAL_AS_FM_CLOCK)
  275.     {
  276.         dat[0] = 0xC0;
  277.         dat[1] = 0x05;
  278.     }
  279.     #endif
  280. #endif

  281.         FM_Write_2(2);
  282.         Delay5Ms(120);
  283.         //init
  284. #if(SYS_CRY == CRY_12M)
  285.         FM_Write_3(72);
  286. #else
  287.         FM_Write_3(70);
  288. #endif

  289.         Delay5Ms(1);
  290.     }
  291. #endif
  292.        
  293.         for(i=0;i<=11;i++)
  294.           dat[i] = rad5807M_init_tbl[i];
  295.         //power on

  296. #if((SYS_CRY == CRY_24M) || (SYS_CRY == CRY_12M))
  297.     #if(FM_CLOCK != USE_CRYSTAL_AS_FM_CLOCK)
  298.     {
  299.         dat[0] = 0xC0;
  300.         dat[1] = 0x05;
  301.     }
  302.     #endif
  303. #endif

  304.         FM_Write_2(2);
  305.         Delay5Ms(120);
  306.         //init
  307. #if(SYS_CRY == CRY_12M)
  308.         FM_Write_3(72);
  309. #else
  310.         FM_Write_3(70);
  311. #endif
  312.         Delay5Ms(1);

  313. }

  314. void CS1000_Powerdown(void)@"RDA5807_RX"
  315. {
  316.     dat[1] &= ~(1<<0);
  317.     FM_Write_2(2);
  318.     Delay5Ms(100);
  319. }

  320. void CS1000_FMSeek_TuneMethod(u16 TunerFrequency,u8 diect)@"RDA5807_RX"
  321. {
  322.     u16 ch;

  323.     ch = 0;


  324.     ch = (TunerFrequency - 8700)/10;
  325.    // dat[0] |=0x40;
  326.     dat[2] = ch>>2;
  327.     dat[3] = ((ch&0x0003)<<6)|0x10;

  328.     FM_Write_2(4);
  329.     Delay5Ms(10);
  330. }


  331. void FM_Read_2(u8 size)
  332. {
  333.     u16 i;

  334.     I2C_Start();
  335.     I2C_sendbyte(0x21);
  336.     ReceiveACK();

  337.     for (i=0;i<size-1;i++)
  338.     {
  339.         readdata[i] = I2C_readbyte();
  340.         I2C_ack();
  341.     }

  342.     readdata[i] = I2C_readbyte();
  343.     I2C_nack();

  344.     I2C_Stop();
  345. }

  346. void FM_Write_2(u8 size)
  347. {
  348.     u8 i;

  349.     I2C_Start();

  350.     I2C_sendbyte(0x20);
  351.     ReceiveACK();

  352.     for (i=0;i<size;i++)
  353.     {
  354.         I2C_sendbyte(dat[i]);
  355.         ReceiveACK();
  356.     }

  357.     I2C_Stop();
  358. }


  359. void FM_Write_3(u8 size)
  360. {
  361.     u8 i;

  362.     I2C_Start();

  363.     I2C_sendbyte(0x20);
  364.     ReceiveACK();

  365.     for (i=0;i<size;i++)
  366.     {
  367. #if 0
  368.         if(0x5804 == rda5807_chipID)
  369.         {
  370.             I2C_sendbyte(rad5807_init_tbl[i]);
  371.         }
  372.         else if(0x5801 == rda5807_chipID)
  373.         {
  374.             I2C_sendbyte(rad5807H_init_tbl[i]);
  375.         }
  376.         else if(0x5808 == rda5807_chipID)
  377.         {
  378.             I2C_sendbyte(rad5807M_init_tbl[i]);
  379.         }
  380. #endif
  381.         I2C_sendbyte(rad5807M_init_tbl[i]);
  382.         ReceiveACK();
  383.     }
  384.     I2C_Stop();
  385. }
  386. /*----------------------------------------------------------------------------*/
  387. /**@brief FM模块RDA5807P设置频率
  388.    @param freq 要设置的频率
  389.    @return 无
  390.    @note 频率范围为875~1080
  391. */
  392. /*----------------------------------------------------------------------------*/
  393. void rda5807p_set_freq(u16 freq)@"RDA5807_RX"
  394. {
  395.     u8 try_cnt = 2;

  396.     while (try_cnt--)
  397.     {
  398.         CS1000_FMSeek_TuneMethod(freq*10,0);
  399.     }
  400. }

  401. /*----------------------------------------------------------------------------*/
  402. /**@brief FM模块RDA5807P关闭
  403.    @param 无
  404.    @return 无
  405.    @note
  406. */
  407. /*----------------------------------------------------------------------------*/
  408. void rda5807p_off(void)@"RDA5807_RX"
  409. {
  410.     CS1000_Powerdown();
  411. }

  412. /*----------------------------------------------------------------------------*/
  413. /**@brief FM模块RDA5807P设置音量
  414.    @param vol 音量值
  415.    @return 无
  416.    @note 音量范围0~15
  417. */
  418. /*----------------------------------------------------------------------------*/
  419. void rda5807p_set_vol(u8 vol)@"RDA5807_RX"
  420. {
  421.     if(vol > 15)
  422.         vol = 15;

  423.     dat[7] &=~0x0F;
  424.     dat[7] |= vol;

  425.     dat[3] &= ~BIT(4);  //03H.4=0,disable tune
  426.     if(vol == 0)
  427.     {
  428.         dat[0] &= ~(1<<6);//MUTE ENABLE
  429.     }
  430.     else
  431.     {
  432.         dat[0] |= (1<<6)|(1<<7);
  433.         dat[1] |= (1<<0);
  434.     }
  435.     FM_Write_2(8);
  436. }

  437. /*----------------------------------------------------------------------------*/
  438. /**@brief FM模块RDA5807P自动搜台
  439.    @param freq 要搜索的频率
  440.    @return 指定的频率下有台返回1,否则返回0
  441.    @note
  442. */
  443. /*----------------------------------------------------------------------------*/
  444. u8 rda5807p_seek(u16 freq)@"RDA5807_RX"
  445. {
  446.    rda5807p_set_freq(freq);

  447.     Delay5Ms(10);

  448.     do
  449.     {
  450.         FM_Read_2(4);
  451.         Delay5Ms(4);
  452.        // fm_rx_rdy = (readdata[3]>>7) & 0x01;
  453.     }
  454.     while (!((readdata[3]>>7) & 0x01));


  455. //    if (flag)
  456. //    {
  457. //        rda5807p_set_freq(cur_freq);
  458. //        return cur_freq;
  459. //    }
  460.    // fm_rx_true = readdata[2] & 0x01;
  461.     if (readdata[2] & 0x01)//FM_TRUE
  462.         return true;
  463.     else
  464.         return false;
  465. }

  466. void rda5807p_mute(void)@"RDA5807_RX"
  467. {
  468.     dat[0] &= ~(1<<6);//MUTE ENABLE

  469.     FM_Write_2(2);
  470.     Delay5Ms(10);
  471. }

  472. void rda5807p_unmute(void)@"RDA5807_RX"
  473. {
  474.     dat[0] |= (1<<6)|(1<<7);
  475.     dat[1] |= (1<<0);

  476.     FM_Write_2(2);
  477.     Delay5Ms(10);
  478. }
  479. /*----------------------------------------------------------------------------*/
  480. /**@brief FM模块RDA5807P检测
  481.    @param 无
  482.    @return 检测到RDA5807P模块返回1,否则返回0
  483.    @note
  484. */
  485. /*----------------------------------------------------------------------------*/
  486. u8 rda5807p_online(void)@"RDA5807_RX"
  487. {
  488.    dat[0] = 0x00;
  489.     dat[1] = 0x02;
  490.     FM_Write_2(2);
  491.     //read ID
  492.     FM_Read_2(10);
  493.     rda5807_chipID = (readdata[8] << 8) | readdata[9];

  494.     if((rda5807_chipID == 0x5801) || (rda5807_chipID == 0x5804) || (rda5807_chipID == 0x5808))
  495.       return 1;
  496.     else
  497.       return 0;
  498. }
复制代码
哈哈
  1. #ifndef _RDA5807P_H_
  2. #define _RDA5807P_H_

  3. #include <include.h>

  4. void CS1000_Write(u8 size);
  5. void CS1000_Read(u8 size);


  6. extern void rda5807p_init(void);
  7. extern void rda5807p_set_freq(u16 freq);
  8. extern void rda5807p_off(void);
  9. extern void rda5807p_set_vol(u8 vol);
  10. extern u8 rda5807p_seek(u16 freq);
  11. extern void rda5807p_mute(void);
  12. extern void rda5807p_unmute(void);
  13. extern u8 rda5807p_online(void);
  14. #endif
复制代码
大家来讨论一下寄存器,为啥子那么多呢?????

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2017-6-21 17:01:51 | 显示全部楼层
几年了。。。楼主,这驱动程序好用吗?准备做一个RAD5807收音机,参考一下。

出0入0汤圆

发表于 2017-6-22 01:25:45 | 显示全部楼层
RDA5807不用读什么寄存器,太麻烦了,
直接写前4个寄存器就可以听广播了。
第一个字节发送$20,后面就是8个字节的数据,高字节在前,低字节在后。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 08:20

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表