RDA5807を使ったラジオ

 

0.まずはお約束

shiro46tan.hatenablog.com

1.回路

 


これで良しとした。
・PIC,74HC4511,7セグLEDを1枚に、RDA5807とパワーアンプを1枚に載せる。
・電源は5V、または単3×3(ニッケル水素電池の充電式)とする。
・私は赤の7セグLEDを利用した。暗いという方は抵抗を調整してください。

f:id:shiro46tan:20210507180409j:plain

回路図

 

f:id:shiro46tan:20210507180740j:plain

製作例
2.ソフト


・マニュアルによれば、RDA5807のIDは10H。1Bit左シフトして、20Hを送信となる。
レジスタへのデータ書き込み方法は、レジスタアドレスが自動INCされるので、それに合わせて順にデータを送る方法。この方法では、電源ON時に最後までデータを書き込めないことがあった。
・ネットにてレジスタアドレスとデータをペアで送る裏コマンドを発見(ID:11h。1Bit左シフトで22h)。これを用いる方法に変更した。
・それでも電源ON時はなぜか周波数が書き込めなかったので、電源ON時に限り周波数を2回書き込んでいる。個体ばらつきによっては、これでも電源ON時は動かないかもしれない。その場合はWait(プログラム中のdelay_ms(1000) )を大きくする。
・10ch分のプリセットは、関東地区用。周波数を変える場合は、freq[]の値を変える。
計算式は、(freq(kHz)-760000)/100。0chは別掲のTransmitterに合わせた。

 

3.動作確認

・電源を入れると、7セグLEDが約0.5秒間0を表示して消灯する。スピーカからは、ホワイトノイズまたは音声が聞こえる。
・SWを押すと、7セグLEDは順にカウントアップ、9の後は0になる。それに伴い受信局が変化すれば完成。
・電流は、5V、LED OFF、音量0で25mA前後。

 

4.プログラム


XC8 V1.34用。

 

/* File: RDA5087radio.c
*
* By Shiro46tan
* 2021/5/7
*/

// --PIC16F1503--
// SDA : PORTC(1) pin 9
// SCL : PORTC(0) pin10
// 4MHz

#include <xc.h>
#define _XTAL_FREQ 4000000

#define SW1 PORTAbits.RA0

#define LED0 PORTCbits.RC2 //Bit0
#define LED1 PORTAbits.RA2 //Bit1
#define LED2 PORTAbits.RA4 //Bit2
#define LED3 PORTCbits.RC3 //Bit3
#define LED4 PORTCbits.RC5 //LED ON/OFF
#define PL PORTAbits.RA5 //LED for check

//************* Config ***********************************
#pragma config FOSC = INTOSC, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = ON
// Watch Dog timer をOffにしないと、途中でリセットがかかる可能性あり
#pragma config BOREN = ON, CLKOUTEN = OFF
//    CLKOUTをRA4として使う
#pragma config WRT = OFF
#pragma config STVREN = ON, BORV = LO, LPBOR = OFF, LVP = OFF


//********************************************************

void i2cTxData(char);
void SendCMD(void);
void SleepIn(void);
void i2cStart(void);
void i2cStop(void);
void reset(void);
void send(unsigned char, unsigned char, unsigned char);


//初期設定

char VOLUME=0x08;

int freq[10]={0x3138,14500,15600,17000,0x7d0,0xdac,0xfa0,0x14b4,0x1964,0x21fc};
// 受信周波数 88.6 90.5 91.6 93 78 79.5 80 81.3 82.5 84.7
//
//
int RcvFreq=0x3138; //(受信周波数-76000KHz)/100 88.6MHz
char ch=0;

//////////// Main //////////////////////////////////
void main(void){

int i=0,j=0;

unsigned char num = 0;
OSCCON = 0b01101000; // 4MHz


__delay_ms(100);

 

ANSELA = 0x0;
ANSELC = 0x0; // PortCをデジタルI/Oにする
TRISC = 0b11000011; // PortC I/O設定 1がInput
TRISA = 0b11000011;
SSPCON1 = 0x28; // I2Cマスター
SSPSTAT = 0x00;
SSPADD = 0x24; // I2C周波数100KHz for 4MHz

WPUA=0b00000011; // pullup
OPTION_REGbits.nWPUEN=0; //

LED4=0;

__delay_ms(1000); //十分なWaitを取る

RcvFreq=0x3138;
reset();
__delay_ms(100);


SendCMD();

send(0x08,0x31,0x38);

INTCONbits.IOCIE=1; //IOC(状態変化割り込み)Enable
IOCAPbits.IOCAP0=1; //Port RA0(=SW1)ボタン割り込み

INTCONbits.GIE=1; //INTグローバルEnable

while(1){
SleepIn();
}

}

 

void i2cStart(void){
SEN = 1; // Start condition
while(SEN); // Start condition
}

void i2cStop(void){ //i2c STOP
SSP1IF = 0; // クリア
PEN = 1; // Stop condition
while(PEN); // Stop condition
}

void i2cTxData(char data){
SSP1IF = 0; //
SSPBUF = data; //
while(!SSP1IF); //
}

void send(unsigned char ch,unsigned char i,unsigned char j){
i2cStart();

i2cTxData(0x22); // スレーブアドレス 0010001+0

i2cTxData(ch); // channel

i2cTxData(i); // upper

i2cTxData(j); // lower

i2cStop();
}


void reset(void) {

send(0x02,0xa0,0x03);

}


void SendCMD(void){

//02H
send(0x02,0xd0,0x01);
// Mono+Bass Boost disable seekしない
// 32.768k Power On

//03H
send(0x03,0x00,0x04);
//Band=1

//04H
send(0x04,0x0a,0x00);
//De-Emphasis50us
//I2S,GPIO 使わない

//05H
send(0x05,0x88,0x80+VOLUME);
//
//Volume 0 - 15

//06H
send(0x06,0x00,0x00);
//I2Setc 使わない


//07H
send(0x07,0x40,0x03);
//0Bit=1にして、08Hに周波数を書き込む

//08H
send(0x08,RcvFreq>>8,0x00ff & RcvFreq);

//chの表示
LED4=1; //LED ON
LED0=ch&1;
LED1=(ch>>1)&1;
LED2=(ch>>2)&1;
LED3=(ch>>3)&1;
__delay_ms(1000); //1秒待つ

LED4=0; //LED OFF

}


void SleepIn(void){


IOCAPbits.IOCAP0=1; //RA0(=SW3)ボタン割り込みON

PL=0;
SLEEP();
}

 


void interrupt isr(void)
{


if(IOCAFbits.IOCAF0){ //RA0(=SW1)ボタンが押されたとき

while(SW1==0); //離すのを待つ
ch++;

if(ch>=10){ //ch=10になったら0にする
ch=0;
}

RcvFreq=freq[ch]; //受信周波数をfreq[ch]にする

SendCMD();
__delay_ms(100);

IOCAFbits.IOCAF0=0; //clear flag
}

}