通過RDA5807製作一個收音機
參加2020年智慧車競賽的聲音信標組 奮戰了一個月 可惜並沒有獲得獎項,正巧該車的收發Chirp波的模組為RDA5807,閒暇之餘,參考了RDA5807的資料手冊,製作了一個通過STM32作為主控的RDA5807 收音機
rda5807.c
#include<stdio.h>
#include<sys.h>
#include<delay.h>
#include<RDA5807.h>
#include<lcd.h>
u16 RXFreq=0;
u8 Vol=0;
u8 RDA_State=0;
//初始化I2C
void rda5807_i2c_init(void)
{
IIC_Init();
}
void RDA_ReadReg(u8 regAddr)
{
u16 buf;
IIC_Start();
IIC_Send_Byte(RDA_WRITE);//傳送晶片地址 方向為寫
IIC_Wait_Ack();
IIC_Send_Byte(regAddr);//傳送暫存器地址
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(RDA_READ);//傳送晶片地址 方向為讀
IIC_Wait_Ack();
buf = IIC_Read_Byte(1);
buf = buf<<8;
buf =buf|IIC_Read_Byte(0);
IIC_Stop();
return buf;
}
void RDA_WriteReg(u8 regAddr,u16 val)
{
IIC_Start();
IIC_Send_Byte(RDA_WRITE); //傳送晶片地址 方向為寫
IIC_Wait_Ack();
IIC_Send_Byte(regAddr); //傳送暫存器地址
IIC_Wait_Ack();
IIC_Send_Byte(val>>8);
IIC_Wait_Ack();
IIC_Send_Byte(val&0xFF);
IIC_Wait_Ack();
IIC_Stop();
}
void RDA_Vol(u8 vol)
{
u16 temp=0;
if(RDA_State==1)
{
temp=RDA_ReadReg(RDA_R05);
temp&=0xfff0;
RDA_WriteReg(RDA_R05,temp|vol);
}
}
//訊號強度獲取 0~127
u16 RDA_RSSI(void)
{
u16 temp=0;
if(RDA_State==1)
{
temp=RDA_ReadReg(RDA_R0B);
temp=(temp>>9)&0x7f;
}
if(temp<30)
{
LED0=0;
LED1=0;
}
else if(temp>=30 && temp<50)
{
LED0=0;
LED1=1;
}
else if(temp>=50 && temp<70)
{
LED0=1;
LED1=0;
}
else if(temp>=70)
{
LED0=1;
LED1=1;
}
return temp;
}
//搜臺方向 1向上搜尋 0向下搜尋
void RDA_Seek_Direction(u8 direction)
{
u16 temp;
if(RDA_State==1)
{
temp=RDA_ReadReg(RDA_R02);
if(direction == 1)
temp|= 1<<9; //1<<9 => 1000000000
else
temp&=~(1<<9);
RDA_WriteReg(RDA_R02,temp);
}
}
u16 RDA_Search_Freq(void)
{
u16 temp;
temp=RDA_ReadReg(RDA_R02);
temp |= (1<<8);
RDA_WriteReg(RDA_R02,temp) ; //SEEK位置一 使能自動搜臺
while((RDA_ReadReg(RDA_R0A)&(1<<14)) == 0) // 等待STC位置一 表示搜尋完成
{
delay_ms(10); //延時10ms
}
temp = (RDA_ReadReg(RDA_R0A)&0x3FF) + 870 ; //獲取當前頻率
return temp; //返回搜到電臺頻率 單位是:100Khz
}
//頻率設定 單位是:100KHz 87~108MHz
void RDA_Set_Freq(u16 freq)
{
u16 temp=0,chan=0;
temp=RDA_ReadReg(RDA_R03);
temp&=0x3F;
chan=freq-870;
temp|=chan<<6;
temp|=1<<4;
RDA_WriteReg(RDA_R03,temp) ;
delay_ms(50);
RDA_Freq_View(freq);
}
//1 使能晶片 0 禁用晶片
void RDA_Enable(void)
{
u16 temp;
temp=RDA_ReadReg(RDA_R02);
if((temp&0x01)==0)
{
RDA_Init();
RDA_State=1;
}
else
{
RDA_WriteReg(RDA_R02,0);
RDA_State=0;
}
}
void RDA_Init(void)
{
RXFreq=998;
Vol=2;
RDA_State=1;
RDA_WriteReg(RDA_R02,0x0002); //軟體復位
delay_ms(30);
RDA_WriteReg(RDA_R02,0xd281); //晶振選擇32.768Khz 向上搜尋 重低音 立體聲 SKMODE = 1搜尋到邊頻時停止
RDA_WriteReg(RDA_R03,0x0000); //步進100Khz 頻帶為87M~108M
RDA_WriteReg(RDA_R04,0x0040); //基本配置
RDA_WriteReg(RDA_R05,0x88A2); //音量設定為vol=2 搜尋閥值為8
RDA_Set_Freq(RXFreq);
RDA_SPK();
LCD_Init();
}
void RDA_Freq_Down(void)
{
RXFreq-=1; //頻率減,步進100KHZ
if(RXFreq<870) RXFreq=870;
RDA_Set_Freq(RXFreq); //頻率設定
}
void RDA_Freq_Up(void)
{
RXFreq+=1; //頻率加,步進100KHZ
if(RXFreq>1080) RXFreq=1080;
RDA_Set_Freq(RXFreq); //頻率設定
}
//大
void RDA_Vol_Big(void)
{
if(Vol<15)
{
Vol++; //音量加
RDA_Vol(Vol); //音量設定 0~15
}
}
void RDA_Vol_Small(void)//下
{
if(Vol>0) //音量減
{
Vol--;
RDA_Vol(Vol);
}
}
void RDA_Freq_View(u16 freq)
{
u16 ge,shi,bai,xiao;
xiao=freq%10;
ge=(freq%100)/10;
shi=(freq%1000)/100;
bai=freq/1000;
LED0=!LED0;
LCD_ShowNum(50,140,xiao,3,16);
LCD_ShowNum(50,170,ge,3,16);
LCD_ShowNum(50,200,shi,3,16);
LCD_ShowNum(50,230,bai,3,16);
}
//功放
void RDA_SPK(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); //使能PB,PE埠時鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 埠配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推輓輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; //IO口速度為50MHz
GPIO_Init(GPIOF, &GPIO_InitStructure); //根據設定引數初始化GPIOB.5
GPIO_SetBits(GPIOF,GPIO_Pin_5); //PB.5 輸出高
}
//此處得加 標頭檔案 myiic.h gpio.h 以及延時函式的.h 以及LED.h
RDA5807.h
#ifndef __RDA5807_H
#define __RDA5807_H
#include "myiic.h"
#include "stm32f10x.h"
extern u16 RXFreq;
extern u8 Vol;
extern u8 RDA_State;
extern u16 add;
//#define SPK_PIN GPIO_PIN_5
//#define SPK_PORT GPIOF
//#define SPK_R GPIO_WriteReverse(SPK_PORT,SPK_PIN);
//RDA 的暫存器地址
#define RDA_R02 0X02 //DHIZ[15],DMUTE[14]靜音,MONO[13]聲道,BASS[12]重低音,SEEKUP[9],SEEK[8],SKMODE[7],CLK_MODE[6:4]時鐘源選擇,SOFTRESET[1]軟復位,ENABLE[0]電源使能
#define RDA_R03 0X03 //CHAN[15:6],TUNE[4],BAND[3:2],SPACE[1:0] 設定頻率 頻寬 步長
#define RDA_R04 0X04 //STCIEN[14],DE[11],I2Senable[6],
#define RDA_R05 0X05 //INT_MODE[15],SEEKTH[14:8](設定自動搜尋訊號強度閥值),LNA_PORT_SEL[7:6]=0b10,LNA_ICSEL_BIT[5:4],VOLUME[3:0]音量;
#define RDA_R0A 0X0A //STC[14]seek complete SF[13]seek fail readchan[9:0]當前頻道
#define RDA_R0B 0X0B //RSSI[15:9],FM TRUE[8]當前頻道是一個節目臺
#define RDA_R0E 0X0E
#define RDA_READ 0x23 //讀RDA5807
#define RDA_WRITE 0x22 //寫RDA5807
u16 RDA_ReadReg(u8 regAddr);
void RDA_WriteReg(u8 regAddr,u16 val);
void RDA_Init(void);
void RDA_Enable(void);
u16 RDA_RSSI(void);
void RDA_Seek_Direction(u8 direction);
u16 RDA_Search_Freq(void);
void RDA_Set_Freq(u16 freq);
void RDA_Freq_Down(void);
void RDA_Freq_Up(void);
void RDA_Freq_View(u16 freq);
void RDA_Vol(u8 vol);
void RDA_Vol_Big(void);
void RDA_Vol_Small(void);
void RDA_SPK(void);
#endif
KEY.c
//按鍵初始化函式
void KEY_Init(void) //IO初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOF,ENABLE);//使能PORTA,PORTF時鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;//KEY0-KEY1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //設定成上拉輸入GPIO_Mode_IN_FLOATING
GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化GPIOE4,3
//初始化 WK_UP-->GPIOA.0 下拉輸入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0設定成輸入,預設下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.0
}
//按鍵處理函式
//返回按鍵值
//mode:0,不支援連續按;1,支援連續按;
//0,沒有任何按鍵按下
//1,KEY0按下
//2,KEY1按下
//2,KEY2按下
//2,KEY3按下
//2,KEY4按下
//3,KEY5按下 WK_UP
//注意此函式有響應優先順序,KEY0>KEY1>KEY_UP!!
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1;//按鍵按鬆開標誌
if(mode)key_up=1; //支援連按
if(key_up&&(KEY0==0||KEY1==0||KEY2==0||KEY3==0||KEY4==0||WK_UP==1))
{
delay_ms(10);//去抖動
key_up=0;
if(KEY0==0)return KEY0_PRES;
else if(KEY1==0)return KEY1_PRES;
else if(KEY2==0)return KEY2_PRES;
else if(KEY3==0)return KEY3_PRES;
else if(KEY4==0)return KEY4_PRES;
else if(WK_UP==1)return WKUP_PRES;
}else if(KEY0==1&&KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1&&WK_UP==0)key_up=1;
return 0;// 無按鍵按下
}
KEY.h
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
//#define KEY0 PEin(0) //PF0
//#define KEY1 PEin(1) //PF1
//#define KEY1 PEin(2) //PF2
//#define KEY1 PEin(3) //PF3
//#define KEY1 PEin(4) //PF4
//#define WK_UP PAin(0) //PA0 WK_UP
#define KEY0 GPIO_ReadInputDataBit(GPIOF,GPIO_Pin_0)//讀取按鍵0
#define KEY1 GPIO_ReadInputDataBit(GPIOF,GPIO_Pin_1)//讀取按鍵1
#define KEY2 GPIO_ReadInputDataBit(GPIOF,GPIO_Pin_2)//讀取按鍵2
#define KEY3 GPIO_ReadInputDataBit(GPIOF,GPIO_Pin_3)//讀取按鍵3
#define KEY4 GPIO_ReadInputDataBit(GPIOF,GPIO_Pin_4)//讀取按鍵4
#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//讀取按鍵5(WK_UP)
#define KEY0_PRES 1 //KEY0按下
#define KEY1_PRES 2 //KEY1按下
#define KEY2_PRES 3 //KEY1按下
#define KEY3_PRES 4 //KEY1按下
#define KEY4_PRES 5 //KEY1按下
#define WKUP_PRES 6 //KEY_UP按下(即WK_UP/KEY_UP)
void KEY_Init(void);//IO初始化
u8 KEY_Scan(u8); //按鍵掃描函式
#endif
main.c
#include "stm32f10x.h"
#include "RDA5807.h"
#include "lcd.h"
#include "led.h"
#include "key.h"
#include "myiic.h"
#include "usart.h"
#include "delay.h"
#include "sys.h"
int main(void)
{
u16 time=0;
vu8 key=0;
int bushu = 10;
delay_init(); //延時函式初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設定中斷優先順序分組為組2:2位搶佔優先順序,2位響應優先順序
uart_init(115200); //串列埠初始化為115200
LED_Init();
LCD_Init();
KEY_Init();
IIC_Init();
RDA_Init();
POINT_COLOR=RED;//設定字型為紅色
while(1)
{
key=KEY_Scan(0); //得到鍵值
if(key)
{
switch(key)
{
case KEY0_PRES:
RDA_Seek_Direction(0);
RXFreq=RDA_Search_Freq();
RDA_Freq_View(RXFreq);
break;
case KEY1_PRES:
RDA_Seek_Direction(1);
RXFreq=RDA_Search_Freq();
RDA_Freq_View(RXFreq);
break;
//case KEY2_PRES;
// RDA_Vol_Small();
// break;
case WKUP_PRES:
RDA_Vol_Big();
break;
case KEY4_PRES:
RDA_Enable();
break;
case KEY3_PRES:
RDA_Freq_Down();
break;
case KEY2_PRES:
RDA_Freq_Up();
break;
}
}else
delay_ms(10);
time++;
// LCD_ShowNum(50,230,time,3,16);
if(time>100)
{
time=0;
//780 282 683
printf("頻率:%d\r\n",RXFreq);
printf("訊號:%d\r\n",RDA_RSSI());
printf("音量:%d\r\n",Vol);
printf("0x0E :%d\r\n",add);
printf("\r\n");
}
}
}
自己設定的按鍵數目較少,並且懶得折騰按鍵的識別方式
只採用按下識別,所以需要的按鍵特別多
參考了 RDA5807程式設計指南,
做出來搞得很亂,採用的天線是粉刺針 ?
通過按鍵控制 上下搜臺以及調頻收臺,最終通過耳機可以聽到廣播
相關文章
- 調幅收音機(AM)與調頻收音機(FM)的區別
- 製作一個Mac APP:XcodeExtensionMacAPPXCode
- Unity製作一個小星球Unity
- 製作一個報警系統
- 如何製作一個CocoaPods私有庫
- 如何製作一個 RPM 檔案
- 自己如何製作一個網頁網頁
- Golang簡單製作一個池Golang
- 通過一個案例理解 JWTJWT
- 如何製作一個手機上的Github圖床捷徑(workflow)Github圖床
- win10系統下怎麼聽收音機_win10電腦中聽收音機教程Win10
- 如何跑通第一個 SQL 作業SQL
- 自己怎麼製作一個網站網站
- 製作一個瀏覽器導航瀏覽器
- 如何用PS製作一個小泡泡呢?
- 如何使用 Arduino 製作一個繪圖儀UI繪圖
- 製作一個電商APP需要多少錢?APP
- 如何製作一個音遊鬼畜視訊
- 怎麼用PPT製作一個照片畫冊?PowerPoint製作照片畫冊教程
- docker通過commit命令提交一個映象DockerMIT
- 作為程式設計師,我是怎麼通過一個方法記住7000個單詞的!程式設計師
- 手機寫作業系統之 製作第1個啟動盤作業系統
- 這款一個人製作的單機遊戲,成為了網友眼中的抗日“神作”遊戲
- 製作一個Node命令列影像識別工具命令列
- 製作一個Node命令列影象識別工具命令列
- 如何用 vue 製作一個探探滑動元件Vue元件
- ❤️❌ 如何用vue製作一個探探滑動元件Vue元件
- 請使用純HTML製作一個進度條HTML
- 製作一個ai叢雨(附Python程式碼)AIPython
- 如何用CSS製作一個圓形放大鏡CSS
- 從零開始製作一個linux iso映象Linux
- 通過express快速搭建一個node服務Express
- [譯] 製作 Vue 3 的過程Vue
- 跟大神一起製作一個屬於自己的Linux作業系統!Linux作業系統
- 【譯】通過css,用一個div做一個芝士漢堡CSS
- 短視訊app製作,附近功能通過使用者IP地址確定位置APP
- Unity製作手機端VR第一步UnityVR
- 推薦一個製作「ASCII 流程圖」工具——Graph EasyASCII流程圖