Si4703 + HT1621 (Arduino)

На базе двух модулей Si4703 и HT1621 можно собрать простое FM-радио. Более подробно об FM-модуле можно узнать из http://rcl-radio.ru/?p=108688, а ЖК модуль HT1621 подробно описан в http://rcl-radio.ru/?p=132305.

Если коротко, то ЖК-модуль с контроллером HT1621 состоит из 6-и разрядов (7 сегментов) и дополнительно содержит индикатор батареи. Управление индикатора осуществляется по шине 3-Wire. Напряжение питания 5 В. Модуль Si4703 представляет собой FM-радиоприёмник (УКВ от 76 МГц до 108 МГц) с цифровым управлением и функцией RDS. Так же модуль содержит маломощный усилитель мощности звуковой частоты TPA6111A2, позволяющий подключать наушники к модулю используя разъем 3,5 мм, при этом подключенные наушники используются в качестве антенны. Управление модуля радио осуществляется по шине 3-Wire. Напряжение питания 3,3 В.

FM — радио имеет 4-е кнопки управления, две для автоматического поиска радиостанций, а другие две для регулировки громкости. На дисплее всегда отображается текущая частота станции, при нажатии на кнопки регулировки громкости дисплей отображает громкость и далее после окончания регулировки громкости в течении 2 секунд отображается текущая громкость и далее дисплей снова переходит в режим отображения частоты станции.

Так же после регулировки громкости или частоты станции через минуту не активности органов управления частота и уровень громкости записываются в энергонезависимую память.

Схема FM-радио

Скетч

#define LCD_CS            2
#define LCD_WR            3
#define LCD_DATA          4

#define Si4703_SDIO       6
#define Si4703_SCLK       5
#define Si4703_SEN        8 
#define Si4703_RST        7

#define BUTTON_FREQ_UP    9
#define BUTTON_FREQ_DW   10
#define BUTTON_VOL_UP    11 
#define BUTTON_VOL_DW    12

#define HT1621_BIAS      0x52                    // 1/3duty 4com
#define HT1621_SYS_DIS   0x00                    // Turn off the oscillator system oscillator and LCD bias generator
#define HT1621_SYS_EN    0x02                    // Turn on the system oscillator
#define HT1621_LCD_OFF   0x04                    // Turn off LCD bias
#define HT1621_LCD_ON    0x06                    // Turn on the LCE bias
#define HT1621_XTAL      0x28                    // external clock
#define HT1621_RC256     0x30                    // internal clock

#include <si4703.h>  // http://rcl-radio.ru/wp-content/uploads/2021/09/si4703.zip
#include <EEPROM.h>
si4703 radio(Si4703_SDIO,Si4703_SCLK,Si4703_SEN,Si4703_RST); // SDIO, SCLK, SEN, RST

unsigned long times,times_w;
int f,save_ch;
int canel,vol; 
int f_cannel = 1035;// test

void setup() {
  pinMode(BUTTON_FREQ_UP,INPUT_PULLUP);// UP F
  pinMode(BUTTON_FREQ_DW,INPUT_PULLUP);// DW F
  pinMode(BUTTON_VOL_UP,INPUT_PULLUP);// VOL+
  pinMode(BUTTON_VOL_DW,INPUT_PULLUP);// VOL-
  pinMode(LCD_CS, OUTPUT);
  pinMode(LCD_WR, OUTPUT);
  pinMode(LCD_DATA, OUTPUT);
  digitalWrite(LCD_CS,HIGH);
  digitalWrite(LCD_WR,HIGH);
  data_100(HT1621_SYS_EN); // Turn on the system oscillator
  data_100(HT1621_BIAS);   // BIAS 13 4 public ports
  data_100(HT1621_RC256);  // Use RC_256K system clock source, on-chip RC oscillator
  data_100(HT1621_LCD_ON);
  clear_lcd();
  radio.init();
  delay(10);
  canel = ((EEPROM.read(400)<<8))|EEPROM.read(401);vol=EEPROM.read(402);
  if(canel>320){canel=0;}if(vol>15){vol=10;}
  radio.fm_start(canel);// 101.9 МГц (1019-760 = 259)
 // radio.fm_start(f_cannel-760);// 103.5 МГц test
  radio.si_volume(vol);// 0...15
}

void loop(){
  if(digitalRead(BUTTON_FREQ_UP)==LOW){radio.seek_up();save_ch=1;times=millis();delay(200);}
  if(digitalRead(BUTTON_FREQ_DW)==LOW){radio.seek_down();save_ch=1;times=millis();delay(200);}

  if(digitalRead(BUTTON_VOL_UP)==LOW){vol++;save_ch=1;times=millis();if(vol>15){vol=15;}radio.si_volume(vol);times_w=millis();delay(200);}
  if(digitalRead(BUTTON_VOL_DW)==LOW){vol--;save_ch=1;times=millis();if(vol<0){vol=0;}radio.si_volume(vol);times_w=millis();delay(200);}

  if(millis()-times_w<=2000){ 
    print_lcd(5, 13,false);
    print_lcd(4, 10,false);
    print_lcd(3, vol/10%10,false);
    print_lcd(2, vol%10,false);
    print_lcd(1, 10,false);
    print_lcd(0, 10,false);
  }

  if(millis()-times_w>2000){  
    f=int(radio.nom_ch()*10+7600);
    print_lcd(5, 12,false);
    if(f/10000%10==0){print_lcd(4, 10,false);}else{print_lcd(4, f/10000%10,false);}
    print_lcd(3, f/1000%10,false);
    print_lcd(2, f/100%10,false);
    print_lcd(1, f/10%10,true);
    print_lcd(0, f%10,false);
  }
 
  delay(1);

/////// EEPROM ////////////////////////////////////////////////// 
  if(millis()-times>60000&&save_ch==1){save_ch=0;canel = radio.nom_ch();
  EEPROM.update(400,(canel>>8) & 0b11);EEPROM.update(401,canel & 0xFF);EEPROM.update(402,vol);}
}

void print_lcd(byte raz, byte num, bool dp){
  switch(raz){
    case 0: raz=0;break;
    case 1: raz=2;break;
    case 2: raz=4;break;
    case 3: raz=6;break;
    case 4: raz=8;break;
    case 5: raz=10;break;
    }
  switch(num){
    case 0: data_101(raz,0b1110+dp);data_101(raz+1,0b1011);break;  // 0 
    case 1: data_101(raz,0b0110+dp);data_101(raz+1,0b0000);break;  // 1 
    case 2: data_101(raz,0b1100+dp);data_101(raz+1,0b0111);break;  // 2 
    case 3: data_101(raz,0b1110+dp);data_101(raz+1,0b0101);break;  // 3 
    case 4: data_101(raz,0b0110+dp);data_101(raz+1,0b1100);break;  // 4 
    case 5: data_101(raz,0b1010+dp);data_101(raz+1,0b1101);break;  // 5 
    case 6: data_101(raz,0b1010+dp);data_101(raz+1,0b1111);break;  // 6 
    case 7: data_101(raz,0b1110+dp);data_101(raz+1,0b0000);break;  // 7 
    case 8: data_101(raz,0b1110+dp);data_101(raz+1,0b1111);break;  // 8 
    case 9: data_101(raz,0b1110+dp);data_101(raz+1,0b1101);break;  // 9 
    case 10: data_101(raz,0);data_101(raz+1,0);break;  // пусто
    case 11: data_101(raz,0b0000);data_101(raz+1,0b0100);break;  // -
    case 12: data_101(raz,0b1000);data_101(raz+1,0b1110);break;  // F
    case 13: data_101(raz,0b0110);data_101(raz+1,0b1011);break;  // U
    }
  }

void clear_lcd(){for(int a=0;a<=32;a++){data_101(a,0);}}

void data_100(int data){
     digitalWrite(LCD_CS,LOW);
   for(int i = 2; i >=0; i--){
     digitalWrite(LCD_WR,LOW);delayMicroseconds(10);
     digitalWrite(LCD_DATA, (0b100 >> i) & 1); 
     digitalWrite(LCD_WR,HIGH);delayMicroseconds(10);
     } 
   for(int i = 8; i >=0; i--){
     digitalWrite(LCD_WR,LOW);delayMicroseconds(10);
     digitalWrite(LCD_DATA, (data >> i) & 1); 
     digitalWrite(LCD_WR,HIGH);delayMicroseconds(10);
     } 
     delayMicroseconds(10);digitalWrite(LCD_CS,HIGH);
     delayMicroseconds(10);digitalWrite(LCD_WR,LOW);
     delayMicroseconds(10);
  }

void data_101(int addr, int data){
     digitalWrite(LCD_CS,LOW);
   for(int i = 2; i >=0; i--){
     digitalWrite(LCD_WR,LOW);delayMicroseconds(10);
     digitalWrite(LCD_DATA, (0b101 >> i) & 1); 
     digitalWrite(LCD_WR,HIGH);delayMicroseconds(10);
     } 
   for(int i = 5; i >=0; i--){
     digitalWrite(LCD_WR,LOW);delayMicroseconds(10);
     digitalWrite(LCD_DATA, (addr >> i) & 1); 
     digitalWrite(LCD_WR,HIGH);delayMicroseconds(10);
     } 
   for(int i = 0; i <=3; i++){
     digitalWrite(LCD_WR,LOW);delayMicroseconds(10);
     digitalWrite(LCD_DATA, (data >> i) & 1); 
     digitalWrite(LCD_WR,HIGH);delayMicroseconds(10);
     }   
     delayMicroseconds(10);digitalWrite(LCD_CS,HIGH);
     delayMicroseconds(10);digitalWrite(LCD_WR,LOW);
  }  

 

Добавить комментарий

Войти с помощью: