JH3DRN 趣味の徒然

主にアマチュア無線、電子工作について書いてます.

KBS京都専用ラジオを作ってみた:スケッチ編

備忘の為スケッチ掲載.

I2Cでコントロール出来るラジオ用IC : Si4730 は値段も安く、AM / FM が受信出来て便利なICでは有るのだが、このラジオを作った当時、参考になるスケッチが無かったので、データシート見ながら自分で関数作った覚えがある。余り参考にならないと思うが備忘をかねてスケッチを掲載する事にした。このスケッチは Arduino IDE 1.8.16 でコンパイル出来る事は確認したのだが、保証は出来ないので悪しからず。

/*------------------------------------------

  Si4730 FM/AM Radio use aitendo Si4730-M
    for Teke Bar Version
    Writen JH3DRN 2020/08/20   Fix Ver  

    PORTB (Digital pin 8 to 13) 
    PORTC (Analog pin) 
    PORTD (Digital pin 0 to 7)
    Pin 2   Interrupt 0 (use this case)
    Pin 3   Interrupt 1 (not use)
    Use Arduino IDE Version is 1.8.16

-------------------------------------------*/

#define   SCL_PIN 5               // SCL=pin A5
#define   SCL_PORT PORTC 
#define   SDA_PIN 4               // SDA=pin A4 
#define   SDA_PORT PORTC 
#define   I2C_FASTMODE  1
#include  <SoftI2CMaster.h>

#define   si4370_add      0xc6    // if use Wire.h Val=0x63
#define   Mode_sel        9       // Freq select DipSW 1
#define   Mode_AM         0
#define   Mode_FM         1
#define   Reset_Pin       3      // Module reset pin
#define   CHATR_CHK       15     // Chattaring check count
#define   CH_MAX_TOKYO    8      // Recive ch MAX Count of Tokyo
#define   CH_MAX_KYOTO    10     // Recive ch MAX Count of Kyoto
#define   CH_MAX_OSAKA    11
#define   Tokyo           0      // Area code Tokyo
#define   Kyoto           1
#define   Osaka           2

// variables will change:
int  buttonState = 0;         // variable for reading the pushbutton status
int  ch_pos;                  // Ch Position
int  ch_max;                  // Ch Count Max Value
int  area_code;               // 0=Tokyo,1=Kyoto etc
char printBuffer[32];         // Need 50 byte
int  ch_pos_now;              // Now Chanel Possition
int  ch_pos_befo;             // Beffore Chanel Possition
int  mode_now;                // Default Band is FM=1 AM=0
int  mode_befo;               // Before Band 
int  mode_cnt=0;

unsigned char Cmd_Si4730_power_up[] =   {0x01,0x41,0x05};            // Power on
unsigned char Cmd_FM_power_up[] = {0x01,0x10,0x05};                  // Power on FM Band
unsigned char Cmd_AM_power_up[] = {0x01,0x11,0x05};                  // POwer on AM Band
unsigned char Cmd_FM_Freq_Tune[] = {0x20,0x00,0x24,0x54,0x00};       // 93.00MHz  Init Freq
unsigned char Cmd_AM_Freq_Tune[] = {0x40,0x00,0x04,0x6e,0x00};       // 1134KHz   Init Freq
unsigned char Cmd_FM_DeemP[] = {0x12,0x00,0x11,0x00,0x00,0x01};      // Deemph 50μS
unsigned char Cmd_FM_Antena_In[] = {0x12,0x00,0x11,0x07,0x00,0x01};  // FM Antena Input
unsigned char Cmd_Set_Vol[] = {0x12,0x00,0x40,0x00,0x00,0x3f};       // Volume Control Max=0x3F

uint16_t Stations_kyoto_FM[CH_MAX_KYOTO] = {7650, 7700, 8100, 8150, 8400, 8940, 9190, 9490};
uint16_t Stations_kyoto_AM[CH_MAX_KYOTO] = {558, 666, 828, 945, 1008, 1143, 1215, 1242};

uint16_t *defaultStations;
/*
TBS Rsdio       954khz
Bunka Hoso      1134khz
Nippon Hoso     1242khz
NHK No1         594khz
NHK No2         693khz
Eagle810        810khz
RadioNippon    1422khz
*/
 
void setup() {
  
  pin_mode_init();            // Set Pin mode to init
  i2c_init();
  Serial.begin(115200);
  Serial.println("Start init");
  RadioModule_Reset();        // Chip Reset
  delay(100);
  freq_mode_set();  
  ch_pos=0;                   // Set Chanel possition is 0
  Set_Chanel(mode_now, ch_pos);
 }

void loop() {
  char option;
  char vol = 15;
  uint8_t  Retbtn;
  byte current_vol;
 
  ch_pos_befo = ch_pos;
  mode_befo = mode_now;
  
  while(1)
    {
    if(digitalRead(Mode_sel) == HIGH)   // Mode AM?
      {
      if(mode_now == Mode_FM)
      {
       mode_now=Mode_AM;
       mode_setting_AM();         
      }
      }else
      if(mode_now == Mode_AM)
      {
       mode_now=Mode_FM;
       mode_setting_FM();              
      }
      
    Retbtn=read_freq_dipsw();       // Read Dip SW
    ch_pos = Retbtn;                // Save now ch
    Serial.print(Retbtn);
    Serial.println();

    if(ch_pos_befo != Retbtn)
    {
    Set_Chanel(mode_now, ch_pos);
    ch_pos_befo = ch_pos;      
    }
    delay(1500);
    }
  delay(100);
}

void RadioModule_Reset(void)
{
  pinMode(Reset_Pin, OUTPUT);    // Reset pin D9 is output
  digitalWrite(Reset_Pin,LOW);
  _delay_ms(1);
  digitalWrite(Reset_Pin,HIGH);
  _delay_ms(1);  
//  PORT_LOW(PORTB,RADIO_RESET);
//  _delay_ms(1);
//  PORT_HIGH(PORTB,RADIO_RESET);
//  _delay_ms(1);
}


void Chip_Power_Down(void)
{                         //     'パワーダウン  受信モードを変える場合、一度電源落とす
unsigned char pow_off[]={0x11};
Si4730_Cmd_Write(pow_off,1);
delay(300);
}

uint8_t Read_Status(void)      // CTS が0x80になるまで待つ
{
  uint8_t msb,lsb;
  uint8_t retdt,i;

  for(i=0;i<10;i++)           // 10回待って駄目なら諦める
  {
  i2c_start(si4370_add | I2C_READ);
  lsb = i2c_read(false);
  msb = i2c_read(true);
  i2c_stop();
//  Serial.print(msb,HEX); Serial.print(" ");
//  Serial.print(lsb,HEX); Serial.println(" ");
  if( lsb == 0x80) break;  // if ACK Recive
  delay(100);
  }
  return(lsb);
}

uint8_t Si4730_Cmd_Write(unsigned char *cmd,int len)
{
  uint8_t ret;
  int i;
  i2c_start(si4370_add | I2C_WRITE);    // write mode 
  for(i=0;i<len;i++)
    {
    i2c_write(cmd[i]);     //    I2cwbyte &H2c  'max 0x3f
    }
  i2c_stop();
  ret=Read_Status(); 
  return(ret);            //    I2cstop
}

void Set_Chanel_Tune(int mode,unsigned int freq_int)
{
//  Serial.print("freq="); Serial.print(freq_int,DEC);
//  Serial.print("mode="); Serial.print(mode,DEC);
  switch(mode)        // AM = mode0,FM = mode1
  {
    case Mode_AM:
            Cmd_AM_Freq_Tune[2]=(freq_int & 0xff00) >> 8; 
            Cmd_AM_Freq_Tune[3]=(freq_int & 0x00ff);
            Si4730_Cmd_Write(Cmd_AM_Freq_Tune,sizeof(Cmd_AM_Freq_Tune));
            break;
    case Mode_FM:
            Cmd_FM_Freq_Tune[2]=(freq_int & 0xff00) >> 8; 
            Cmd_FM_Freq_Tune[3]=(freq_int & 0x00ff);
            Si4730_Cmd_Write(Cmd_FM_Freq_Tune,sizeof(Cmd_FM_Freq_Tune));
            break;
    default:
            break;
  }
}

void pin_mode_init(void)
{
  pinMode(10, INPUT);   // Dip SW port D10=12Mode sel
  pinMode(11, INPUT);   // D11-13 Freq select
  pinMode(12, INPUT);
  pinMode(9, INPUT);    // D9 = Freq AM/FM

  pinMode(Reset_Pin, OUTPUT);   // Board reset port (D3)
  pinMode(5, OUTPUT);           // LED port D5 = Mode sel
  pinMode(6, OUTPUT);           // D6-D8 Freq. sel sw
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);

  digitalWrite(5,HIGH);    // all LED off
  digitalWrite(6,HIGH);    
  digitalWrite(7,HIGH);    
  digitalWrite(8,HIGH);    
}

/*
TBS Rsdio       954khz
Bunka Hoso     1134khz
Nippon Hoso     1242khz
NHK No1         594khz
NHK No2         693khz
Eagle810        810khz
RadioNippon    1422khz
*/

void Set_Chanel(int mode, int pos)       // mode AM/FM pos ch possition
  {
//  Serial.print(pos,HEX); Serial.println("  pos ");
  Set_Chanel_Tune(mode,defaultStations[pos]);    // Start Freqncy setup
  }

//--------------BAND SWITCH --------------------------

void mode_setting_AM()
  {
  Chip_Power_Down();            // Chip Power down
  Si4730_Cmd_Write(Cmd_AM_power_up,sizeof(Cmd_AM_power_up));
  defaultStations = Stations_kyoto_AM;  // Kyoto Frequncy set
  ch_max = CH_MAX_KYOTO;
  ch_pos=0;
  Set_Chanel(mode_now,ch_pos);
  digitalWrite(10,LOW);

  }
  
void mode_setting_FM()
  {
  Chip_Power_Down();            // Chip Power down
  Si4730_Cmd_Write(Cmd_FM_power_up,sizeof(Cmd_FM_power_up));
  ch_max = CH_MAX_TOKYO;
  ch_pos=0;
  defaultStations = Stations_kyoto_FM;  // Kyoto Frequncy set
 
  Set_Chanel(mode_now,ch_pos);
  digitalWrite(10,HIGH);
}

uint8_t read_freq_dipsw()     // Read Dip SW Value & Set LED
{
uint8_t retval;

retval = 0x00;              // init val set

if (digitalRead(10) == HIGH)
  {
    retval = retval | 0b0001;
    digitalWrite(8,LOW);
  } else digitalWrite(8,HIGH);

if (digitalRead(11) == HIGH)
  {
    retval = retval | 0b0010;
    digitalWrite(7,LOW);
  } else digitalWrite(7,HIGH);

if (digitalRead(12) == HIGH)
  {
    retval = retval | 0b0100;
    digitalWrite(6,LOW);
  } else digitalWrite(6,HIGH);
return(retval);
}

/* Freq Mode set  */

void freq_mode_set()
  {
   if ( digitalRead(Mode_sel) == HIGH )        // Mode AM ?
        {
        mode_now=Mode_AM;
        mode_setting_AM();
       } 
       else
       {
       mode_now=Mode_FM;           // Default Band is FM
       mode_setting_FM();
       }
  mode_now = mode_befo;
  }