分享

51单片机+TEA5767+数码管的FM收音机制作 电路图+程序

 共同成长888 2019-12-30
 现在网上很多网友都在做和TEA5767有关的东东,今天找到个MP4的尸体,屏碎了,打开一看刚好有能用的TEA5767,验证了一下这个东西的实用性,用手上刚好有的51单片机开发板和lm386,为这个集成模块搭建了一个测试平台,下面是试验图片,如果在西安的朋友,肯定知道我手的那个电台了,哈哈!
图片一:


这个图可以看到整体结构了,其实硬件电路很简单,看看pdf文档完全可以搭建出来,单片机实验板是以前开发的商品。
图片二:


这一部分是主要部分了,中间上面那个就是拆下来的TEA5767,它右边是LM386,做功率放大的,下面的扬声器是从一个笔记本里边拆下来的(太败家了,衰!)。
        下面的程序可以直接运行了,绝对没问题的,这个也是参考了几个网站的程序,做了些修改,可以手动自动调台了,手动调台有问题,算法好像不对,但是出来的频率问题不大,自动搜索的结果是正确的,我要提醒大家一点,自动搜台的效果和接受强度,也就是天线,有很大的关系,我的天线是一截不到15mm的软导线,good  luck!
  1. /***************************************************************************************************
  2. TEA5767采用I2C接口控制,单片机用AT89S52.晶振11.0592Mhz。采用四位LED显示。
  3. TEA5767采用I2C接口控制.TEA5767读写数据都是5个字节,其中PLL参数14位. Fosc =11.0592Mhz.
  4. ****************************************************************************************************/
  5. #include "regx52.h"
  6. #include "intrins.h"
  7. /***********************************************************************************/
  8. #define max_freq 108000     //108Mhz
  9. #define min_freq 87500        //87.5Mhz
  10. #define max_pll 0x339b       //108MHz时的pll.
  11. #define min_pll 0x299d        //87.5MHz时的pll.
  12. #define Add_Freq    1
  13. #define Dec_Freq    0
  14. #define REFERENCE_FREQ    32.768
  15. #define ATIIcxxDriverAddressW 0xC0
  16. #define ATIIcxxDriverAddressR 0xC1
  17. #define _Nop() _nop_(),_nop_(),_nop_(),_nop_(),_nop_()    /*定义空指令*/
  18. #define     LED     P0
  19. void Initialization(void);
  20. void Get_Pll(void);
  21. void Get_Frequency(void);
  22. void Search(unsigned char mode);
  23. void Auto_Search(unsigned char mode);
  24. unsigned char GetKey();
  25. void Delay(unsigned char Time);
  26. void Led_Display(unsigned long i);
  27. void DelayD(unsigned char Time);
  28. unsigned char GetKey();
  29. void Delay(unsigned char Time);
  30. void ATIICxx_PWrite(unsigned char *McuAddress,unsigned char count);
  31. void ATIICxx_PRead(unsigned char *McuAddress,unsigned char count);
  32. void I2C_Send_Byte(unsigned char sendbyte);
  33. unsigned char I2C_Receive_Byte(void);
  34. void I2C_Start(void);
  35. void I2C_Stop(void);
  36. void I2C_Ack(void);
  37. void I2C_Noack(void);

  38. /*********************************************************************/
  39. /* IIC读写程序芯片型号*/
  40. sbit I2C_SCK=P3^0; /*实时时钟时钟线引脚 */
  41. sbit I2C_SDA=P3^1; /*实时时钟数据线引脚 */
  42. sbit k1=P1^7;
  43. sbit k2=P1^6;
  44. sbit k3=P1^5;
  45. sbit k4=P1^4;
  46. /*********************************************************************/
  47. /************************************************************************/
  48. sbit ge=P2^3;
  49. sbit shi=P2^2;
  50. sbit bai=P2^1;
  51. sbit qan=P2^0;
  52. unsigned char tab[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳
  53.                          //0,    1,   2   3    4    5    6    7    8    9
  54. /************************************************************************/
  55. unsigned char radio_write_data[5]={0x2d,0x56,0x20,0x11,0x00}; //初始化写入TEA5767的数据(FM89.8Mhz)
  56. unsigned char radio_read_data[5];                    
  57. unsigned int Pll_Data;
  58. unsigned long Frequency_Data;
  59. /***********************************************************************************/
  60. void Initialization(void)
  61. {
  62.     TMOD = 0x11;
  63.     TH0 = 0x5d;
  64.     TL0 = 0x3d;
  65.     TR0 = 0;    //25ms
  66.     TH1 = 0x5d;
  67.     TL1 = 0x3d;
  68.     TR1 = 0;    //25ms
  69.     T2CON = 0x30;
  70.     T2MOD = 0x00;
  71.     RCAP2H = 0xFE;
  72.     TH2 = RCAP2H;
  73.     RCAP2L = 0xFB;
  74.     TL2 = RCAP2L;
  75.     TR2 = 0;    //2400bps
  76.     PCON = 0x00;
  77.     SCON = 0xD0;
  78.     IP = 0x14;
  79.     EX0 = 1;
  80.     IT0 = 1;
  81.     ET0 = 1;
  82.     EX1 = 1;
  83.     IT1 = 1;
  84.     ES = 0;
  85.     EA = 0;
  86. }

  87. /***********************************************************************************/
  88. //读TEA5767状态,并转换成频率
  89. void Radio_Read(void)
  90. {
  91.     unsigned char temp_l,temp_h;
  92.     Pll_Data = 0;

  93.     ATIICxx_PRead(&radio_read_data[0],5);
  94.    
  95.     temp_l = radio_read_data[1];
  96.     temp_h = radio_read_data[0];
  97.     temp_h &= 0x3f;
  98.     Pll_Data = temp_h*256+temp_l;
  99.     Get_Frequency();
  100. }

  101. /***********************************************************************************/
  102. //由PLL计算频率
  103. void Get_Frequency(void)
  104. {
  105.     unsigned char hlsi;
  106.     unsigned int npll = 0;
  107.    
  108.     npll = Pll_Data;
  109.     hlsi = radio_read_data[2]&0x10;
  110.     if (hlsi)
  111.         Frequency_Data = (unsigned long)((float)(npll)*(float)REFERENCE_FREQ*(float)0.25-225);    //频率单位:KHz
  112.     else
  113.         Frequency_Data = (unsigned long)((float)(npll)*(float)REFERENCE_FREQ*(float)0.25+225);    //频率单位:KHz
  114. }

  115. /***********************************************************************************/
  116. //由频率计算PLL
  117. void Get_Pll(void)
  118. {
  119.     unsigned char hlsi;

  120.     hlsi = radio_read_data[2]&0x10;
  121.     if (hlsi)
  122.         Pll_Data = (unsigned int)((float)((Frequency_Data+225)*4)/(float)REFERENCE_FREQ);    //频率单位:k
  123.     else
  124.         Pll_Data = (unsigned int)((float)((Frequency_Data-225)*4)/(float)REFERENCE_FREQ);    //频率单位:k
  125. }

  126. /***********************************************************************************/
  127. //手动设置频率,mode=1,+0.1MHz; mode="0:-0".1MHz ,不用考虑TEA5767用于搜台的相关位:SM,SUD
  128. void Search(unsigned char mode)
  129. {
  130.     Radio_Read();
  131.            
  132.     if(mode)
  133.     {
  134.         Frequency_Data += 100;
  135.         if(Frequency_Data > max_freq)
  136.             Frequency_Data = min_freq;
  137.     }
  138.     else
  139.     {
  140.         Frequency_Data -= 100;
  141.         if(Frequency_Data < min_freq)
  142.             Frequency_Data = max_freq;
  143.     }
  144.             
  145.     Get_Pll();
  146.     radio_write_data[0] = Pll_Data/256;
  147.     radio_write_data[1] = Pll_Data%256;
  148.     radio_write_data[2] = 0x41;
  149.     radio_write_data[3] = 0x11;
  150.     radio_write_data[4] = 0x40;
  151.     ATIICxx_PWrite(&radio_write_data[0],5);
  152. }

  153. /***********************************************************************************/
  154. //自动搜台,mode=1,频率增加搜台; mode="0:频率减小搜台".
  155. void Auto_Search(unsigned char mode)
  156. {
  157.     Radio_Read();
  158.     Get_Pll();
  159.     if(mode)
  160.     {
  161.         radio_write_data[2] = 0xb1;
  162.         if(Pll_Data > max_pll)
  163.         {
  164.             Pll_Data = min_pll;
  165.         }
  166.     }
  167.     else
  168.     {
  169.         radio_write_data[2] = 0x41;
  170.         if(Pll_Data < min_pll)
  171.         {
  172.             Pll_Data = max_pll;
  173.         }
  174.     }
  175.          
  176.     radio_write_data[0] = Pll_Data/256+0x40;
  177.     radio_write_data[1] = Pll_Data%256;   
  178.     radio_write_data[3] = 0x11;
  179.     radio_write_data[4] = 0x40;
  180.     ATIICxx_PWrite(&radio_write_data[0],5);
  181.     Radio_Read();
  182.     while(!(radio_read_data[0]&0x80))     //RF电台就绪标志
  183.     {
  184.         Radio_Read();
  185.     }   
  186. }

  187. /***********************************************************************************/
  188. void main(void)
  189. {
  190. //0x2d,0x56,0x20,0x11,0x00
  191.     unsigned long temp;
  192.     Initialization();
  193.     radio_write_data[0] =0x2A;
  194.     radio_write_data[1] =0xB6;
  195.     radio_write_data[2] =0x41;
  196.     radio_write_data[3] =0x11;
  197.     radio_write_data[4] =0x40;
  198.     ATIICxx_PWrite(&radio_write_data[0],5);//初始化TEA5767(89.8Mhz)
  199.     Frequency_Data = 89800;

  200.     while(1)
  201.     { temp= Frequency_Data;
  202.     Led_Display(Frequency_Data);

  203. if( k1 == 0)
  204.    { DelayD(2);
  205.       while(k1 == 0);//等待键松开
  206.       Search(Add_Freq);
  207.    }
  208. if( k2 == 0)
  209.    { DelayD(2);
  210.       while(k2 == 0);//等待键松开
  211.     Search(Dec_Freq);
  212.    }
  213. if( k3 == 0)
  214.    { DelayD(2);
  215.       while(k3 == 0);//等待键松开
  216.     Auto_Search(Add_Freq);
  217.    }
  218. if( k4 == 0)
  219.    { DelayD(2);
  220.       while(k4 == 0);//等待键松开
  221.     Auto_Search(Dec_Freq);
  222.    }

  223.     }
  224. }

  225. /*********************************************************************/
  226. struct bytedata_2
  227. {
  228. unsigned char ByteH;
  229. unsigned char ByteL;
  230. };

  231. union int2byte
  232. {
  233. unsigned int IntData;
  234. struct bytedata_2 ByteData;
  235. };
  236. /*********************************************************************/
  237. //启动I2C总线,退出时SCL为低
  238. void I2C_Start(void)
  239. {
  240. I2C_SDA=1;    /*发送起始条件的数据信号*/
  241. _Nop();
  242. I2C_SCK=1;
  243. _Nop();_Nop();_Nop();_Nop();_Nop();/*起始条件建立时间大于4.7us,延时*/
  244. I2C_SDA=0;    /*发送起始信号*/
  245. _Nop();_Nop();_Nop();_Nop();_Nop();     /* 起始条件锁定时间大于4μs*/
  246. I2C_SCK=0;    /*钳住I2C总线,准备发送或接收数据 */
  247. _Nop();_Nop();_Nop();_Nop();_Nop();/*起始条件建立时间大于4.7us,延时*/
  248. }
  249. //*停止I2C总线
  250. void I2C_Stop(void)
  251. {
  252. I2C_SCK=0;
  253. I2C_SDA=0;   /*发送结束条件的数据信号*/
  254. _Nop();           /*发送结束条件的时钟信号*/
  255. I2C_SCK=1;   /*结束条件建立时间大于4μs*/
  256. _Nop();_Nop();_Nop();_Nop();_Nop();
  257. I2C_SDA=1;   /*发送I2C总线结束信号*/
  258. }
  259. //MCU等待应答位(返回0表示应答)
  260. bit I2C_WaitAck(void)
  261. {
  262. unsigned char ucErrTime = 200;    //因故障接收方无ACK,超时值。

  263. I2C_SCK=0;
  264. I2C_SDA=1;
  265. _Nop();
  266. I2C_SCK=1;
  267. while(I2C_SDA)
  268. {
  269.        ucErrTime--;
  270.        if (ucErrTime == 0)
  271.        {
  272.           I2C_Stop();
  273.           return 0;
  274.         }
  275. }

  276. I2C_SCK=0;
  277. return 1;
  278. }
  279. //MCU应答信号
  280. void I2C_Ack(void)
  281. {
  282. I2C_SCK=0;
  283. I2C_SDA=0;
  284. _Nop();
  285. _Nop();
  286. _Nop();
  287. _Nop();
  288. _Nop();
  289. I2C_SCK=1;
  290. _Nop();
  291. _Nop();
  292. _Nop();
  293. _Nop();
  294. _Nop();
  295. I2C_SCK=0;
  296. }
  297. //MCU发送非应答信号
  298. void I2C_Noack(void)
  299. {
  300. I2C_SCK=0;
  301. I2C_SDA=1;
  302. _Nop();
  303. _Nop();
  304. I2C_SCK=1;
  305. _Nop();
  306. _Nop();
  307. I2C_SCK=0;
  308. }
  309. void I2C_Send_Byte(unsigned char sendbyte)
  310. {
  311. unsigned char i = 8;

  312. while( i-- )
  313. {
  314.    I2C_SCK = 0;
  315.    _Nop(); //_Nop();
  316.    if ( sendbyte &0x80 ) I2C_SDA =1;
  317.    else I2C_SDA =0;
  318.    _Nop(); //_Nop();
  319.    I2C_SCK = 1;
  320.    _Nop(); //_Nop();
  321.    sendbyte <<= 1;
  322. }

  323. I2C_WaitAck();
  324. }

  325. static unsigned char I2C_Receive_Byte(void)
  326. {
  327. unsigned char i = 8, data_buffer;

  328. I2C_SDA = 1;
  329. while ( i--)
  330. {
  331.    I2C_SCK =0;
  332.    _Nop();_Nop();
  333.    I2C_SCK =1;
  334.    _Nop();_Nop();
  335.    data_buffer <<= 1;

  336.    if ( I2C_SDA ) data_buffer++;
  337. }
  338. return (data_buffer);
  339. }

  340. void ATIICxx_PWrite(unsigned char *McuAddress,unsigned char count)
  341. {
  342. I2C_Start();
  343. I2C_Send_Byte( ATIIcxxDriverAddressW );
  344. while(count--)
  345. {
  346.    I2C_Send_Byte( *(unsigned char*)McuAddress );
  347.    ((unsigned char*)McuAddress)++;
  348. }
  349. I2C_Stop();
  350. }

  351. void ATIICxx_PRead(unsigned char *McuAddress,unsigned char count)
  352. {
  353. I2C_Start();
  354. I2C_Send_Byte( ATIIcxxDriverAddressR );
  355. while(count--)
  356. {
  357.    *McuAddress = I2C_Receive_Byte();
  358.    I2C_Ack();
  359.    McuAddress++;
  360. }

  361. I2C_Noack();
  362. I2C_Stop();
  363. }

  364. void DelayD(unsigned char Time)
  365. {
  366.         unsigned char i;
  367.       
  368.         while( --Time != 0)
  369.         {
  370.                 for(i = 0; i < 125; i++); //i 从0加到125,CPU大概就耗时1 毫秒 。
  371.         }
  372. }

  373. /************************************************************************/
  374. void Led_Display(unsigned long i)             //显示函数
  375. {
  376. LED = tab[i/100000];
  377. qan = 0;
  378. bai = 1;
  379. shi = 1;
  380. ge = 1;
  381. DelayD(3);
  382. LED = tab[(i%100000)/10000];
  383. qan = 1;
  384. bai = 0;
  385. shi = 1;
  386. ge = 1;
  387. DelayD(3);
  388. LED = tab[((i%100000)%10000)/1000]&0x7f;
  389. qan = 1;
  390. bai = 1;
  391. shi = 0;
  392. ge = 1;
  393. DelayD(3);
  394. LED = tab[(((i%100000)%10000)%1000)/100];
  395. qan = 1;
  396. bai = 1;
  397. shi = 1;
  398. ge = 0;
  399. DelayD(3);
  400. }
复制代码

希望大家可以继续改进,让这个东东的功能达到完善。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多