收藏 分销(赏)

RDA5820和51单片机制作的FM数字收音机源代码及电路原理图.doc

上传人:xrp****65 文档编号:7446572 上传时间:2025-01-05 格式:DOC 页数:13 大小:50KB 下载积分:10 金币
下载 相关 举报
RDA5820和51单片机制作的FM数字收音机源代码及电路原理图.doc_第1页
第1页 / 共13页
RDA5820和51单片机制作的FM数字收音机源代码及电路原理图.doc_第2页
第2页 / 共13页


点击查看更多>>
资源描述
*  晶振:8M */ #include <reg52.h> #include <string.h> #define ChannelCount      50          //最多支持多少个台,因为常驻内存,多了RAM放不下 #define uchar   unsigned char #define uint   unsigned int typedef struct {  uchar Freq;  uchar Rssi; }ChannelInfo; sbit SDA  = P2^0; sbit SCL  = P2^1; sbit key1 = P3^4; sbit key2 = P2^7; sbit key3 = P2^6; sbit key4 = P2^5; // P3^7; sbit LcdEn = P3^4; sbit LcdRs = P3^5; uchar Channel  = 0; uchar FreqTune = 0; const uint MinFreq   = 870;   //起始频率 * 100KHz const uint MaxFreq   = 1080;  //最高频率 * 100KHz const uchar FmAddr   = 0×22;  //FM模块IIC 地址 const uchar EpAddr   = 0xA0;  //24C02 EPPRom 的地址 uchar RSSI     = 0;           //信号强度 uchar ChannelTune[ChannelCount]; uchar code LevlChar[5][8] = {{0x1F,0×11,0x0A,0×04,0×04,0×04,0×04,0×04}, {0×00,0×00,0×00,0×00,0×00,0×00,0×06,0x1E}, {0×00,0×00,0×00,0×00,0×06,0x1E,0x1E,0x1E},     //显示型号强度的自定义字符 {0×00,0×00,0×06,0x1E,0x1E,0x1E,0x1E,0x1E}, {0×06,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E}};  uchar vol   = 0×8;  //音量0~0xF uchar Func    = 0×0;   //当前功能号 bit AutoScan  = 0;     //标记当前是不是在自动搜台 bit Mute   = 0;  //标记是否被静音 uchar KeyNumber = 0; void OpenIIC(); void CloseIIC(); void IICWrite(uchar uaddr, uchar romaddr, uint rdata,bit _i6b); void IICWriteByte( uchar byte ); uint IICRead(uchar uaddr, uchar romaddr,bit _i6b); uchar IICReadByte(bit next); void FM_SetFreq(); void FM_SetVolume(); uint FM_ReadReg(uchar regAddr);     //读取FM模块的寄存器 void FM_WriteReg(uchar regAddr,uint dat); //写FM模块的寄存器 uchar FM_GetRSSI();               //获取当前的信号强大 void Delay(uint c); bit KeyScan(); void BeginScan(); void Lcd_DispNumber(uint number); void Lcd_Init(); void Lcd_Comm(uchar cmd); void Lcd_Data(uchar dat); void Lcd_String(char* dat); void Lcd_DispRssi(); void Lcd_DispFreq(); void Lcd_Refresh(); void Lcd_DispDiscript(); void Eprom_LoadInitData(); uint Eprom_Read(uchar addr,bit _16bit); void Eprom_Write(uchar addr,uint dat,bit _16bit); void main() {     P3 = 0xff;  P2 = 0xff;    Delay(10000);               //延时,等待外部FM模块的启动  Eprom_LoadInitData();         //从EppRom 加载频道音量等信息  FM_WriteReg(2,0xd281);  //启动FM模块  FM_SetVolume();         //设置启动音量  FM_SetFreq();      //设置默认频道的频率  Lcd_Init();  Lcd_Refresh();   while(1)  {    if( KeyScan())   {    Lcd_Refresh();    }  } } void Eprom_LoadInitData() {  uint result = 0;    int i=0;  result =Eprom_Read(0,0);  if(result>0){ vol = (uchar)result – 1;}  result =Eprom_Read(1,0);  Channel = (uchar)result;  for(i=0;i<ChannelCount;i++)  {   result =Eprom_Read(i * 2 + 2,1);   ChannelTune[i] = result;  }  FreqTune = ChannelTune[Channel]; } void Eprom_Write(uchar addr,uint dat,bit _16bit) {  IICWrite(EpAddr,addr,dat,_16bit); } uint Eprom_Read(uchar addr,bit _16bit) {  return IICRead(EpAddr,addr,_16bit); } uint FM_ReadReg(uchar regAddr) {  return IICRead(FmAddr,regAddr,1); } void FM_WriteReg(uchar regAddr,uint dat) {   IICWrite(FmAddr,regAddr,dat,1); } void FM_SetFreq() {  FM_WriteReg(3,(FreqTune<<6) | 0×10); } void FM_SetVolume() {  uint reg2H;  if(vol>0)  {    if(Mute)   {    reg2H = FM_ReadReg(2);    reg2H |= 0×4000;    FM_WriteReg(2,reg2H);    }   Mute = 0;   FM_WriteReg(5,vol);  }  else  {   Mute = 1;   reg2H = FM_ReadReg(2);   reg2H &= 0xBFFF;   FM_WriteReg(2,reg2H);  }  Eprom_Write(0,vol+1,0); } void Lcd_Init() {  uchar CGRamAddr = 0×40;  int i,j;  LcdEn = 0;  Lcd_Comm(0×38);  Lcd_Comm(0x0c);  Lcd_Comm(0×06);  Lcd_Comm(0×01);       for(j=0;j<5;j++){   Lcd_Comm(CGRamAddr + 8 * j); //建立自定义字符 (显示信号强度的)      for(i=0;i<8;i++)    {    Lcd_Data(LevlChar[j][i]);    Delay(510);   }  } } void Lcd_Comm(uchar cmd) {  LcdRs =0;  P0 = cmd;  Delay(50);  LcdEn = 1;  Delay(50);  LcdEn = 0; } void Lcd_Data(uchar dat) {  LcdRs = 1;  P0 = dat;  Delay(50);  LcdEn = 1;  Delay(50);  LcdEn = 0;  } void Lcd_String(char* dat) {  char *p;  int j, i=strlen(dat);  for(j=0;j<i;j++)  {   p=dat + j;   Lcd_Data(*p);   } } void Lcd_DispRssi() {  int i;  Lcd_Comm(0×80);  for(i=0;i<5;i++)  {   Lcd_Data(‘ ‘);   }  RSSI = FM_GetRSSI();  Lcd_Comm(0×80);  Lcd_Data(0×00);          if(RSSI>=1) Lcd_Data(0×01);  if(RSSI>=2) Lcd_Data(0×02);  if(RSSI>=3) Lcd_Data(0×03);  if(RSSI>=4) Lcd_Data(0×04);  } void Lcd_DispFreq() {  uint curFreq = MinFreq + FreqTune;  int i;  Lcd_Comm(0×85);  for(i=5;i<16;i++)  {   Lcd_Data(‘ ‘);   }  Lcd_Comm(0×80+6);  if(curFreq>=1000)Lcd_Data(48 +curFreq /1000 % 10);  Lcd_Data(48 +curFreq /100 % 10);  Lcd_Data(48 +curFreq /10 % 10);  Lcd_Data(‘.’);  Lcd_Data(48 + curFreq % 10);  Lcd_Data(‘M’);          Lcd_Data(‘H’);  Lcd_Data(‘Z’); } void Lcd_DispDiscript() {  int i;  Lcd_Comm(0×80+0×40);  for(i=0;i<15;i++)  {   Lcd_Data(‘ ‘);   }   Lcd_Comm(0×80+0×40);   switch(Func)   {    case 0:    Lcd_String(“Channel:”);    Lcd_DispNumber(Channel+1);    break;   case 1:    Lcd_String(“Volume:”);    Lcd_DispNumber(vol);    break;   case 2:    Lcd_String(“Tune”);    break;   case 3:    Lcd_String(“Auto Scan”);   }  } void Lcd_Refresh() {  Lcd_DispRssi();  Lcd_DispFreq();   Lcd_DispDiscript(); } void Lcd_DispNumber(uint number) {  int i=0,len;  char str[6]={‘\0′,’\0′,’\0′,’\0′,’\0′,’\0′};  char temp;  do  {   str[i++] = ’0′ + (number % 10);   number /= 10;  }while(number) ;  len = strlen(str);  for(i=0;i<len/2;i++)  {   temp = str[i];   str[i] = str[len-i-1];   str[len-i-1] = temp;  }  Lcd_String(str); } bit KeyScan() {  bit keyRel = 0;   //按键释放检测  char value=0;  int i;  uint temp;  if(AutoScan) return 0;  if(KeyNumber==0)  {     if(key3==0)     {       Delay(50);    if(key3==0)    {     KeyNumber =3;    }     }       if(key4==0)     {       Delay(50);    if(key4==0)    {      KeyNumber=4;    }     }       if(key2==0)     {      Delay(50);    if(key2==0)    {     KeyNumber=2;    }     }   return 0;  }  else  {     switch(KeyNumber)     {       case 1:    if(key1==1)keyRel = 1; break;    case 2:    if(key2==1)keyRel = 1; break;    case 3:    if(key3==1)keyRel = 1; break;    case 4:    if(key4==1)keyRel = 1; break;     }     if(keyRel)     {          switch(KeyNumber)       {      case 2:       Func++;       if(Func>3) Func = 0;       break;      case 3:       value = -1;       break;      case 4:       value = 1;       break;       }       if(KeyNumber>2)       {         if(Func==0)      {       if((value > 0 && Channel<ChannelCount) || (value<0 && Channel > 0))       {         Channel+=value;        FreqTune= ChannelTune[Channel];        FM_SetFreq();        Eprom_Write(1,Channel, 0);       }      }      else if(Func==1)      {       if((value > 0 && vol<0xF) || (value<0 && vol > 0))       {             vol+=value;        FM_SetVolume();       }      }      else if(Func==2)      {       if((value > 0 && FreqTune<0xd2) || (value<0 && FreqTune > 0))       {         FreqTune+=value;        ChannelTune[Channel] = FreqTune;        FM_SetFreq();        Eprom_Write(Channel * 2 + 2 ,FreqTune,1);       }      }      else if(Func==3) //开始自动扫描      {       AutoScan = 1;       BeginScan();       AutoScan = 0;       Channel = 0;       FreqTune = ChannelTune[0];        Func = 0;       FM_SetFreq();       //覆盖EppRom中的所有的频道       for(i=0;i<ChannelCount;i++)       {        temp = ChannelTune[i];        Eprom_Write(i * 2+2,temp,1);       }       Eprom_Write(0×01,0,0); //重置EPPROM中的频道号为0      }     }       KeyNumber=0;      }      return keyRel;    } } //全自动搜索 void BeginScan() {   uint state;  int i=0,count=0;  bit cmp = 0;  uint seekth = 0×8;  //灵敏度 0~127,默认为8  灵敏度越低越可能搜索到假台,高了可能一些信号弱一点的频道被跳过。  uint reg5H;  uint tempTune = 0;  for(i=0;i<ChannelCount;i++)   //清除原有的电台数据  {                  ChannelTune[i]=0;  }  reg5H = FM_ReadReg(0×05);  reg5H = (reg5H & 0x80FF) | (seekth<<7);  FM_WriteReg(0×05,reg5H);  for(i=0;i<=MaxFreq – MinFreq;i++)  {    FreqTune = i;   FM_SetFreq();   Lcd_DispFreq();   do   {    state = FM_ReadReg(0x0B);    cmp = (state>>  7  ) & 0×1;   }while(!cmp);   Delay(100);   state = FM_ReadReg(0x0B);   cmp = (state >>   8  ) & 0×1;   if(cmp)   {    ChannelTune[count]=i;     count++;   }   if(count>=ChannelCount){ break; }  } } uchar FM_GetRSSI() {  uint regVal =FM_ReadReg(0x0b);   regVal = regVal>>9;    return (uchar)(regVal/16); } void Delay(uint c) {  int i=0;  for(i=0;i<c;i++); } uint IICRead(uchar uaddr, uchar ramAddr,bit _16b) {  uint buf;  OpenIIC();  IICWriteByte(uaddr);  IICWriteByte(ramAddr);  OpenIIC();  IICWriteByte(uaddr | 0×01);       if(_16b)  {   buf = IICReadByte(1);   buf = buf<<8;   buf =buf | IICReadByte(0);  }  else  {   buf = IICReadByte(0);  }  CloseIIC();  return buf; } uchar IICReadByte(bit next) {  uchar buf =0,i=0;  for(i=0;i<8;i++)  {    buf <<=1;   SCL = 1;   buf |= SDA;   Delay(5);   SCL = 0;   Delay(5);   }  if(next)  {   SDA = 0;   SCL = 1;   Delay(5);   SCL = 0;   Delay(5);   SDA = 1;  }  else  {   SDA = 1;   SCL = 1;   Delay(5);   SCL = 0;   Delay(5);    SDA=0;  }  return buf; } void IICWrite(uchar uaddr, uchar romaddr, uint rdata,bit _16b) {    uchar temp;  OpenIIC();  IICWriteByte(uaddr);  IICWriteByte(romaddr);           if(_16b)  {   temp =(uchar)((rdata>>8) & 0x00ff) ;   IICWriteByte(temp);  }  temp = (uchar) (rdata & 0xff);  IICWriteByte(temp);   CloseIIC(); } void IICWriteByte( uchar byte ) {  uchar i=0;   int f=30000;        bit bitdata;  for(i=0;i<8;i++)  {     bitdata =byte>>(7-i) & 1;     SDA = bitdata;     SCL =1;     Delay(5);     SCL = 0;     Delay(5);  }  SCL = 1;  while(SDA && –f);  Delay(5);  SCL = 0;  Delay(5); } void CloseIIC() {  SDA = 0 ;  SCL = 1;  Delay(5);  SDA = 1;  Delay(5);  SCL = 1;  SDA = 1;  Delay(150); //防止过快的读取造成EPPROM 来不及反应 } void OpenIIC() {  SDA = 1;  SCL = 1;  Delay(5);  SDA = 0;  Delay(5);  SCL = 0;  Delay(5); } /****************************************************************************************************************/
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 应用文书 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服