久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6372|回復: 7
打印 上一主題 下一主題
收起左側

STM32與TEA5767收音機OLED顯示、自動/手動搜臺,DS1302顯示時間 源程序

  [復制鏈接]
跳轉到指定樓層
樓主
接上TEA5767模塊后可以接受FM電臺87500——108000KHZ, 音量調節只能靜音或者打開,因為模塊本身不具有調節選項;可以手動設置頻率(軟件步進精度10KHZ,模塊的角度不清楚)也可以自動搜臺,但只能應對強臺的搜索。OLED我用的是1.3寸的,0.96寸也是兼容的,但貌似1.3寸版本多了兩列像素,所以可能邊緣的顯示0.96會出點小問題。收音模塊我是用的帶功放的,但最好買單獨的模塊來做,因為這個音量不可用程序調節!
主要模塊和功能如下:
1、OLED屏:操作界面顯示(選中時反顯)
2、三個10K電阻下拉的按鍵:左邊功能選擇減,中間兼“確認”和“減”功能,右邊“加”功能
3、DS1302:提供實時時鐘:可修改時間
4、TEA5767完整帶功放模塊:收音的核心,靜音音量示數為0其余都表示聲音“開”,配有音頻口用于接入天線(實測插一個耳機效果最好)
5、STM32F103C6T6單片機:C8T6也可以用,完全兼容;不過程序也就18K左右用C8浪費了,SRAM也完全夠了

模塊的接線為:1、OLED: SCL->PA5  SDA->PA7  3.3V電源
2、按鍵:10K電阻下拉,接PA2、3、4,分別對應按鍵1,2,3
3、TEA5767模塊:SCL->PB7   SDA->PB5
4、DS1302模塊:  RST->PB10   DAT->PB1   CLK->PB0

制作出來的實物圖如下:

收音機整體模塊


菜單界面


手動搜臺,步進或設置


收音機主界面


存臺取臺


三個按鍵進行操作

實測多次代碼各項功能都沒有問題可以運行,另外程序中有一些功能選項沒有寫實現代碼,例如“恢復設置”,它們不影響最終功能的實現可以自由寫入需要恢復的變量;還有鬧鐘功能,只需要按照其他界面的設計邏輯寫一些“if else”語句就可以實現,由于沒有蜂鳴器就沒寫了。不過這些都不影響主要的功能的實現,畢竟它只是一個收音機...

部分STM32單片機代碼如下:
#include "delay.h"
#include "sys.h"
#include "stdio.h"
#include "interrupt.h"
#include "stdlib.h"
#include "oled.h"
#include "tea5657.h"
#include "ds1302.h"

#define StartPosition  0x08005000 //存取臺在flash中的起始位置,程序大概有18KB,不能與程序沖突


u32 Frequence; //頻率全局變量,單位為10KHZ
u16 count=0,result,SystemTime,Channel[41]; //存取40個臺,可更改
u8  KeyState[3],Menu1, Menu2, ItemSwitch,Menu2_1;
unsigned char countNumber = 0, SetNumber[5], Time[8], TimeBuff[8], Laud, ChannelSet=1,Signal, Brightness = 3; //初始亮度為3(1—5)
unsigned char radio_write_data[5]={0x29,0xc2,0x40,0x12,0x40};      
unsigned char radio_read_data[5];        //TEA5767讀出的狀態


void DrawFirst1(void); //分別為各個界面的驅動函數
void DrawFirst2(void);
void DrawFirst3(void);
void DrawFirst4(void);
void DrawFirst5(void);
void DrawFirst6(void);
void DrawFirst7(void);
void SetPicture1_1(void);
void SetPicture2_1(void);
void SetPicture2_2(void);
void SetPicture2_5(void);        
void SetPicture2_3(void);
void SetPicture2_6(void);        
void ClockTime(void); //定時讀取DS1302
void InputA_Init(uint16_t a); //輸入配置函數
uint16_t FLASH_ReadHalfWord(uint32_t address); //到address讀一個16位數據
void FLASH_WriteMoreData(uint32_t startAddress,uint16_t *writeData,uint16_t countToWrite); //address寫入任意長度的16位數據
void Updata_Channel(void);   //更新電臺存儲,將數組中的電臺寫入FLASH中
void Updata_W_Channel(void); //將Flash中的電臺頻率讀到數組中





int main(void)
{
                        delay_init(); //延時函數初始化
                        OLED_Init();  //1.3寸或0.96寸OLED均可以驅動
                        TIM3_INIT_Config(10);                          //定時10ms中斷
                        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設置中斷優先級分組為組2:2位搶占優先級,2位響應優先級
                //        OLED_ColorTurn(0);                             //0正常顯示,1 反色顯示
                //        OLED_DisplayTurn(0);                           //0正常顯示 1 屏幕翻轉顯示
                        Tea_Init(1);                                 //收音機模塊初始化
                        DrawFirst1();                                //主界面
                        OLED_Refresh();                              //更新顯示
            DS1302_init();                               //DS1302初始化
            InputA_Init(GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4); //按鍵輸入設置
                //        Search(Frequence*10);                        //搜索
        while(1)
        {
                if(KeyState[0]==255){
                         KeyState[0] = 0;
                         Menu1++;
                        if(Menu1>2) Menu1=0; // 三種狀態中切換:菜單 音量 無
                }
                  DrawFirst1();   //畫出基本界面
                          switch (Menu1){                  //設定區域反顯操作
                                case 1: OLED_ShowChinese(0,2,3,16,0),
                            OLED_ShowChinese(16,2,4,16,0);   break; //菜單
                                case 2: OLED_ShowChinese(75,2,5,16,0),
                            OLED_ShowChinese(91,2,6,16,0);   break; //音量
                                default:break;
                }
       if(Menu1 == 1){ //菜單鍵 為了保持程序可讀性和整潔性,重復判斷了兩次Menu1的狀態,可以將上面的顯示更新代碼移到if的大括號中
                         if(KeyState[1]==255)
       SetPicture1_1();                 //進入菜單界面                 
       }
                         else if(Menu1 == 2){ //調節音量,由于模塊本身不具有音量調節功能,故需要自行開發推薦用PWM來完成,音量大小用全局變量Laud表示,每次調音量都重新寫入
                           if(KeyState[1]==255)      {Laud++,KeyState[1]=0,Search(Frequence*10);}
                                 else if(KeyState[2]==255) {Laud--,KeyState[2]=0,Search(Frequence*10);} //9:01001 16: 10000 15:01111
         if(Laud>19) Laud = 0; //19級可調
       }
                        OLED_Refresh(); //更新顯示
                }
}



void InputA_Init(uint16_t a){ //按鍵初始化
GPIO_InitTypeDef  GPIO_InitStructure;     
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);      
GPIO_InitStructure.GPIO_Pin = a;                     
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //當按鍵沒有按下時,IO口檢測為高電平,為上拉電阻模式,按下IO口與地連接,為低電平   
GPIO_Init(GPIOA ,&GPIO_InitStructure);  
}



void Updata_R_Channel(void)
{
        u8 i;
        for(i=0; i<40; i++)
        {
                Channel[ i] = FLASH_ReadHalfWord(StartPosition + 2*i);
        }
        
}




void Updata_W_Channel(void)
{
        FLASH_WriteMoreData(StartPosition,Channel,40);
}






uint16_t FLASH_ReadHalfWord(uint32_t address)
{
   return *(__IO uint16_t*)address;
}







void FLASH_WriteMoreData(uint32_t startAddress,uint16_t *writeData,uint16_t countToWrite)
  {   
      uint32_t offsetAddress=startAddress - 0X08000000;               //計算去掉0X08000000后的實際偏移地址
      uint32_t sectorPosition=offsetAddress/2048;            //計算扇區地址,對于STM32F103VET6為0~255
      uint32_t sectorStartAddress=sectorPosition*2048+FLASH_BASE;    //對應扇區的首地址
      uint16_t dataIndex;


   FLASH_Unlock();         //解鎖寫保護

   FLASH_ErasePage(sectorStartAddress);//擦除這個扇區

   for(dataIndex=0;dataIndex<countToWrite;dataIndex++)
   {
     FLASH_ProgramHalfWord(startAddress+dataIndex*2,writeData[dataIndex]);
   }

   FLASH_Lock();//上鎖寫保護
}










void DrawFirst1(void)
{
          OLED_ShowNum(47,28,Time[4],1,16,1);//時間數字
    OLED_ShowNum(55,28,Time[5],1,16,1);
          OLED_ShowString(63,28,":",16,1);
          OLED_ShowNum(71,28,Time[0],1,16,1);
          OLED_ShowNum(79,28,Time[1],1,16,1);
          OLED_ShowNum(90,35,Time[2],1,8,1);
          OLED_ShowNum(96,35,Time[3],1,8,1);
               
          OLED_ShowNum(47,48,Frequence/100,3,16,1);//頻率
          OLED_ShowNum(80,48,Frequence%100,2,16,1);
          OLED_ShowString(72,48,".",16,1);
          OLED_ShowString(100,48,"MHZ",16,1);
        
          OLED_ShowChinese(0,2,3,16,1); //菜單
                OLED_ShowChinese(16,2,4,16,1);
        
          OLED_ShowChinese(75,2,5,16,1); //音量
                OLED_ShowChinese(91,2,6,16,1);
          OLED_ShowNum(110,2,Laud,2,16,1);
        
                OLED_ShowChinese(0,28,7,16,1); //時間
                OLED_ShowChinese(16,28,8,16,1);
                OLED_ShowString(32,28,":",16,1);
        
                OLED_ShowChinese(0,48,13,16,1); //頻率
                OLED_ShowChinese(16,48,19,16,1);
                OLED_ShowString(32,48,":",16,1);
               
                OLED_DrawLine(0,21,130,21,1);
}



void DrawFirst2(void)
{
            
                  OLED_ShowChinese(0,0-ItemSwitch,14,16,1); //自動搜臺
                                                OLED_ShowChinese(16,0-ItemSwitch,15,16,1);
                                          OLED_ShowChinese(32,0-ItemSwitch,16,16,1);
                                          OLED_ShowChinese(48,0-ItemSwitch,17,16,1);
                                         
                                          OLED_ShowChinese(0,16-ItemSwitch,18,16,1); //手動搜臺
                                                OLED_ShowChinese(16,16-ItemSwitch,15,16,1);
                                          OLED_ShowChinese(32,16-ItemSwitch,16,16,1);
                                          OLED_ShowChinese(48,16-ItemSwitch,17,16,1);
                                         
                                                OLED_ShowChinese(0,32-ItemSwitch,29,16,1), //存取電臺
                                          OLED_ShowChinese(16,32-ItemSwitch,33,16,1),
                                                OLED_ShowChinese(32,32-ItemSwitch,28,16,1),
                                          OLED_ShowChinese(48,32-ItemSwitch,17,16,1);
                                                                        
                                                OLED_ShowChinese(0,48-ItemSwitch,22,16,1), //設置鬧鐘
                                                OLED_ShowChinese(16,48-ItemSwitch,23,16,1),
                                                OLED_ShowChinese(32,48-ItemSwitch,9,16,1),
                                                OLED_ShowChinese(48,48-ItemSwitch,10,16,1);
        
            OLED_ShowChinese(0,64-ItemSwitch,22,16,1), //設置時間
                                                OLED_ShowChinese(16,64-ItemSwitch,23,16,1),
                                                OLED_ShowChinese(32,64-ItemSwitch,7,16,1),
                                                OLED_ShowChinese(48,64-ItemSwitch,8,16,1);
                                                
                                                OLED_ShowChinese(0,80-ItemSwitch,37,16,1); //設置亮度
                                                OLED_ShowChinese(16,80-ItemSwitch,38,16,1);
                                          OLED_ShowChinese(32,80-ItemSwitch,39,16,1);
                                          OLED_ShowChinese(48,80-ItemSwitch,40,16,1);
                                                                        
                                                OLED_ShowChinese(0,96-ItemSwitch,31,16,1),//恢復設置
                                                OLED_ShowChinese(16,96-ItemSwitch,32,16,1),
                                                OLED_ShowChinese(32,96-ItemSwitch,22,16,1),
                                                OLED_ShowChinese(48,96-ItemSwitch,23,16,1);
                                                                        
                                                OLED_ShowChinese(94,48,20,16,1),//返回
                                                OLED_ShowChinese(110,48,21,16,1);
}



void DrawFirst3(void)
{
                  OLED_ShowChinese(32,0,22,16,1); //設置頻率
                                                OLED_ShowChinese(48,0,23,16,1);
                                          OLED_ShowChinese(64,0,13,16,1);
                                          OLED_ShowChinese(80,0,19,16,1);

                  OLED_ShowChinese(94,48,20,16,1);//返回
                                          OLED_ShowChinese(110,48,21,16,1);
        
                  OLED_ShowChinese(0,48,24,16,1); //確認
                                                OLED_ShowChinese(16,48,25,16,1);
        
                  OLED_ShowChinese(48,48,26,16,1); //步進
                                          OLED_ShowChinese(64,48,27,16,1);

        
            OLED_ShowString(48,24,".",8,1); //頻率數據
                  OLED_ShowString(78,24,"MHZ",8,1);
                        OLED_ShowNum(20,24,SetNumber[0],1,8,1);
                                                OLED_ShowNum(30,24,SetNumber[1],1,8,1);
                                                OLED_ShowNum(40,24,SetNumber[2],1,8,1);
                                                OLED_ShowNum(56,24,SetNumber[3],1,8,1);
                  OLED_ShowNum(66,24,SetNumber[4],1,8,1);
                                                
                                                OLED_ShowNum(110,24,Signal,2,8,1); //信號強度
}



void DrawFirst4(void)
{
                  OLED_ShowChinese(32,0,22,16,1); //設置時間
                                                OLED_ShowChinese(48,0,23,16,1);
                                          OLED_ShowChinese(64,0,7,16,1);
                                          OLED_ShowChinese(80,0,8,16,1);

                  OLED_ShowChinese(94,48,20,16,1);//返回
                                          OLED_ShowChinese(110,48,21,16,1);
        
                  OLED_ShowChinese(0,48,24,16,1); //確認
                                                OLED_ShowChinese(16,48,25,16,1);

                        OLED_ShowNum(50,26,TimeBuff[0],2,8,1); //時間
                  OLED_ShowString(63,26,":",8,1);
                                                OLED_ShowNum(68,26,TimeBuff[1],2,8,1);
}        



void DrawFirst5(void)
{
          OLED_ShowString(20,0,"Channel:",16,1); //頻道顯示
    OLED_ShowNum(84,0,ChannelSet,2,16,1);        
        
          OLED_ShowNum(22,25,Channel[ChannelSet]/100,3,16,1);//頻率數據
          OLED_ShowNum(55,25,Channel[ChannelSet]%100,2,16,1);
          OLED_ShowString(47,25,".",16,1);
          OLED_ShowString(75,25,"MHZ",16,1);
        
          OLED_ShowChinese(0,48,33,16,1);  //取臺
                OLED_ShowChinese(16,48,17,16,1);
                OLED_ShowChinese(48,48,29,16,1); //存臺
                OLED_ShowChinese(64,48,17,16,1);
          OLED_ShowChinese(94,48,20,16,1); //返回
                OLED_ShowChinese(110,48,21,16,1);
        
}

......限于篇幅余下代碼下載附件......

代碼工程51hei下載地址:
TEA5767收音機.7z (630.89 KB, 下載次數: 194)

評分

參與人數 1黑幣 +100 收起 理由
admin + 100 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏17 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:170270 發表于 2021-8-13 14:37 | 只看該作者
能收到幾個臺?為啥我做的總是只有3到4個清晰地臺。。。。
回復

使用道具 舉報

板凳
ID:338727 發表于 2021-8-14 13:34 來自手機 | 只看該作者
依然是你 發表于 2021-8-13 14:37
能收到幾個臺?為啥我做的總是只有3到4個清晰地臺。。。。

我做的只能收到強臺,弱臺不清晰
回復

使用道具 舉報

地板
ID:525016 發表于 2022-12-3 15:27 | 只看該作者
請問樓主,能分享一下原理圖嗎?謝謝
回復

使用道具 舉報

5#
ID:651494 發表于 2022-12-10 16:27 | 只看該作者
的沈嬌妮 發表于 2021-8-14 13:34
我做的只能收到強臺,弱臺不清晰

OLED會干擾FM接收靈敏度,解決的方法:1,軟件OLED寫入只在數據更新時寫入一次,不要頻繁循環寫入;2,OLED數據時鐘線使用三極管隔離反向,濾波電容處理,可以增加阻抗,從而降低IIC輻射干擾;3,硬件收音模塊,OLED電源等濾波,OLED有條件可以加裝接地屏蔽罩
回復

使用道具 舉報

6#
ID:1062732 發表于 2023-2-14 23:04 | 只看該作者
請問樓主只能收到電流聲,收不到電臺里的聲音是怎么回事
回復

使用道具 舉報

7#
ID:72088 發表于 2023-2-27 18:11 | 只看該作者
數碼管靜態顯示屏才能避免干擾收聽廣播,多年經驗總結,
回復

使用道具 舉報

8#
ID:996773 發表于 2023-3-1 13:18 | 只看該作者


我是剛學匯編兩年沒多久,拋磚引玉,匯編程序短小精悍,4k容量51單片機足夠跑了,

同時驅動液晶和LED,想用哪個就哪個,直接驅動松下大廠的原裝收音板,松下的品質

我就不用說了。有頻道模式和頻率雙模式,內部eeprom存儲30個頻道的頻率,立體聲和

單聲道可選
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国外成人免费视频 | 日韩在线视频一区二区三区 | 日韩影音 | 国产免费一区二区三区 | 91欧美精品成人综合在线观看 | 国产激情片在线观看 | 日韩av一区二区在线观看 | 999久久久| 国产一级特黄视频 | 一区二区中文字幕 | 伊人手机在线视频 | 欧美1区2区 | 日日夜夜草 | 国产精品一区二区在线播放 | 国偷自产av一区二区三区 | 欧美一区二区在线观看 | 午夜视频在线 | 国产亚洲精品成人av久久ww | 男人av网 | 亚洲一区二区在线 | 日韩在线免费视频 | 久久免费国产 | 日韩中文字幕 | www.亚洲| 欧美美女一区二区 | 91资源在线 | 中文字幕亚洲精品在线观看 | 国产精品成人一区二区三区夜夜夜 | 一区二区三区欧美在线 | 亚欧精品 | 国产ts人妖另类 | 九九在线精品视频 | 精品国产乱码久久久久久老虎 | 91久久国产综合久久91精品网站 | 日韩国产精品一区二区三区 | 国产精品国产三级国产aⅴ原创 | 断背山在线观看 | 日韩三级免费观看 | 一区二区三区四区在线视频 | 日韩免费视频 | 天天艹逼网|