接上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
制作出來的實物圖如下:
51hei圖片_20210812235612.jpg (1.2 MB, 下載次數: 81)
下載附件
收音機整體模塊
2021-8-13 00:00 上傳
收音機整體模塊
51hei圖片_20210812235638.jpg (1005.44 KB, 下載次數: 88)
下載附件
菜單界面
2021-8-13 00:02 上傳
菜單界面
51hei圖片_20210812235656.jpg (1008.75 KB, 下載次數: 69)
下載附件
手動搜臺,步進或設置
2021-8-13 00:04 上傳
手動搜臺,步進或設置
51hei圖片_20210813000537.jpg (915.75 KB, 下載次數: 68)
下載附件
收音機主界面
2021-8-13 00:06 上傳
收音機主界面
51hei圖片_20210812235643.jpg (991.2 KB, 下載次數: 66)
下載附件
存臺取臺
2021-8-13 00:07 上傳
存臺取臺
51hei圖片_20210812235709.jpg (1.11 MB, 下載次數: 64)
下載附件
三個按鍵進行操作
2021-8-13 00:25 上傳
三個按鍵進行操作
實測多次代碼各項功能都沒有問題可以運行,另外程序中有一些功能選項沒有寫實現代碼,例如“恢復設置”,它們不影響最終功能的實現可以自由寫入需要恢復的變量;還有鬧鐘功能,只需要按照其他界面的設計邏輯寫一些“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.png (3.32 KB, 下載次數: 70)
下載附件
2021-8-13 01:30 上傳
代碼工程51hei下載地址:
TEA5767收音機.7z
(630.89 KB, 下載次數: 194)
2021-8-13 00:49 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|