找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9818|回复: 11
打印 上一主题 下一主题
收起左侧

STC89C52RC + TEA5767 + TDA2822 FM收音机

  [复制链接]
跳转到指定楼层
楼主
ID:111350 发表于 2016-10-23 11:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 linymda 于 2016-10-23 15:52 编辑

一直对单片机有兴趣,本身具备一点电子方面的知识,C语音也还能做简单的修改。
这次闲来无事,网上淘来TEA5767完整版芯片,决定做个FM收音机。

资料都是网上搜大神们的作品而来,一并感谢。

芯片使用:
STC89C52RC 单片机
TEA5767 完整版
TDA2822 放大芯片
其他元件:
电阻
电容
晶振
按键
等等

没有用显示。

外接及电池(4节干电池)两套电源,方便移动。

主要功能:
1、开机预设当地强信号台
2、手动切换预设的12个台,本地强台
3、手动搜索

实现的功能:
耳机收听能清晰收到本地12个FM台(济南)

后续:
解决声音小的问题,有可能的话改成喇叭收听。

实物图:


原理图:(借用的图,有稍微的修改,比如增加指示灯等)


TEA5767.zip (39.97 KB, 下载次数: 178)
频率转换十六进制.zip (4.14 KB, 下载次数: 109)

  1. #include <reg51.h>
  2. #include <string.h>
  3. #include <math.h>
  4. #define uchar unsigned char
  5. #define uint unsigned int

  6. #define max_freq 108000 //手动搜索最高频率
  7. #define min_freq 87500  //手动搜索最低频率
  8.    
  9. uint tt=0; //手动选预设台标记

  10. sbit SDA=P0^0;   //接在TEA5767的数据端口        
  11. sbit SCL=P0^1;   //接在TEA5767的时钟端口      
  12. sbit KEY1=P3^5;  //频率增加按键端口      
  13. sbit KEY2=P3^4;  //频率减小按键端口
  14. sbit KEY3=P3^3;  //预设电台增加
  15. sbit KEY4=P3^2;  //预设电台减少

  16. unsigned char radio_write_data[5]={0x2a,0x30,0xC0,0x17,0x00};        //要写入TEA5767的数据,88.7M,开机预设
  17.                                   //前两位是频率,后三位不需要修改
  18. unsigned int pll;
  19. unsigned long frequency=87500;

  20. void delay1ms (unsigned int b)//1ms延时
  21. {
  22. for(b;b>0;b--)
  23. {unsigned int i;
  24.   for(i=0;i<300;i++)
  25.    {;}
  26. }
  27. }

  28. void Delayus(unsigned char x)
  29. {
  30. for(;x>0;x--);
  31. }

  32. void iic_start()
  33. {
  34. SDA=1;
  35. Delayus(5);
  36. SCL=1;
  37. Delayus(5);
  38. SDA=0;
  39. Delayus(5);
  40. SCL=0;
  41. Delayus(5);
  42. }

  43. void iic_stop()
  44. {
  45. SCL=0;
  46. Delayus(5);
  47. SDA=0;
  48. Delayus(5);
  49. SCL=1;
  50. Delayus(5);
  51. SDA=1;
  52. Delayus(5);
  53. }

  54. void iic_ack()
  55. {
  56. SDA=0;
  57. Delayus(5);
  58. SCL=1;
  59. Delayus(5);
  60. SCL=0;
  61. Delayus(5);
  62. SDA=1;
  63. Delayus(5);
  64. }


  65. bit iic_testack()
  66. {
  67. bit ErrorBit;
  68. SDA=1;
  69. Delayus(5);
  70. SCL=1;
  71. Delayus(5);
  72. ErrorBit=SDA;
  73. Delayus(5);
  74. SCL=0;
  75. return ErrorBit;
  76. }

  77. void iic_write8bit(unsigned char input)
  78. {
  79. unsigned char temp;
  80. for(temp=8;temp>0;temp--)
  81. {
  82.   SDA=(bit)(input&0x80);
  83.   Delayus(5);
  84.   SCL=1;
  85.   Delayus(5);
  86.   SCL=0;
  87.   Delayus(5);
  88.   input=input<<1;
  89. }
  90. }



  91. //由频率计算PLL
  92. void get_pll(void)
  93. {
  94.     unsigned char hlsi;
  95.    
  96.     hlsi=radio_write_data[2]&0x10;  //HLSI位
  97.     if (hlsi)
  98.         pll=(unsigned int)((float)((frequency+225)*4)/(float)32.768);    //频率单位:k
  99.     else
  100.         pll=(unsigned int)((float)((frequency-225)*4)/(float)32.768);    //频率单位:k
  101. }


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

  115. void radio_write(void)
  116. {
  117.     unsigned char i;
  118.     iic_start();
  119.     iic_write8bit(0xc0);        //TEA5767写地址
  120.     if(!iic_testack())
  121.     {
  122.         for(i=0;i<5;i++)
  123.         {
  124.             iic_write8bit(radio_write_data[i]);
  125.             iic_ack();
  126.         }
  127.     }
  128.     iic_stop();  
  129. }


  130. //将显示的频率算好后写到TEA5767芯片里面实现调节,不用考虑TEA5767用于搜台的相关位:SM,SUD
  131. void search(bit mode)
  132. {
  133.     //radio_read();        
  134.     if(mode)
  135.     {
  136.         frequency+=10;
  137.         if(frequency>max_freq)
  138.             frequency=min_freq;
  139.     }
  140.     else
  141.     {
  142.         frequency-=10;
  143.         if(frequency<min_freq)
  144.             frequency=max_freq;
  145.     }         
  146.     get_pll();
  147.     radio_write_data[0]=pll/256;
  148.     radio_write_data[1]=pll%256;
  149.     radio_write_data[2]=0xC0;
  150.     radio_write_data[3]=0x17;
  151.     radio_write_data[4]=0x00;
  152.     radio_write();
  153. }



  154. void main()
  155. {
  156. delay1ms(150);
  157. radio_write();
  158. while(1)
  159. {
  160.           if(KEY1==0)
  161.           {
  162.            delay1ms(15); //延时15ms
  163.            if(KEY1==0)
  164.      while(KEY1==0);//等待按键释放
  165.            search(1);
  166.           }

  167.     if(KEY2==0)
  168.     {
  169.      delay1ms(15); //延时15ms
  170.      if(KEY2==0)
  171.      while(KEY2==0);//等待按键释放
  172.      search(0);
  173.     }

  174.     if(KEY3==0)
  175.     {
  176.      delay1ms(15); //延时15ms
  177.      if(KEY3==0)
  178.      while(KEY3==0);//等待按键释放
  179.           if (tt==11)//手动选台判断,保证能循环选择,不严禁能工作,请忽略
  180.              tt=-1;
  181.           tt++;
  182.           switch(tt) //手动选台
  183.      {
  184.        case 0:
  185.                   {
  186.                   radio_write_data[0]=0x2A;//写入的频率
  187.         radio_write_data[1]=0x30;
  188.                   break;
  189.                   }
  190.        case 1:
  191.                   {
  192.                   radio_write_data[0]=0x2B;
  193.         radio_write_data[1]=0x3C;
  194.                   break;
  195.                   }
  196.        case 2:
  197.                   {
  198.                   radio_write_data[0]=0x2B;
  199.         radio_write_data[1]=0xB6;
  200.                   break;
  201.                   }
  202.        case 3:
  203.                   {
  204.                   radio_write_data[0]=0x2C;
  205.         radio_write_data[1]=0x86;
  206.                   break;
  207.                   }      
  208.                   case 4:
  209.                   {
  210.                   radio_write_data[0]=0x2D;
  211.         radio_write_data[1]=0x6E;
  212.                   break;
  213.                   }      
  214.                   case 5:
  215.                   {
  216.                   radio_write_data[0]=0x2E;
  217.         radio_write_data[1]=0xB7;
  218.                   break;
  219.                   }      
  220.                   case 6:
  221.                   {
  222.                   radio_write_data[0]=0x30;
  223.         radio_write_data[1]=0xD0;
  224.                   break;
  225.                   }      
  226.                   case 7:
  227.                   {
  228.                   radio_write_data[0]=0x31;
  229.         radio_write_data[1]=0x0D;
  230.                   break;
  231.                   }      
  232.                   case 8:
  233.                   {
  234.                   radio_write_data[0]=0x31;
  235.         radio_write_data[1]=0xA0;
  236.                   break;
  237.                   }      
  238.                   case 9:
  239.                   {
  240.                   radio_write_data[0]=0x32;
  241.         radio_write_data[1]=0xB9;
  242.                   break;
  243.                   }      
  244.                   case 10:
  245.                   {
  246.                   radio_write_data[0]=0x33;
  247.         radio_write_data[1]=0x02;
  248.                   break;
  249.                   }
  250.                   case 11:
  251.                   {
  252.                   radio_write_data[0]=0x33;
  253.         radio_write_data[1]=0x4B;
  254.                   break;
  255.                   }
  256.       }
  257.           radio_write_data[2]=0xC0;//写入的其他参数
  258.      radio_write_data[3]=0x17;
  259.      radio_write_data[4]=0x00;
  260.      radio_write();
  261.           if (tt==11)
  262.              tt=0;
  263.     }

  264.     if(KEY4==0)
  265.     {
  266.      delay1ms(15); //延时15ms
  267.      if(KEY4==0)
  268.      while(KEY4==0);//等待按键释放
  269.           if (tt==0)//手动选台判断,保证能循环选择,不严禁能工作,请忽略
  270.              tt=12;
  271.           tt--;
  272.           switch(tt) //手动选台
  273.      {
  274.        case 0:
  275.                   {
  276.                   radio_write_data[0]=0x2A;
  277.         radio_write_data[1]=0x30;
  278.                   break;
  279.                   }
  280.        case 1:
  281.                   {
  282.                   radio_write_data[0]=0x2B;
  283.         radio_write_data[1]=0x3C;
  284.                   break;
  285.                   }
  286.        case 2:
  287.                   {
  288.                   radio_write_data[0]=0x2B;
  289.         radio_write_data[1]=0xB6;
  290.                   break;
  291.                   }
  292.        case 3:
  293.                   {
  294.                   radio_write_data[0]=0x2C;
  295.         radio_write_data[1]=0x86;
  296.                   break;
  297.                   }      
  298.                   case 4:
  299.                   {
  300.                   radio_write_data[0]=0x2D;
  301.         radio_write_data[1]=0x6E;
  302.                   break;
  303.                   }      
  304.                   case 5:
  305.                   {
  306.                   radio_write_data[0]=0x2E;
  307.         radio_write_data[1]=0xB7;
  308.                   break;
  309.                   }      
  310.                   case 6:
  311.                   {
  312.                   radio_write_data[0]=0x30;
  313.         radio_write_data[1]=0xD0;
  314.                   break;
  315.                   }      
  316.                   case 7:
  317.                   {
  318.                   radio_write_data[0]=0x31;
  319.         radio_write_data[1]=0x0D;
  320.                   break;
  321.                   }      
  322.                   case 8:
  323.                   {
  324.                   radio_write_data[0]=0x31;
  325.         radio_write_data[1]=0xA0;
  326.                   break;
  327.                   }      
  328.                   case 9:
  329.                   {
  330.                   radio_write_data[0]=0x32;
  331.         radio_write_data[1]=0xB9;
  332.                   break;
  333.                   }      
  334.                   case 10:
  335.                   {
  336.                   radio_write_data[0]=0x33;
  337.         radio_write_data[1]=0x02;
  338.                   break;
  339.                   }
  340.                   case 11:
  341.                   {
  342.                   radio_write_data[0]=0x33;
  343.         radio_write_data[1]=0x4B;
  344.                   break;
  345.                   }
  346.       }
  347.           radio_write_data[2]=0xC0;
  348.      radio_write_data[3]=0x17;
  349.      radio_write_data[4]=0x00;
  350.      radio_write();
  351.           if (tt==0)
  352.              tt=11;
  353.     }
  354. }
  355. }
复制代码



评分

参与人数 2黑币 +105 收起 理由
ssfc + 5 赞一个!
admin + 100 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏9 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:96682 发表于 2016-10-23 13:23 | 只看该作者
LZ,2822音量咋会小呢?不是有双声道电位器嘛,板上的电位器既不方便调节而且还会造成音量的不同步
回复

使用道具 举报

板凳
ID:111350 发表于 2016-10-23 15:47 | 只看该作者
wc86110 发表于 2016-10-23 13:23
LZ,2822音量咋会小呢?不是有双声道电位器嘛,板上的电位器既不方便调节而且还会造成音量的不同步

带耳机还可以,带喇叭没试,不知道行不行。
回复

使用道具 举报

地板
ID:145935 发表于 2016-11-7 15:12 | 只看该作者
用按键调音量就完美了。
回复

使用道具 举报

5#
ID:151105 发表于 2016-11-29 21:16 | 只看该作者
不明觉厉
回复

使用道具 举报

6#
ID:155262 发表于 2016-12-20 00:44 | 只看该作者
好厉害
回复

使用道具 举报

7#
ID:155262 发表于 2016-12-24 18:39 | 只看该作者
大哥啊,我怎么觉得你原理图和代码的接口不一样啊
回复

使用道具 举报

8#
ID:111350 发表于 2016-12-30 20:51 | 只看该作者
舞炀l 发表于 2016-12-24 18:39
大哥啊,我怎么觉得你原理图和代码的接口不一样啊

图是借的,对应的自己修改就行。
回复

使用道具 举报

9#
ID:249545 发表于 2017-11-26 16:09 | 只看该作者
家里的收音机不少,可是不堪用.广告太多了.
乡下也需要很高的灵敏度才行.
回复

使用道具 举报

10#
ID:276348 发表于 2018-1-21 22:27 | 只看该作者
用了2822就做成立体声的了。
回复

使用道具 举报

11#
ID:103981 发表于 2020-6-24 17:27 | 只看该作者
感谢分享,努力学习
回复

使用道具 举报

12#
ID:1063423 发表于 2024-4-26 08:03 来自手机 | 只看该作者
普通电位器能控制单片机调音量?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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