На базе двух модулей 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); }