关于1602屏灯控制的问题-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

楼主: xgm1818

[未解决] 关于1602屏灯控制的问题

[复制链接]
 楼主| 发表于 2022-3-16 19:59 | 显示全部楼层
lwq1947 发表于 2022-3-16 15:44
说具体点,比如将#define ENCODER_PIN_A 2改成#define ENCODER_PIN_A 10,连接10与2,在void setup()中添 ...

非常感谢您的回复,我还是不能理解具体怎么改,今天下午看到有一段程序与我想要达到的有些吻合,我用开关代替编码器搭了模拟电路,不过是用delay做延时,用delay做的延时如果加到主程序里面应该是系统会卡死的;其它我就不会了,您再帮我看看如果下面这个程序把延时部分改了能不能用,应该怎么改;

  1. int SensorLED = 8;       //定义8脚控制1602背光
  2. int SensorINPUT = 2;      //定义编码开关连接中断0(2脚)
  3. char state = LOW;

  4. void setup() {

  5. pinMode(SensorLED, OUTPUT);         //LED为输出模式
  6. pinMode(SensorINPUT, INPUT); //输入模式

  7.   //电平改变触发,触发中断0,调用blink函数
  8.   attachInterrupt(0, blink, CHANGE);
  9. }

  10. void loop() {

  11.   if (state == HIGH) {        // 如果state为HIGH
  12.     state = LOW;
  13.     digitalWrite(SensorLED, HIGH);  // 亮灯
  14.     delay(5000);          //延时
  15.   }
  16.   else {
  17.     digitalWrite(SensorLED, LOW);    // 否则,关灯
  18.   }
  19. }
  20. void blink() {               //中断函数blink()
  21.   state = !state;             //一旦中断触发,state状态反转
  22. }
复制代码
 楼主| 发表于 2022-3-16 20:14 | 显示全部楼层
lwq1947 发表于 2022-3-16 15:44
说具体点,比如将#define ENCODER_PIN_A 2改成#define ENCODER_PIN_A 10,连接10与2,在void setup()中添 ...

偿试上面的代码放进主程序里也是报错的
111.png
发表于 2022-3-17 06:50 | 显示全部楼层
xgm1818 发表于 2022-3-16 20:14
偿试上面的代码放进主程序里也是报错的

中断名不要用blink,以下程序可行:
uint32_t ptime=0;
void abc() {
digitalWrite(8,HIGH);
ptime= millis();
}
void setup() {
  attachInterrupt(0, abc, CHANGE );
  pinMode(8
  ,OUTPUT);
  digitalWrite(8,LOW);
}

void loop() {
if(millis()-ptime>5000) digitalWrite(8,LOW);

}
 楼主| 发表于 2022-3-17 19:11 | 显示全部楼层
lwq1947 发表于 2022-3-17 06:50
中断名不要用blink,以下程序可行:
uint32_t ptime=0;
void abc() {

谢谢!我将您的程序单独上传,拧动编码器后能正常点亮1602背光,偶尔有时候要较长时间熄灭,用万用表电压挡架在D8口时就能熄灭,这个我感觉在D8口加个对地电阻就可以了,但是当我把这个背光程序加到主程序里,还是没有点亮背光,不知是不是我加的位置不对?下面是我加进去之后程序;
  1. #include <SI4735.h>
  2. #include <EEPROM.h>
  3. #include <LiquidCrystal.h>
  4. #include "Rotary.h"
  5. #include "patch_init.h" // 整个SSBRX初始化字符串的SSB补丁

  6. const uint16_t size_content = sizeof ssb_patch_content; // 参见补丁_init。H


  7. #define FM_BAND_TYPE 0
  8. #define MW_BAND_TYPE 1
  9. #define SW_BAND_TYPE 2
  10. #define LW_BAND_TYPE 3

  11. #define RESET_PIN 9

  12. //编码引脚
  13. #define ENCODER_PIN_A 2
  14. #define ENCODER_PIN_B 3

  15. // LCD 16x02 or LCD20x4 PINs
  16. #define LCD_D7 4
  17. #define LCD_D6 5
  18. #define LCD_D5 6
  19. #define LCD_D4 7
  20. #define LCD_RS 12
  21. #define LCD_E 13

  22. // Buttons controllers
  23. #define ENCODER_PUSH_BUTTON 14 // 引脚A0/14
  24. #define DUMMY_BUTTON 15

  25. #define MIN_ELAPSED_TIME 300
  26. #define MIN_ELAPSED_RSSI_TIME 500
  27. #define ELAPSED_COMMAND 3000
  28. #define ELAPSED_CLICK 1500  
  29. #define DEFAULT_VOLUME 40   

  30. #define FM 0
  31. #define LSB 1
  32. #define USB 2
  33. #define AM 3
  34. #define LW 4

  35. #define SSB 1

  36. #define EEPROM_SIZE        512

  37. #define STORE_TIME 10000 // 使当前接收器状态可写的非活动时间(10秒/10000毫秒)。
  38. // EEPROM - Stroring control variables
  39. const uint8_t app_id = 31; // EEPROM-选通控制变量
  40. const int eeprom_address = 0;
  41. long storeTime = millis();

  42. bool itIsTimeToSave = false;

  43. bool bfoOn = false;
  44. bool ssbLoaded = false;

  45. int8_t agcIdx = 0;
  46. uint8_t disableAgc = 0;
  47. int8_t agcNdx = 0;
  48. int8_t softMuteMaxAttIdx = 4;
  49. int8_t avcIdx;   // 最小12,最大90
  50. uint8_t countClick = 0;

  51. uint8_t seekDirection = 1;

  52. bool cmdBand = false;
  53. bool cmdVolume = false;
  54. bool cmdAgc = false;
  55. bool cmdBandwidth = false;
  56. bool cmdStep = false;
  57. bool cmdMode = false;
  58. bool cmdMenu = false;
  59. bool cmdRds  =  false;
  60. bool cmdSoftMuteMaxAtt = false;
  61. bool cmdAvc = false;


  62. bool fmRDS = false;

  63. int16_t currentBFO = 0;
  64. long elapsedRSSI = millis();
  65. long elapsedButton = millis();
  66. long elapsedCommand = millis();
  67. long elapsedClick = millis();
  68. volatile int encoderCount = 0;
  69. uint16_t currentFrequency;
  70. uint16_t previousFrequency = 0;


  71. const uint8_t currentBFOStep = 10;

  72. const char * menu[] = {"Volume", "FM RDS", "Step", "Mode", "BFO", "BW", "AGC/Att", "SoftMute", "AVC", "Seek Up", "Seek Down"};
  73. int8_t menuIdx = 0;
  74. const int lastMenu = 10;
  75. int8_t currentMenuCmd = -1;

  76. typedef struct
  77. {
  78.   uint8_t idx;      // SI473X设备带宽指数
  79.   const char *desc; //带宽描述
  80. } Bandwidth;

  81. int8_t bwIdxSSB = 4;
  82. const int8_t maxSsbBw = 5;
  83. Bandwidth bandwidthSSB[] = {
  84.   {4, "0.5"},
  85.   {5, "1.0"},
  86.   {0, "1.2"},
  87.   {1, "2.2"},
  88.   {2, "3.0"},
  89.   {3, "4.0"}
  90. };


  91. int8_t bwIdxAM = 4;
  92. const int8_t maxAmBw = 6;
  93. Bandwidth bandwidthAM[] = {
  94.   {4, "1.0"},
  95.   {5, "1.8"},
  96.   {3, "2.0"},
  97.   {6, "2.5"},
  98.   {2, "3.0"},
  99.   {1, "4.0"},
  100.   {0, "6.0"}
  101. };

  102. int8_t bwIdxFM = 0;
  103. const int8_t maxFmBw = 4;

  104. Bandwidth bandwidthFM[] = {
  105.     {0, "AUT"}, // 自动-默认值
  106.     {1, "110"}, // 强制宽(110 kHz)通道滤波器。
  107.     {2, " 84"},
  108.     {3, " 60"},
  109.     {4, " 40"}};



  110. int tabAmStep[] = {1,    // 0
  111.                    5,    // 1
  112.                    9,    // 2
  113.                    10,   // 3
  114.                    50,   // 4
  115.                    100}; // 5

  116. const int lastAmStep = (sizeof tabAmStep / sizeof(int)) - 1;
  117. int idxAmStep = 3;

  118. int tabFmStep[] = {5, 10, 20};
  119. const int lastFmStep = (sizeof tabFmStep / sizeof(int)) - 1;
  120. int idxFmStep = 1;

  121. uint16_t currentStepIdx = 1;


  122. const char *bandModeDesc[] = {"FM ", "LSB", "USB", "AM "};
  123. uint8_t currentMode = FM;

  124. /**
  125. *  Band data structure
  126. */
  127. typedef struct
  128. {
  129.   const char *bandName;   // 波段描述
  130.   uint8_t bandType;       //波段类型(FM、MW或SW)
  131.   uint16_t minimumFreq;   // 频带的最小频率
  132.   uint16_t maximumFreq;   // 频带的最大频率
  133.   uint16_t currentFreq;   // 默认频率或当前频率
  134.   int8_t currentStepIdx;  // tabStepAM的Idex:Defeult频率阶跃(参见tabStepAM)
  135.   int8_t bandwidthIdx;    // 表带宽FM、带宽AM或带宽SSB的索引;
  136.   uint8_t disableAgc;
  137.   int8_t agcIdx;
  138.   int8_t agcNdx;
  139.   int8_t avcIdx;
  140. } Band;

  141. /*
  142.   乐队桌
  143. 您可以配置自己的乐队计划。以评论为指导。
  144. 要添加新的标注栏,只需在下表中插入一行即可。不需要额外的代码。
  145. 如果不需要给定的标注栏,可以通过删除一行来删除标注栏。
  146. 此外,还可以更改标注栏的参数。
  147. 注意:在添加或删除此表的一行后,必须重置eeprom。
  148. 在第一次按下编码器按钮时打开接收器,以重置eeprom内容。
  149. */
  150. Band band[] = {
  151.     {"VHF", FM_BAND_TYPE, 6400, 10800, 10390, 1, 0, 1, 0, 0, 0},
  152.     {"MW1", MW_BAND_TYPE, 150, 1720, 810, 3, 4, 0, 0, 0, 32},
  153.     {"MW2", MW_BAND_TYPE, 531, 1701, 783, 2, 4, 0, 0, 0, 32},
  154.     {"MW3", MW_BAND_TYPE, 1700, 3500, 2500, 1, 4, 1, 0, 0, 32},
  155.     {"80M", MW_BAND_TYPE, 3500, 4000, 3700, 0, 4, 1, 0, 0, 32},
  156.     {"SW1", SW_BAND_TYPE, 4000, 5500, 4885, 1, 4, 1, 0, 0, 32},
  157.     {"SW2", SW_BAND_TYPE, 5500, 6500, 6000, 1, 4, 1, 0, 0, 32},
  158.     {"40M", SW_BAND_TYPE, 6500, 7300, 7100, 0, 4, 1, 0, 0, 40},
  159.     {"SW3", SW_BAND_TYPE, 7200, 8000, 7200, 1, 4, 1, 0, 0, 40},
  160.     {"SW4", SW_BAND_TYPE, 9000, 11000, 9500, 1, 4, 1, 0, 0, 40},
  161.     {"SW5", SW_BAND_TYPE, 11100, 13000, 11900, 1, 4, 1, 0, 0, 40},
  162.     {"SW6", SW_BAND_TYPE, 13000, 14000, 13500, 1, 4, 1, 0, 0, 40},
  163.     {"20M", SW_BAND_TYPE, 14000, 15000, 14200, 0, 4, 1, 0, 0, 42},
  164.     {"SW7", SW_BAND_TYPE, 15000, 17000, 15300, 1, 4, 1, 0, 0, 42},
  165.     {"SW8", SW_BAND_TYPE, 17000, 18000, 17500, 1, 4, 1, 0, 0, 42},
  166.     {"15M", SW_BAND_TYPE, 20000, 21400, 21100, 0, 4, 1, 0, 0, 44},
  167.     {"SW9", SW_BAND_TYPE, 21400, 22800, 21500, 1, 4, 1, 0, 0, 44},
  168.     {"CB ", SW_BAND_TYPE, 26000, 28000, 27500, 0, 4, 1, 0, 0, 44},
  169.     {"10M", SW_BAND_TYPE, 28000, 30000, 28400, 0, 4, 1, 0, 0, 44},
  170.     {"ALL", SW_BAND_TYPE, 150, 30000, 15000, 0, 4, 1, 0, 0, 48} //所有乐队。LW、MW和SW(从150kHz到30MHz)
  171. };

  172. const int lastBand = (sizeof band / sizeof(Band)) - 1;
  173. int bandIdx = 0;
  174. int tabStep[] = {1, 5, 10, 50, 100, 500, 1000};
  175. const int lastStep = (sizeof tabStep / sizeof(int)) - 1;


  176. uint8_t rssi = 0;
  177. uint8_t volume = DEFAULT_VOLUME;

  178. // 设备类声明
  179. Rotary encoder = Rotary(ENCODER_PIN_A, ENCODER_PIN_B);

  180. LiquidCrystal lcd(LCD_RS, LCD_E, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
  181. SI4735 rx;

  182. //以下背光控制
  183. uint32_t ptime=0;
  184. void abc() {
  185. digitalWrite(8,HIGH);
  186. ptime= millis();
  187. }

  188. //以上背光控制


  189. void setup()
  190. {
  191.   // 编码器引脚
  192.   pinMode(ENCODER_PUSH_BUTTON, INPUT_PULLUP);
  193.   pinMode(ENCODER_PIN_A, INPUT_PULLUP);
  194.   pinMode(ENCODER_PIN_B, INPUT_PULLUP);
  195.   lcd.begin(16, 2);

  196. //以下背光控制

  197.   attachInterrupt(0, abc, CHANGE );
  198.   pinMode(8 ,OUTPUT);
  199.   digitalWrite(8,LOW);

  200. //以上背光控制



  201.   // 飞溅-删除或更改飞溅信息
  202.   lcd.setCursor(3, 0);//显示器光标,原为0,0
  203.   lcd.print("SI4732A10");//打印("SI4732A10")原为“PU2CLR-SI4735”
  204.   lcd.setCursor(0, 1);
  205.   lcd.print("Arduino Library");
  206.   Flash(1000);
  207.   lcd.setCursor(0, 0);
  208.   lcd.print("DIY Mirko Radio");
  209.   lcd.setCursor(0, 1);
  210.   lcd.print("By RICARDO/2021");
  211.   Flash(1000);
  212.   //末端飞溅

  213.   EEPROM.begin();

  214.   // 如果要重置eeprom,请在启动过程中按住音量上升按钮
  215.   if (digitalRead(ENCODER_PUSH_BUTTON) == LOW)
  216.   {
  217.     EEPROM.update(eeprom_address, 0);
  218.     lcd.setCursor(0,0);
  219.     lcd.print("EEPROM RESETED");
  220.     delay(2000);
  221.     lcd.clear();
  222.   }

  223.   // 通过中断控制编码器
  224.   attachInterrupt(digitalPinToInterrupt(ENCODER_PIN_A), rotaryEncoder, CHANGE);
  225.   attachInterrupt(digitalPinToInterrupt(ENCODER_PIN_B), rotaryEncoder, CHANGE);

  226.   rx.setI2CFastModeCustom(100000);
  227.   
  228.   rx.getDeviceI2CAddress(RESET_PIN); //查找并设置I2C总线地址。如果出现错误,则返回0
  229.   
  230.   rx.setup(RESET_PIN, MW_BAND_TYPE);
  231.   // 如果使用外部参考时钟(有源晶体或信号发生器),请注释上面的行,并取消注释下面的三行
  232.   // rx.setRefClock(32768);
  233.   // rx.setRefClockPrescaler(1);   // will work with 32768  
  234.   // rx.setup(RESET_PIN, 0, MW_BAND_TYPE, SI473X_ANALOG_AUDIO, XOSCEN_RCLK);

  235.   
  236.   delay(300);
  237.   rx.setAvcAmMaxGain(48); // 设置AM/SSB模式下自动音量控制的最大增益(可以使用12到90dB之间的值)。




  238.   // 检查EEPROM内容
  239.   if (EEPROM.read(eeprom_address) == app_id)
  240.   {
  241.     readAllReceiverInformation();
  242.   } else
  243.     rx.setVolume(volume);
  244.   
  245.   useBand();
  246.   showStatus();
  247. }

  248. /**
  249. *  用视觉效果清洁屏幕。
  250. */
  251. void Flash(int d)
  252. {
  253.   delay(d);
  254.   lcd.clear();
  255.   lcd.noDisplay();
  256.   delay(500);
  257.   lcd.display();
  258. }

  259. /*
  260.   将当前接收器信息写入eeprom。
  261. EEPROM。更新避免在同一内存位置写入相同的数据。这样可以节省不必要的录音。
  262. */
  263. void saveAllReceiverInformation()
  264. {
  265.   int addr_offset;

  266.   EEPROM.begin();

  267.   EEPROM.update(eeprom_address, app_id);                 // 存储应用程序id;
  268.   EEPROM.update(eeprom_address + 1, rx.getVolume()); // 存储当前卷
  269.   EEPROM.update(eeprom_address + 2, bandIdx);            // 存储当前波段
  270.   EEPROM.update(eeprom_address + 3, fmRDS);
  271.   EEPROM.update(eeprom_address + 4, currentMode); // 存储当前模式(FM/AM/SSB)
  272.   EEPROM.update(eeprom_address + 5, currentBFO >> 8);
  273.   EEPROM.update(eeprom_address + 6, currentBFO & 0XFF);

  274.   addr_offset = 7;
  275.   band[bandIdx].currentFreq = currentFrequency;

  276.   for (int i = 0; i <= lastBand; i++)
  277.   {
  278.     EEPROM.update(addr_offset++, (band[i].currentFreq >> 8));   // 存储频带的当前频率高字节
  279.     EEPROM.update(addr_offset++, (band[i].currentFreq & 0xFF)); // 存储频带的当前频率低字节
  280.     EEPROM.update(addr_offset++, band[i].currentStepIdx);       // 存储频带的当前步长
  281.     EEPROM.update(addr_offset++, band[i].bandwidthIdx);         // 表带宽索引(直接位置)
  282.     EEPROM.update(addr_offset++, band[i].disableAgc );
  283.     EEPROM.update(addr_offset++, band[i].agcIdx);
  284.     EEPROM.update(addr_offset++, band[i].agcNdx);
  285.     EEPROM.update(addr_offset++, band[i].avcIdx);

  286.   }

  287.   EEPROM.end();
  288. }

  289. /**
  290. * 从eeprom读取最后一个接收器状态。
  291. */
  292. void readAllReceiverInformation()
  293. {
  294.   uint8_t volume;
  295.   int addr_offset;
  296.   int bwIdx;

  297.   volume = EEPROM.read(eeprom_address + 1); //获取存储的卷;
  298.   bandIdx = EEPROM.read(eeprom_address + 2);
  299.   fmRDS = EEPROM.read(eeprom_address + 3);
  300.   currentMode = EEPROM.read(eeprom_address + 4);
  301.   currentBFO = EEPROM.read(eeprom_address + 5) << 8;
  302.   currentBFO |= EEPROM.read(eeprom_address + 6);

  303.   addr_offset = 7;
  304.   for (int i = 0; i <= lastBand; i++)
  305.   {
  306.     band[i].currentFreq = EEPROM.read(addr_offset++) << 8;
  307.     band[i].currentFreq |= EEPROM.read(addr_offset++);
  308.     band[i].currentStepIdx = EEPROM.read(addr_offset++);
  309.     band[i].bandwidthIdx = EEPROM.read(addr_offset++);
  310.     band[i].disableAgc = EEPROM.read(addr_offset++);
  311.     band[i].agcIdx = EEPROM.read(addr_offset++);
  312.     band[i].agcNdx = EEPROM.read(addr_offset++);
  313.     band[i].avcIdx = EEPROM.read(addr_offset++);
  314.   }


  315.   currentFrequency = band[bandIdx].currentFreq;

  316.   if (band[bandIdx].bandType == FM_BAND_TYPE)
  317.   {
  318.     currentStepIdx = idxFmStep = band[bandIdx].currentStepIdx;
  319.     rx.setFrequencyStep(tabFmStep[currentStepIdx]);
  320.   }
  321.   else
  322.   {
  323.     currentStepIdx = idxAmStep = band[bandIdx].currentStepIdx;
  324.     rx.setFrequencyStep(tabAmStep[currentStepIdx]);
  325.   }

  326.   bwIdx = band[bandIdx].bandwidthIdx;

  327.   if (currentMode == LSB || currentMode == USB)
  328.   {
  329.     loadSSB();
  330.     bwIdxSSB = (bwIdx > 5) ? 5 : bwIdx;
  331.     rx.setSSBAudioBandwidth(bandwidthSSB[bwIdxSSB].idx);
  332.     //如果选择的音频带宽约为2 kHz或以下,建议将边带截止滤波器设置为0。
  333.     if (bandwidthSSB[bwIdxSSB].idx == 0 || bandwidthSSB[bwIdxSSB].idx == 4 || bandwidthSSB[bwIdxSSB].idx == 5)
  334.       rx.setSBBSidebandCutoffFilter(0);
  335.     else
  336.       rx.setSBBSidebandCutoffFilter(1);
  337.   }
  338.   else if (currentMode == AM)
  339.   {
  340.     bwIdxAM = bwIdx;
  341.     rx.setBandwidth(bandwidthAM[bwIdxAM].idx, 1);
  342.   }
  343.   else
  344.   {
  345.     bwIdxFM = bwIdx;
  346.     rx.setFmBandwidth(bandwidthFM[bwIdxFM].idx);
  347.   }

  348.   delay(50);
  349.   rx.setVolume(volume);
  350. }

  351. /*
  352. * 要将任何更改存储到EEPROM中,至少需要存储毫秒的不活动时间。
  353. */
  354. void resetEepromDelay()
  355. {
  356.   elapsedCommand = storeTime = millis();
  357.   itIsTimeToSave = true;
  358. }

  359. /**
  360.     将所有命令标志设置为false
  361. 当禁用所有标志(false)时,编码器控制频率
  362. */
  363. void disableCommands()
  364. {
  365.   cmdBand = false;
  366.   bfoOn = false;
  367.   cmdVolume = false;
  368.   cmdAgc = false;
  369.   cmdBandwidth = false;
  370.   cmdStep = false;
  371.   cmdMode = false;
  372.   cmdMenu = false;
  373.   cmdSoftMuteMaxAtt = false;
  374.   cmdRds = false;
  375.   cmdAvc =  false;
  376.   countClick = 0;

  377.   showCommandStatus((char *) "VFO ");
  378. }



  379. /**
  380. *通过中断读取编码器
  381. *使用旋转。h和扶轮社。通过中断处理编码器的cpp实现
  382. * if you do not add ICACHE_RAM_ATTR declaration, the system will reboot during attachInterrupt call.
  383. * With ICACHE_RAM_ATTR macro you put the function on the RAM.
  384. */
  385. void  rotaryEncoder()
  386. { // 旋转编码器事件
  387.   uint8_t encoderStatus = encoder.process();
  388.   if (encoderStatus)//如果编码器状态
  389.     encoderCount = (encoderStatus == DIR_CW) ? 1 : -1;//编码器计数=(编码器状态==DIR_CW)?1 : -1;
  390. }

  391. /**
  392. * 在显示屏上显示频率信息
  393. */
  394. void showFrequency()
  395. {
  396.   char tmp[15];
  397.   char bufferDisplay[15];
  398.   char *unit;
  399.   int col = 4;
  400.   sprintf(tmp, "%5.5u", currentFrequency);
  401.   bufferDisplay[0] = (tmp[0] == '0') ? ' ' : tmp[0];
  402.   bufferDisplay[1] = tmp[1];
  403.   if (rx.isCurrentTuneFM())
  404.   {
  405.     bufferDisplay[2] = tmp[2];
  406.     bufferDisplay[3] = '.';
  407.     bufferDisplay[4] = tmp[3];
  408.     if ( fmRDS ) {
  409.       col = 0;
  410.       unit = (char *)" ";
  411.     } else {
  412.       unit = (char *)"MHz";
  413.     }
  414.   }
  415.   else
  416.   {
  417.     if (currentFrequency < 1000)
  418.     {
  419.       bufferDisplay[1] = ' ';
  420.       bufferDisplay[2] = tmp[2];
  421.       bufferDisplay[3] = tmp[3];
  422.       bufferDisplay[4] = tmp[4];
  423.     }
  424.     else
  425.     {
  426.       bufferDisplay[2] = tmp[2];
  427.       bufferDisplay[3] = tmp[3];
  428.       bufferDisplay[4] = tmp[4];
  429.     }
  430.     unit = (char *)"kHz";
  431.   }
  432.   bufferDisplay[5] = '\0';
  433.   strcat(bufferDisplay, unit);
  434.   lcd.setCursor(col, 1);
  435.   lcd.print(bufferDisplay);
  436.   showMode();
  437. }

  438. /**
  439. * 显示当前模式
  440. */
  441. void showMode()
  442. {
  443.   char *bandMode;

  444.    
  445.   if (currentFrequency < 520)
  446.     bandMode = (char *)"LW  ";
  447.   else
  448.     bandMode = (char *)bandModeDesc[currentMode];
  449.   lcd.setCursor(0, 0);
  450.   lcd.print(bandMode);

  451.   if ( currentMode == FM && fmRDS ) return;
  452.   
  453.   lcd.setCursor(0, 1);
  454.   lcd.print(band[bandIdx].bandName);
  455. }

  456. /**
  457. * 在显示屏上显示一些基本信息
  458. */
  459. void showStatus()
  460. {
  461.   lcd.clear();
  462.   showFrequency();
  463.   showRSSI();
  464. }

  465. /**
  466. *  显示当前带宽状态
  467. */
  468. void showBandwidth()
  469. {
  470.   char *bw;
  471.   char bandwidth[20];
  472.   if (currentMode == LSB || currentMode == USB)
  473.   {
  474.     bw = (char *)bandwidthSSB[bwIdxSSB].desc;
  475.     showBFO();
  476.   }
  477.   else if (currentMode == AM)
  478.   {
  479.     bw = (char *)bandwidthAM[bwIdxAM].desc;
  480.   }
  481.   else
  482.   {
  483.     bw = (char *)bandwidthFM[bwIdxFM].desc;
  484.   }

  485.   sprintf(bandwidth, "BW: %s", bw);
  486.   lcd.clear();
  487.   lcd.setCursor(0, 0);
  488.   lcd.print(bandwidth);
  489. }

  490. /**
  491. *  显示当前的RSSI和SNR状态
  492. */
  493. void showRSSI()
  494. {
  495.   int rssiAux = 0;
  496.   char sMeter[7];

  497.   if (currentMode == FM)
  498.   {
  499.     lcd.setCursor(14, 0);
  500.     lcd.print((rx.getCurrentPilot()) ? "ST" : "MO");
  501.     lcd.setCursor(10, 0);
  502.     if ( fmRDS ) {
  503.       lcd.print("RDS");
  504.       return;
  505.     }
  506.     else
  507.       lcd.print("   ");
  508.   }

  509.    
  510.   if (rssi < 2)
  511.     rssiAux = 4;
  512.   else if (rssi < 4)
  513.     rssiAux = 5;
  514.   else if (rssi < 12)
  515.     rssiAux = 6;
  516.   else if (rssi < 25)
  517.     rssiAux = 7;
  518.   else if (rssi < 50)
  519.     rssiAux = 8;
  520.   else
  521.     rssiAux = 9;

  522.   sprintf(sMeter, "S%1.1u%c", rssiAux, (rssi >= 60) ? '+' : '.');
  523.   lcd.setCursor(13, 1);
  524.   lcd.print(sMeter);
  525. }

  526. /**
  527. *    显示当前AGC和衰减状态
  528. */
  529. void showAgcAtt()
  530. {
  531.   char sAgc[15];
  532.   lcd.clear();
  533.   rx.getAutomaticGainControl();
  534.   if ( !disableAgc /*agcNdx == 0 && agcIdx == 0 */ )
  535.     strcpy(sAgc, "AGC ON");
  536.   else
  537.     sprintf(sAgc, "ATT: %2.2d", agcNdx);

  538.   lcd.setCursor(0, 0);
  539.   lcd.print(sAgc);
  540. }


  541. /**
  542. *  显示当前步骤
  543. */
  544. void showStep()
  545. {
  546.   char sStep[15];

  547.   sprintf(sStep, "Stp:%4d", (currentMode == FM)? (tabFmStep[currentStepIdx] *10) : tabAmStep[currentStepIdx] );
  548.   lcd.setCursor(0, 0);
  549.   lcd.print(sStep);
  550. }

  551. /**
  552. *  显示当前BFO值
  553. */
  554. void showBFO()
  555. {
  556.   char bfo[15];
  557.   if (currentBFO > 0)
  558.     sprintf(bfo, "BFO:+%4.4d", currentBFO);
  559.   else
  560.     sprintf(bfo, "BFO:%4.4d", currentBFO);

  561.   lcd.clear();
  562.   lcd.setCursor(0, 0);
  563.   lcd.print(bfo);
  564.   elapsedCommand = millis();
  565. }

  566. /*
  567. * 在LCD上显示音量
  568. */
  569. void showVolume()
  570. {
  571.   char volAux[12];
  572.   sprintf(volAux, "VOLUME: %2u", rx.getVolume());
  573.   lcd.clear();
  574.   lcd.setCursor(0, 0);
  575.   lcd.print(volAux);
  576. }

  577. /**
  578. * 显示柔和的静音
  579. */
  580. void showSoftMute()
  581. {
  582.   char sMute[18];
  583.   sprintf(sMute, "Soft Mute: %2d", softMuteMaxAttIdx);
  584.   lcd.clear();
  585.   lcd.setCursor(0, 0);
  586.   lcd.print(sMute);
  587. }


  588. /**
  589. * Show Soft Mute
  590. */
  591. void showAvc()
  592. {
  593.   char sAvc[18];
  594.   sprintf(sAvc, "AVC: %2d", avcIdx);
  595.   lcd.clear();
  596.   lcd.setCursor(0, 0);
  597.   lcd.print(sAvc);
  598. }



  599. /**
  600. * 显示RDS开或关
  601. */
  602. void showRdsSetup()
  603. {
  604.   char sRdsStatus[10];
  605.   sprintf(sRdsStatus, "RDS: %s", (fmRDS)? "ON ": "OFF");
  606.   lcd.clear();
  607.   lcd.setCursor(0, 0);
  608.   lcd.print(sRdsStatus);  

  609. }

  610. /***************  
  611. *   RDS
  612. *   
  613. */

  614. char *stationName;
  615. char bufferStatioName[20];

  616. void clearRDS() {
  617.    stationName = (char *) "           ";
  618.    showRDSStation();
  619. }

  620. void showRDSStation()
  621. {
  622.     int col = 8;
  623.     for (int i = 0; i < 8; i++ ) {
  624.       if (stationName[i] != bufferStatioName[i] ) {
  625.         lcd.setCursor(col + i, 1);
  626.         lcd.print(stationName[i]);
  627.         bufferStatioName[i] = stationName[i];
  628.       }
  629.     }
  630.    
  631.     delay(100);
  632. }


  633. /*
  634. * 检查电台名称是否可用
  635. */
  636. void checkRDS()
  637. {
  638.   rx.getRdsStatus();
  639.   if (rx.getRdsReceived())
  640.   {
  641.     if (rx.getRdsSync() && rx.getRdsSyncFound() && !rx.getRdsSyncLost() && !rx.getGroupLost() )
  642.     {
  643.       stationName = rx.getRdsText0A();
  644.       if (stationName != NULL )
  645.       {
  646.         showRDSStation();
  647.       }
  648.     }
  649.   }
  650. }


  651. /**
  652. *   设置波段向上(1)或向下(!1)
  653. */
  654. void setBand(int8_t up_down)
  655. {
  656.   band[bandIdx].currentFreq = currentFrequency;
  657.   band[bandIdx].currentStepIdx = currentStepIdx;
  658.   if (up_down == 1)
  659.     bandIdx = (bandIdx < lastBand) ? (bandIdx + 1) : 0;
  660.   else
  661.     bandIdx = (bandIdx > 0) ? (bandIdx - 1) : lastBand;
  662.   useBand();
  663.   delay(MIN_ELAPSED_TIME); // 再等一会儿,等待释放按钮。
  664. }

  665. /**
  666. * 将收音机切换到当前波段
  667. */
  668. void useBand()
  669. {
  670.   if (band[bandIdx].bandType == FM_BAND_TYPE)
  671.   {
  672.     currentMode = FM;
  673.     rx.setTuneFrequencyAntennaCapacitor(0);
  674.     rx.setFM(band[bandIdx].minimumFreq, band[bandIdx].maximumFreq, band[bandIdx].currentFreq, tabFmStep[band[bandIdx].currentStepIdx]);
  675.     rx.setSeekFmLimits(band[bandIdx].minimumFreq, band[bandIdx].maximumFreq);
  676.     rx.setRdsConfig(1, 2, 2, 2, 2);
  677.     rx.setFifoCount(1);
  678.    
  679.     bfoOn = ssbLoaded = false;
  680.     bwIdxFM = band[bandIdx].bandwidthIdx;
  681.     rx.setFmBandwidth(bandwidthFM[bwIdxFM].idx);   
  682.   }
  683.   else
  684.   {

  685.     disableAgc = band[bandIdx].disableAgc;
  686.     agcIdx = band[bandIdx].agcIdx;
  687.     agcNdx = band[bandIdx].agcNdx;
  688.     avcIdx = band[bandIdx].avcIdx;
  689.    
  690.     // set the tuning capacitor for SW or MW/LW
  691.     rx.setTuneFrequencyAntennaCapacitor((band[bandIdx].bandType == MW_BAND_TYPE || band[bandIdx].bandType == LW_BAND_TYPE) ? 0 : 1);
  692.     if (ssbLoaded)
  693.     {
  694.       rx.setSSB(band[bandIdx].minimumFreq, band[bandIdx].maximumFreq, band[bandIdx].currentFreq, tabAmStep[band[bandIdx].currentStepIdx], currentMode);
  695.       rx.setSSBAutomaticVolumeControl(1);
  696.       rx.setSsbSoftMuteMaxAttenuation(softMuteMaxAttIdx); // Disable Soft Mute for SSB
  697.       bwIdxSSB = band[bandIdx].bandwidthIdx;
  698.       rx.setSSBAudioBandwidth(bandwidthSSB[bwIdxSSB].idx);
  699.       delay(500);
  700.       rx.setSsbAgcOverrite(disableAgc, agcNdx);
  701.     }
  702.     else
  703.     {
  704.       currentMode = AM;
  705.       rx.setAM(band[bandIdx].minimumFreq, band[bandIdx].maximumFreq, band[bandIdx].currentFreq, tabAmStep[band[bandIdx].currentStepIdx]);
  706.       bfoOn = false;
  707.       bwIdxAM = band[bandIdx].bandwidthIdx;
  708.       rx.setBandwidth(bandwidthAM[bwIdxAM].idx, 1);
  709.       rx.setAmSoftMuteMaxAttenuation(softMuteMaxAttIdx); // Soft Mute for AM or SSB
  710.       rx.setAutomaticGainControl(disableAgc, agcNdx);

  711.     }
  712.     rx.setSeekAmLimits(band[bandIdx].minimumFreq, band[bandIdx].maximumFreq); // Consider the range all defined current band
  713.     rx.setSeekAmSpacing(5); // Max 10kHz for spacing
  714.     rx.setAvcAmMaxGain(avcIdx);
  715.   }
  716.   delay(100);
  717.   currentFrequency = band[bandIdx].currentFreq;
  718.   currentStepIdx = band[bandIdx].currentStepIdx;

  719.   rssi = 0;
  720.   showStatus();
  721.   showCommandStatus((char *) "Band");
  722. }


  723. void loadSSB() {
  724.    rx.setI2CFastModeCustom(400000); // You can try rx.setI2CFastModeCustom(700000); or greater value
  725.    rx.loadPatch(ssb_patch_content, size_content, bandwidthSSB[bwIdxSSB].idx);
  726.    rx.setI2CFastModeCustom(100000);  
  727.    ssbLoaded =  true;
  728. }

  729. /**
  730. * 切换带宽
  731. */
  732. void doBandwidth(int8_t v)
  733. {
  734.     if (currentMode == LSB || currentMode == USB)
  735.     {
  736.       bwIdxSSB = (v == 1) ? bwIdxSSB + 1 : bwIdxSSB - 1;

  737.       if (bwIdxSSB > maxSsbBw)
  738.         bwIdxSSB = 0;
  739.       else if (bwIdxSSB < 0)
  740.         bwIdxSSB = maxSsbBw;

  741.       rx.setSSBAudioBandwidth(bandwidthSSB[bwIdxSSB].idx);
  742.       // If audio bandwidth selected is about 2 kHz or below, it is recommended to set Sideband Cutoff Filter to 0.
  743.       if (bandwidthSSB[bwIdxSSB].idx == 0 || bandwidthSSB[bwIdxSSB].idx == 4 || bandwidthSSB[bwIdxSSB].idx == 5)
  744.         rx.setSBBSidebandCutoffFilter(0);
  745.       else
  746.         rx.setSBBSidebandCutoffFilter(1);

  747.       band[bandIdx].bandwidthIdx = bwIdxSSB;
  748.     }
  749.     else if (currentMode == AM)
  750.     {
  751.       bwIdxAM = (v == 1) ? bwIdxAM + 1 : bwIdxAM - 1;

  752.       if (bwIdxAM > maxAmBw)
  753.         bwIdxAM = 0;
  754.       else if (bwIdxAM < 0)
  755.         bwIdxAM = maxAmBw;

  756.       rx.setBandwidth(bandwidthAM[bwIdxAM].idx, 1);
  757.       band[bandIdx].bandwidthIdx = bwIdxAM;
  758.       
  759.     } else {
  760.     bwIdxFM = (v == 1) ? bwIdxFM + 1 : bwIdxFM - 1;
  761.     if (bwIdxFM > maxFmBw)
  762.       bwIdxFM = 0;
  763.     else if (bwIdxFM < 0)
  764.       bwIdxFM = maxFmBw;

  765.     rx.setFmBandwidth(bandwidthFM[bwIdxFM].idx);
  766.     band[bandIdx].bandwidthIdx = bwIdxFM;
  767.   }
  768.   showBandwidth();
  769.   delay(MIN_ELAPSED_TIME); // waits a little more for releasing the button.
  770. }

  771. /**
  772. * 在显示屏上显示cmd。这意味着你在设置一些东西。
  773. */
  774. void showCommandStatus(char * currentCmd)
  775. {
  776.   lcd.setCursor(5, 0);
  777.   lcd.print(currentCmd);
  778. }

  779. /**
  780. * Show menu options
  781. */
  782. void showMenu() {
  783.   lcd.clear();
  784.   lcd.setCursor(0, 0);
  785.   lcd.setCursor(0, 1);
  786.   lcd.print(menu[menuIdx]);
  787.   showCommandStatus( (char *) "Menu");
  788. }

  789. /**
  790. *  AGC和衰减设置
  791. */
  792. void doAgc(int8_t v) {
  793.   agcIdx = (v == 1) ? agcIdx + 1 : agcIdx - 1;
  794.   if (agcIdx < 0 )
  795.     agcIdx = 37;
  796.   else if ( agcIdx > 37)
  797.     agcIdx = 0;
  798.   disableAgc = (agcIdx > 0); // if true, disable AGC; esle, AGC is enable
  799.   if (agcIdx > 1)
  800.     agcNdx = agcIdx - 1;
  801.   else
  802.     agcNdx = 0;
  803.   if ( currentMode == AM )
  804.      rx.setAutomaticGainControl(disableAgc, agcNdx); // if agcNdx = 0, no attenuation
  805.   else
  806.     rx.setSsbAgcOverrite(disableAgc, agcNdx, 0B1111111);

  807.   band[bandIdx].disableAgc = disableAgc;
  808.   band[bandIdx].agcIdx = agcIdx;
  809.   band[bandIdx].agcNdx = agcNdx;

  810.   showAgcAtt();
  811.   delay(MIN_ELAPSED_TIME); // 再等一会儿,等待释放按钮。
  812.   elapsedCommand = millis();
  813. }


  814. /**
  815. * 切换当前步骤
  816. */
  817. void doStep(int8_t v)
  818. {
  819.     if ( currentMode == FM ) {
  820.       idxFmStep = (v == 1) ? idxFmStep + 1 : idxFmStep - 1;
  821.       if (idxFmStep > lastFmStep)
  822.         idxFmStep = 0;
  823.       else if (idxFmStep < 0)
  824.         idxFmStep = lastFmStep;
  825.         
  826.       currentStepIdx = idxFmStep;
  827.       rx.setFrequencyStep(tabFmStep[currentStepIdx]);
  828.       
  829.     } else {
  830.       idxAmStep = (v == 1) ? idxAmStep + 1 : idxAmStep - 1;
  831.       if (idxAmStep > lastAmStep)
  832.         idxAmStep = 0;
  833.       else if (idxAmStep < 0)
  834.         idxAmStep = lastAmStep;

  835.       currentStepIdx = idxAmStep;
  836.       rx.setFrequencyStep(tabAmStep[currentStepIdx]);
  837.       rx.setSeekAmSpacing(5); // Max 10kHz for spacing
  838.     }
  839.     band[bandIdx].currentStepIdx = currentStepIdx;
  840.     showStep();
  841.     delay(MIN_ELAPSED_TIME); // 再等一会儿,等待释放按钮。
  842.     elapsedCommand = millis();
  843. }

  844. /**
  845. * Switches to the AM, LSB or USB modes
  846. */
  847. void doMode(int8_t v)
  848. {
  849.   if (currentMode != FM)
  850.   {
  851.     if (v == 1)  { // clockwise
  852.       if (currentMode == AM)
  853.       {
  854.         // If you were in AM mode, it is necessary to load SSB patch (avery time)
  855.         loadSSB();
  856.         ssbLoaded = true;
  857.         currentMode = LSB;
  858.       }
  859.       else if (currentMode == LSB)
  860.         currentMode = USB;
  861.       else if (currentMode == USB)
  862.       {
  863.         currentMode = AM;
  864.         bfoOn = ssbLoaded = false;
  865.       }
  866.     } else { // and counterclockwise
  867.       if (currentMode == AM)
  868.       {
  869.         // If you were in AM mode, it is necessary to load SSB patch (avery time)
  870.         loadSSB();
  871.         ssbLoaded = true;
  872.         currentMode = USB;
  873.       }
  874.       else if (currentMode == USB)
  875.         currentMode = LSB;
  876.       else if (currentMode == LSB)
  877.       {
  878.         currentMode = AM;
  879.         bfoOn = ssbLoaded = false;
  880.       }
  881.     }
  882.     // Nothing to do if you are in FM mode
  883.     band[bandIdx].currentFreq = currentFrequency;
  884.     band[bandIdx].currentStepIdx = currentStepIdx;
  885.     useBand();
  886.   }
  887.   delay(MIN_ELAPSED_TIME); // waits a little more for releasing the button.
  888.   elapsedCommand = millis();
  889. }

  890. /**
  891. * Sets the audio volume
  892. */
  893. void doVolume( int8_t v ) {
  894.   if ( v == 1)
  895.     rx.volumeUp();
  896.   else
  897.     rx.volumeDown();

  898.   showVolume();
  899.   delay(MIN_ELAPSED_TIME); // waits a little more for releasing the button.
  900. }

  901. /**
  902. *  This function is called by the seek function process.
  903. */
  904. void showFrequencySeek(uint16_t freq)
  905. {
  906.   currentFrequency = freq;
  907.   showFrequency();
  908. }

  909. /**
  910. *  Find a station. The direction is based on the last encoder move clockwise or counterclockwise
  911. */
  912. void doSeek()
  913. {
  914.   if ((currentMode == LSB || currentMode == USB)) return; // It does not work for SSB mode

  915.   lcd.clear();
  916.   rx.seekStationProgress(showFrequencySeek, seekDirection);
  917.   showStatus();
  918.   currentFrequency = rx.getFrequency();
  919.   
  920. }

  921. /**
  922. * Sets the Soft Mute Parameter
  923. */
  924. void doSoftMute(int8_t v)
  925. {
  926.   softMuteMaxAttIdx = (v == 1) ? softMuteMaxAttIdx + 1 : softMuteMaxAttIdx - 1;
  927.   if (softMuteMaxAttIdx > 32)
  928.     softMuteMaxAttIdx = 0;
  929.   else if (softMuteMaxAttIdx < 0)
  930.     softMuteMaxAttIdx = 32;

  931.   rx.setAmSoftMuteMaxAttenuation(softMuteMaxAttIdx);
  932.   showSoftMute();
  933.   elapsedCommand = millis();
  934. }


  935. /**
  936. * 设置自动音量控制的最大增益。
  937. */
  938. void doAvc(int8_t v)
  939. {
  940.   avcIdx = (v == 1) ? avcIdx + 2 : avcIdx - 2;
  941.   if (avcIdx > 90)
  942.     avcIdx = 12;
  943.   else if (avcIdx < 12)
  944.     avcIdx = 90;

  945.   rx.setAvcAmMaxGain(avcIdx);

  946.   band[bandIdx].avcIdx = avcIdx;

  947.   showAvc();
  948.   elapsedCommand = millis();
  949. }


  950. /**
  951. * 打开或关闭RDS
  952. */
  953. void doRdsSetup(int8_t v)
  954. {
  955.   fmRDS = (v == 1)? true:false;
  956.   showRdsSetup();
  957.   elapsedCommand = millis();
  958. }


  959. /**
  960. * 菜单选项选择
  961. */
  962. void doMenu( int8_t v) {
  963.   menuIdx = (v == 1) ? menuIdx + 1 : menuIdx - 1;
  964.   if (menuIdx > lastMenu)
  965.     menuIdx = 0;
  966.   else if (menuIdx < 0)
  967.     menuIdx = lastMenu;

  968.   showMenu();
  969.   delay(MIN_ELAPSED_TIME); // waits a little more for releasing the button.
  970.   elapsedCommand = millis();
  971. }



  972. /**
  973. * Return true if the current status is Menu command
  974. */
  975. bool isMenuMode() {
  976.   return (cmdMenu | cmdStep | cmdBandwidth | cmdAgc | cmdVolume | cmdSoftMuteMaxAtt | cmdMode | cmdRds | cmdAvc);
  977. }


  978. /**
  979. * 启动菜单操作过程
  980. */
  981. void doCurrentMenuCmd() {
  982.   disableCommands();
  983.   switch (currentMenuCmd) {
  984.      case 0:                 // VOLUME
  985.       cmdVolume = true;
  986.       showVolume();
  987.       break;
  988.     case 1:
  989.       cmdRds = true;
  990.       showRdsSetup();
  991.       break;
  992.     case 2:                 // STEP
  993.       cmdStep = true;
  994.       showStep();
  995.       break;
  996.     case 3:                 // MODE
  997.       cmdMode = true;
  998.       lcd.clear();
  999.       showMode();
  1000.       break;
  1001.     case 4:
  1002.         bfoOn = true;
  1003.         if ((currentMode == LSB || currentMode == USB)) {
  1004.           showBFO();
  1005.         }
  1006.       // showFrequency();
  1007.       break;      
  1008.     case 5:                 // BW
  1009.       cmdBandwidth = true;
  1010.       showBandwidth();
  1011.       break;
  1012.     case 6:                 // AGC/ATT
  1013.       cmdAgc = true;
  1014.       showAgcAtt();
  1015.       break;
  1016.     case 7:
  1017.       cmdSoftMuteMaxAtt = true;
  1018.       showSoftMute();  
  1019.       break;
  1020.     case 8:
  1021.       cmdAvc =  true;
  1022.       showAvc();
  1023.       break;  
  1024.     case 9:
  1025.       seekDirection = 1;
  1026.       doSeek();
  1027.       break;  
  1028.     case 10:
  1029.       seekDirection = 0;
  1030.       doSeek();
  1031.       break;   
  1032.     default:
  1033.       showStatus();
  1034.       break;
  1035.   }
  1036.   currentMenuCmd = -1;
  1037.   elapsedCommand = millis();
  1038. }




  1039. /**
  1040. * Main loop
  1041. */
  1042. void loop()
  1043. {

  1044. //以下背光控制

  1045. if(millis()-ptime>5000) digitalWrite(8,LOW);


  1046. //以上背光控制



  1047.   
  1048.   // 检查编码器是否移动.
  1049.   if (encoderCount != 0)
  1050.   {
  1051.     if (bfoOn & (currentMode == LSB || currentMode == USB))
  1052.     {
  1053.       currentBFO = (encoderCount == 1) ? (currentBFO + currentBFOStep) : (currentBFO - currentBFOStep);
  1054.       rx.setSSBBfo(currentBFO);
  1055.       showBFO();

  1056.   
  1057.       
  1058.     }


  1059.   
  1060.     else if (cmdMenu)
  1061.       doMenu(encoderCount);
  1062.     else if (cmdMode)
  1063.       doMode(encoderCount);
  1064.     else if (cmdStep)
  1065.       doStep(encoderCount);
  1066.     else if (cmdAgc)
  1067.       doAgc(encoderCount);
  1068.     else if (cmdBandwidth)
  1069.       doBandwidth(encoderCount);
  1070.     else if (cmdVolume)
  1071.       doVolume(encoderCount);
  1072.     else if (cmdSoftMuteMaxAtt)
  1073.       doSoftMute(encoderCount);
  1074.     else if (cmdAvc)
  1075.       doAvc(encoderCount);      
  1076.     else if (cmdBand)
  1077.       setBand(encoderCount);
  1078.     else if (cmdRds )
  1079.       doRdsSetup(encoderCount);  
  1080.     else
  1081.     {
  1082.       if (encoderCount == 1)
  1083.       {
  1084.      
  1085.         rx.frequencyUp();
  1086.       }
  1087.       else
  1088.       {
  1089.         rx.frequencyDown();
  1090.       }
  1091.       // 仅当当前频率发生变化时才显示
  1092.       currentFrequency = rx.getFrequency();
  1093.       showFrequency();
  1094.     }
  1095.     encoderCount = 0;
  1096.     resetEepromDelay();
  1097.   }
  1098.   else
  1099.   {
  1100.     if (digitalRead(ENCODER_PUSH_BUTTON) == LOW)
  1101.     {





  1102.       
  1103.       countClick++;
  1104.       if (cmdMenu)
  1105.       {
  1106.         currentMenuCmd = menuIdx;
  1107.         doCurrentMenuCmd();
  1108.       }
  1109.       else if (countClick == 1)
  1110.       { // 只要点击一下,你就可以通过旋转编码器来选择波段
  1111.         if (isMenuMode())
  1112.         {
  1113.           disableCommands();
  1114.           showStatus();
  1115.           showCommandStatus((char *)"VFO ");
  1116.         }
  1117.         else if ( bfoOn ) {
  1118.           bfoOn = false;
  1119.           showStatus();
  1120.         }
  1121.         else
  1122.         {
  1123.           cmdBand = !cmdBand;
  1124.           showCommandStatus((char *)"Band");
  1125.         }
  1126.       }
  1127.       else
  1128.       { // 如果在1/2秒内点击超过一次,请转到菜单。
  1129.         cmdMenu = !cmdMenu;
  1130.         if (cmdMenu)
  1131.           showMenu();
  1132.       }
  1133.       delay(MIN_ELAPSED_TIME);
  1134.       elapsedCommand = millis();
  1135.     }
  1136.   }

  1137.   // 仅当此条件发生变化时才显示RSSI状态
  1138.   if ((millis() - elapsedRSSI) > MIN_ELAPSED_RSSI_TIME * 6)
  1139.   {
  1140.     rx.getCurrentReceivedSignalQuality();
  1141.     int aux = rx.getCurrentRSSI();
  1142.     if (rssi != aux && !isMenuMode())
  1143.     {
  1144.       rssi = aux;
  1145.       showRSSI();
  1146.     }
  1147.     elapsedRSSI = millis();
  1148.   }

  1149.   // Disable commands control
  1150.   if ((millis() - elapsedCommand) > ELAPSED_COMMAND)
  1151.   {
  1152.     if ((currentMode == LSB || currentMode == USB) )
  1153.     {
  1154.       bfoOn = false;
  1155.       // showBFO();
  1156.       showStatus();
  1157.     } else if (isMenuMode())
  1158.       showStatus();
  1159.     disableCommands();
  1160.     elapsedCommand = millis();
  1161.   }

  1162.   if ((millis() - elapsedClick) > ELAPSED_CLICK)
  1163.   {
  1164.     countClick = 0;
  1165.     elapsedClick = millis();
  1166.   }

  1167.   // 仅当当前频率发生变化时才显示
  1168.   if (itIsTimeToSave)
  1169.   {
  1170.     if ((millis() - storeTime) > STORE_TIME)
  1171.     {
  1172.       saveAllReceiverInformation();
  1173.       storeTime = millis();
  1174.       itIsTimeToSave = false;
  1175.     }
  1176.   }

  1177.   if (currentMode == FM && fmRDS && !isMenuMode() )
  1178.   {
  1179.       if (currentFrequency != previousFrequency)
  1180.       {
  1181.         clearRDS();
  1182.         previousFrequency = currentFrequency;
  1183.        }
  1184.       else
  1185.       {
  1186.         checkRDS();
  1187.       }
  1188.   }  

  1189.   delay(2);
  1190. }
复制代码
发表于 2022-3-17 20:20 | 显示全部楼层
xgm1818 发表于 2022-3-17 19:11
谢谢!我将您的程序单独上传,拧动编码器后能正常点亮1602背光,偶尔有时候要较长时间熄灭,用万用表电压 ...

时间是最后停止旋转编码器后延时5秒,若在5秒之内又旋转编码器会再加5秒的。#define ENCODER_PIN_A 2要改为#define ENCODER_PIN_A 10(其它未用的端口),再将10与2用导线连起来。
 楼主| 发表于 2022-3-17 21:49 | 显示全部楼层
本帖最后由 xgm1818 于 2022-3-17 21:56 编辑

我把2改成了10,再将2与10导线连接,拧编码器背光正常点亮,比刚才稳定了,而且能正常熄灭,不过拧编码器的同时(调整频率),不灵敏了,例如,原先是编码器拧一小格频率增加或减少0.1MHZ,现在编码器快速拧一圈左右频率增加或减少0.2MHZ,如果拧的慢的话还没应;
3333.png
发表于 2022-3-22 06:05 | 显示全部楼层
xgm1818 发表于 2022-3-17 21:49
我把2改成了10,再将2与10导线连接,拧编码器背光正常点亮,比刚才稳定了,而且能正常熄灭,不过拧编码器的 ...

你没直接给我回复,是我搜回复才看到你的贴子。你将2与10导线断开。看编码器工作是否正常,
发表于 2022-3-23 07:03 | 显示全部楼层
xgm1818 发表于 2022-3-17 21:49
我把2改成了10,再将2与10导线连接,拧编码器背光正常点亮,比刚才稳定了,而且能正常熄灭,不过拧编码器的 ...

你的程序太大所以没仔细看,现在发现你的编码器原程序就是用的中断来调频率。那就不要改端口了。在你原有的中断程序中添加:
void  rotaryEncoder()
{ // 旋转编码器事件
  uint8_t encoderStatus = encoder.process();
  if (encoderStatus)//如果编码器状态
    encoderCount = (encoderStatus == DIR_CW) ? 1 : -1;//编码器计数=(编码器状态==DIR_CW)?1 : -1;
digitalWrite(8,HIGH);
ptime= millis();
}
主程序添加if(millis()-ptime>5000) digitalWrite(8,LOW);
这样应该可以了。
 楼主| 发表于 2022-3-23 21:22 | 显示全部楼层
lwq1947 发表于 2022-3-23 07:03
你的程序太大所以没仔细看,现在发现你的编码器原程序就是用的中断来调频率。那就不要改端口了。在你原有 ...

  1. #include <SI4735.h>
  2. #include <EEPROM.h>
  3. #include <LiquidCrystal.h>
  4. #include "Rotary.h"
  5. #include "patch_init.h" // 整个SSBRX初始化字符串的SSB补丁

  6. const uint16_t size_content = sizeof ssb_patch_content; // 参见补丁_init。H


  7. #define FM_BAND_TYPE 0
  8. #define MW_BAND_TYPE 1
  9. #define SW_BAND_TYPE 2
  10. #define LW_BAND_TYPE 3

  11. #define RESET_PIN 9

  12. //编码引脚

  13. #define ENCODER_PIN_A 2
  14.                                                                                             
  15. #define ENCODER_PIN_B 3

  16. // LCD 16x02 or LCD20x4 PINs
  17. #define LCD_D7 4
  18. #define LCD_D6 5
  19. #define LCD_D5 6
  20. #define LCD_D4 7
  21. #define LCD_RS 12
  22. #define LCD_E 13

  23. // Buttons controllers
  24. #define ENCODER_PUSH_BUTTON 14 // 引脚A0/14
  25. #define DUMMY_BUTTON 15

  26. #define MIN_ELAPSED_TIME 300
  27. #define MIN_ELAPSED_RSSI_TIME 500
  28. #define ELAPSED_COMMAND 3000
  29. #define ELAPSED_CLICK 1500  
  30. #define DEFAULT_VOLUME 40   

  31. #define FM 0
  32. #define LSB 1
  33. #define USB 2
  34. #define AM 3
  35. #define LW 4

  36. #define SSB 1

  37. #define EEPROM_SIZE        512

  38. #define STORE_TIME 10000 // 使当前接收器状态可写的非活动时间(10秒/10000毫秒)。
  39. // EEPROM - Stroring control variables
  40. const uint8_t app_id = 31; // EEPROM-选通控制变量
  41. const int eeprom_address = 0;
  42. long storeTime = millis();

  43. bool itIsTimeToSave = false;

  44. bool bfoOn = false;
  45. bool ssbLoaded = false;

  46. int8_t agcIdx = 0;
  47. uint8_t disableAgc = 0;
  48. int8_t agcNdx = 0;
  49. int8_t softMuteMaxAttIdx = 4;
  50. int8_t avcIdx;   // 最小12,最大90
  51. uint8_t countClick = 0;

  52. uint8_t seekDirection = 1;

  53. bool cmdBand = false;
  54. bool cmdVolume = false;
  55. bool cmdAgc = false;
  56. bool cmdBandwidth = false;
  57. bool cmdStep = false;
  58. bool cmdMode = false;
  59. bool cmdMenu = false;
  60. bool cmdRds  =  false;
  61. bool cmdSoftMuteMaxAtt = false;
  62. bool cmdAvc = false;


  63. bool fmRDS = false;

  64. int16_t currentBFO = 0;
  65. long elapsedRSSI = millis();
  66. long elapsedButton = millis();
  67. long elapsedCommand = millis();
  68. long elapsedClick = millis();
  69. volatile int encoderCount = 0;
  70. uint16_t currentFrequency;
  71. uint16_t previousFrequency = 0;


  72. const uint8_t currentBFOStep = 10;

  73. const char * menu[] = {"Volume", "FM RDS", "Step", "Mode", "BFO", "BW", "AGC/Att", "SoftMute", "AVC", "Seek Up", "Seek Down"};
  74. int8_t menuIdx = 0;
  75. const int lastMenu = 10;
  76. int8_t currentMenuCmd = -1;

  77. typedef struct
  78. {
  79.   uint8_t idx;      // SI473X设备带宽指数
  80.   const char *desc; //带宽描述
  81. } Bandwidth;

  82. int8_t bwIdxSSB = 4;
  83. const int8_t maxSsbBw = 5;
  84. Bandwidth bandwidthSSB[] = {
  85.   {4, "0.5"},
  86.   {5, "1.0"},
  87.   {0, "1.2"},
  88.   {1, "2.2"},
  89.   {2, "3.0"},
  90.   {3, "4.0"}
  91. };


  92. int8_t bwIdxAM = 4;
  93. const int8_t maxAmBw = 6;
  94. Bandwidth bandwidthAM[] = {
  95.   {4, "1.0"},
  96.   {5, "1.8"},
  97.   {3, "2.0"},
  98.   {6, "2.5"},
  99.   {2, "3.0"},
  100.   {1, "4.0"},
  101.   {0, "6.0"}
  102. };

  103. int8_t bwIdxFM = 0;
  104. const int8_t maxFmBw = 4;

  105. Bandwidth bandwidthFM[] = {
  106.     {0, "AUT"}, // 自动-默认值
  107.     {1, "110"}, // 强制宽(110 kHz)通道滤波器。
  108.     {2, " 84"},
  109.     {3, " 60"},
  110.     {4, " 40"}};



  111. int tabAmStep[] = {1,    // 0
  112.                    5,    // 1
  113.                    9,    // 2
  114.                    10,   // 3
  115.                    50,   // 4
  116.                    100}; // 5

  117. const int lastAmStep = (sizeof tabAmStep / sizeof(int)) - 1;
  118. int idxAmStep = 3;

  119. int tabFmStep[] = {5, 10, 20};
  120. const int lastFmStep = (sizeof tabFmStep / sizeof(int)) - 1;
  121. int idxFmStep = 1;

  122. uint16_t currentStepIdx = 1;


  123. const char *bandModeDesc[] = {"FM ", "LSB", "USB", "AM "};
  124. uint8_t currentMode = FM;

  125. /**
  126. *  Band data structure
  127. */
  128. typedef struct
  129. {
  130.   const char *bandName;   // 波段描述
  131.   uint8_t bandType;       //波段类型(FM、MW或SW)
  132.   uint16_t minimumFreq;   // 频带的最小频率
  133.   uint16_t maximumFreq;   // 频带的最大频率
  134.   uint16_t currentFreq;   // 默认频率或当前频率
  135.   int8_t currentStepIdx;  // tabStepAM的Idex:Defeult频率阶跃(参见tabStepAM)
  136.   int8_t bandwidthIdx;    // 表带宽FM、带宽AM或带宽SSB的索引;
  137.   uint8_t disableAgc;
  138.   int8_t agcIdx;
  139.   int8_t agcNdx;
  140.   int8_t avcIdx;
  141. } Band;

  142. /*
  143.   乐队桌
  144. 您可以配置自己的乐队计划。以评论为指导。
  145. 要添加新的标注栏,只需在下表中插入一行即可。不需要额外的代码。
  146. 如果不需要给定的标注栏,可以通过删除一行来删除标注栏。
  147. 此外,还可以更改标注栏的参数。
  148. 注意:在添加或删除此表的一行后,必须重置eeprom。
  149. 在第一次按下编码器按钮时打开接收器,以重置eeprom内容。
  150. */
  151. Band band[] = {
  152.     {"VHF", FM_BAND_TYPE, 6400, 10800, 10390, 1, 0, 1, 0, 0, 0},
  153.     {"MW1", MW_BAND_TYPE, 150, 1720, 810, 3, 4, 0, 0, 0, 32},
  154.     {"MW2", MW_BAND_TYPE, 531, 1701, 783, 2, 4, 0, 0, 0, 32},
  155.     {"MW3", MW_BAND_TYPE, 1700, 3500, 2500, 1, 4, 1, 0, 0, 32},
  156.     {"80M", MW_BAND_TYPE, 3500, 4000, 3700, 0, 4, 1, 0, 0, 32},
  157.     {"SW1", SW_BAND_TYPE, 4000, 5500, 4885, 1, 4, 1, 0, 0, 32},
  158.     {"SW2", SW_BAND_TYPE, 5500, 6500, 6000, 1, 4, 1, 0, 0, 32},
  159.     {"40M", SW_BAND_TYPE, 6500, 7300, 7100, 0, 4, 1, 0, 0, 40},
  160.     {"SW3", SW_BAND_TYPE, 7200, 8000, 7200, 1, 4, 1, 0, 0, 40},
  161.     {"SW4", SW_BAND_TYPE, 9000, 11000, 9500, 1, 4, 1, 0, 0, 40},
  162.     {"SW5", SW_BAND_TYPE, 11100, 13000, 11900, 1, 4, 1, 0, 0, 40},
  163.     {"SW6", SW_BAND_TYPE, 13000, 14000, 13500, 1, 4, 1, 0, 0, 40},
  164.     {"20M", SW_BAND_TYPE, 14000, 15000, 14200, 0, 4, 1, 0, 0, 42},
  165.     {"SW7", SW_BAND_TYPE, 15000, 17000, 15300, 1, 4, 1, 0, 0, 42},
  166.     {"SW8", SW_BAND_TYPE, 17000, 18000, 17500, 1, 4, 1, 0, 0, 42},
  167.     {"15M", SW_BAND_TYPE, 20000, 21400, 21100, 0, 4, 1, 0, 0, 44},
  168.     {"SW9", SW_BAND_TYPE, 21400, 22800, 21500, 1, 4, 1, 0, 0, 44},
  169.     {"CB ", SW_BAND_TYPE, 26000, 28000, 27500, 0, 4, 1, 0, 0, 44},
  170.     {"10M", SW_BAND_TYPE, 28000, 30000, 28400, 0, 4, 1, 0, 0, 44},
  171.     {"ALL", SW_BAND_TYPE, 150, 30000, 15000, 0, 4, 1, 0, 0, 48} //所有乐队。LW、MW和SW(从150kHz到30MHz)
  172. };

  173. const int lastBand = (sizeof band / sizeof(Band)) - 1;
  174. int bandIdx = 0;
  175. int tabStep[] = {1, 5, 10, 50, 100, 500, 1000};
  176. const int lastStep = (sizeof tabStep / sizeof(int)) - 1;


  177. uint8_t rssi = 0;
  178. uint8_t volume = DEFAULT_VOLUME;

  179. // 设备类声明
  180. Rotary encoder = Rotary(ENCODER_PIN_A, ENCODER_PIN_B);

  181. LiquidCrystal lcd(LCD_RS, LCD_E, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
  182. SI4735 rx;




  183. void setup()
  184. {
  185.   // 编码器引脚
  186.   pinMode(ENCODER_PUSH_BUTTON, INPUT_PULLUP);
  187.   pinMode(ENCODER_PIN_A, INPUT_PULLUP);
  188.   pinMode(ENCODER_PIN_B, INPUT_PULLUP);
  189.   lcd.begin(16, 2);



  190.   // 飞溅-删除或更改飞溅信息
  191.   lcd.setCursor(3, 0);//显示器光标,原为0,0
  192.   lcd.print("SI4732A10");//打印("SI4732A10")原为“PU2CLR-SI4735”
  193.   lcd.setCursor(0, 1);
  194.   lcd.print("Arduino Library");
  195.   Flash(1000);
  196.   lcd.setCursor(0, 0);
  197.   lcd.print("DIY Mirko Radio");
  198.   lcd.setCursor(0, 1);
  199.   lcd.print("By RICARDO/2021");
  200.   Flash(1000);
  201.   //末端飞溅

  202.   EEPROM.begin();

  203.   // 如果要重置eeprom,请在启动过程中按住音量上升按钮
  204.   if (digitalRead(ENCODER_PUSH_BUTTON) == LOW)
  205.   {
  206.     EEPROM.update(eeprom_address, 0);
  207.     lcd.setCursor(0,0);
  208.     lcd.print("EEPROM RESETED");
  209.     delay(2000);
  210.     lcd.clear();
  211.   }

  212.   // 通过中断控制编码器
  213.   attachInterrupt(digitalPinToInterrupt(ENCODER_PIN_A), rotaryEncoder, CHANGE);
  214.   attachInterrupt(digitalPinToInterrupt(ENCODER_PIN_B), rotaryEncoder, CHANGE);


  215.   rx.setI2CFastModeCustom(100000);
  216.   
  217.   rx.getDeviceI2CAddress(RESET_PIN); //查找并设置I2C总线地址。如果出现错误,则返回0
  218.   
  219.   rx.setup(RESET_PIN, MW_BAND_TYPE);
  220.   // 如果使用外部参考时钟(有源晶体或信号发生器),请注释上面的行,并取消注释下面的三行
  221.   // rx.setRefClock(32768);
  222.   // rx.setRefClockPrescaler(1);   // will work with 32768  
  223.   // rx.setup(RESET_PIN, 0, MW_BAND_TYPE, SI473X_ANALOG_AUDIO, XOSCEN_RCLK);

  224.   
  225.   delay(300);
  226.   rx.setAvcAmMaxGain(48); // 设置AM/SSB模式下自动音量控制的最大增益(可以使用12到90dB之间的值)。




  227.   // 检查EEPROM内容
  228.   if (EEPROM.read(eeprom_address) == app_id)
  229.   {
  230.     readAllReceiverInformation();
  231.   } else
  232.     rx.setVolume(volume);
  233.   
  234.   useBand();
  235.   showStatus();
  236. }

  237. /**
  238. *  用视觉效果清洁屏幕。
  239. */
  240. void Flash(int d)
  241. {
  242.   delay(d);
  243.   lcd.clear();
  244.   lcd.noDisplay();
  245.   delay(500);
  246.   lcd.display();
  247. }

  248. /*
  249.   将当前接收器信息写入eeprom。
  250. EEPROM。更新避免在同一内存位置写入相同的数据。这样可以节省不必要的录音。
  251. */
  252. void saveAllReceiverInformation()
  253. {
  254.   int addr_offset;

  255.   EEPROM.begin();

  256.   EEPROM.update(eeprom_address, app_id);                 // 存储应用程序id;
  257.   EEPROM.update(eeprom_address + 1, rx.getVolume()); // 存储当前卷
  258.   EEPROM.update(eeprom_address + 2, bandIdx);            // 存储当前波段
  259.   EEPROM.update(eeprom_address + 3, fmRDS);
  260.   EEPROM.update(eeprom_address + 4, currentMode); // 存储当前模式(FM/AM/SSB)
  261.   EEPROM.update(eeprom_address + 5, currentBFO >> 8);
  262.   EEPROM.update(eeprom_address + 6, currentBFO & 0XFF);

  263.   addr_offset = 7;
  264.   band[bandIdx].currentFreq = currentFrequency;

  265.   for (int i = 0; i <= lastBand; i++)
  266.   {
  267.     EEPROM.update(addr_offset++, (band[i].currentFreq >> 8));   // 存储频带的当前频率高字节
  268.     EEPROM.update(addr_offset++, (band[i].currentFreq & 0xFF)); // 存储频带的当前频率低字节
  269.     EEPROM.update(addr_offset++, band[i].currentStepIdx);       // 存储频带的当前步长
  270.     EEPROM.update(addr_offset++, band[i].bandwidthIdx);         // 表带宽索引(直接位置)
  271.     EEPROM.update(addr_offset++, band[i].disableAgc );
  272.     EEPROM.update(addr_offset++, band[i].agcIdx);
  273.     EEPROM.update(addr_offset++, band[i].agcNdx);
  274.     EEPROM.update(addr_offset++, band[i].avcIdx);

  275.   }

  276.   EEPROM.end();
  277. }

  278. /**
  279. * 从eeprom读取最后一个接收器状态。
  280. */
  281. void readAllReceiverInformation()
  282. {
  283.   uint8_t volume;
  284.   int addr_offset;
  285.   int bwIdx;

  286.   volume = EEPROM.read(eeprom_address + 1); //获取存储的卷;
  287.   bandIdx = EEPROM.read(eeprom_address + 2);
  288.   fmRDS = EEPROM.read(eeprom_address + 3);
  289.   currentMode = EEPROM.read(eeprom_address + 4);
  290.   currentBFO = EEPROM.read(eeprom_address + 5) << 8;
  291.   currentBFO |= EEPROM.read(eeprom_address + 6);

  292.   addr_offset = 7;
  293.   for (int i = 0; i <= lastBand; i++)
  294.   {
  295.     band[i].currentFreq = EEPROM.read(addr_offset++) << 8;
  296.     band[i].currentFreq |= EEPROM.read(addr_offset++);
  297.     band[i].currentStepIdx = EEPROM.read(addr_offset++);
  298.     band[i].bandwidthIdx = EEPROM.read(addr_offset++);
  299.     band[i].disableAgc = EEPROM.read(addr_offset++);
  300.     band[i].agcIdx = EEPROM.read(addr_offset++);
  301.     band[i].agcNdx = EEPROM.read(addr_offset++);
  302.     band[i].avcIdx = EEPROM.read(addr_offset++);
  303.   }


  304.   currentFrequency = band[bandIdx].currentFreq;

  305.   if (band[bandIdx].bandType == FM_BAND_TYPE)
  306.   {
  307.     currentStepIdx = idxFmStep = band[bandIdx].currentStepIdx;
  308.     rx.setFrequencyStep(tabFmStep[currentStepIdx]);
  309.   }
  310.   else
  311.   {
  312.     currentStepIdx = idxAmStep = band[bandIdx].currentStepIdx;
  313.     rx.setFrequencyStep(tabAmStep[currentStepIdx]);
  314.   }

  315.   bwIdx = band[bandIdx].bandwidthIdx;

  316.   if (currentMode == LSB || currentMode == USB)
  317.   {
  318.     loadSSB();
  319.     bwIdxSSB = (bwIdx > 5) ? 5 : bwIdx;
  320.     rx.setSSBAudioBandwidth(bandwidthSSB[bwIdxSSB].idx);
  321.     //如果选择的音频带宽约为2 kHz或以下,建议将边带截止滤波器设置为0。
  322.     if (bandwidthSSB[bwIdxSSB].idx == 0 || bandwidthSSB[bwIdxSSB].idx == 4 || bandwidthSSB[bwIdxSSB].idx == 5)
  323.       rx.setSBBSidebandCutoffFilter(0);
  324.     else
  325.       rx.setSBBSidebandCutoffFilter(1);
  326.   }
  327.   else if (currentMode == AM)
  328.   {
  329.     bwIdxAM = bwIdx;
  330.     rx.setBandwidth(bandwidthAM[bwIdxAM].idx, 1);
  331.   }
  332.   else
  333.   {
  334.     bwIdxFM = bwIdx;
  335.     rx.setFmBandwidth(bandwidthFM[bwIdxFM].idx);
  336.   }

  337.   delay(50);
  338.   rx.setVolume(volume);
  339. }

  340. /*
  341. * 要将任何更改存储到EEPROM中,至少需要存储毫秒的不活动时间。
  342. */
  343. void resetEepromDelay()
  344. {
  345.   elapsedCommand = storeTime = millis();
  346.   itIsTimeToSave = true;
  347. }

  348. /**
  349.     将所有命令标志设置为false
  350. 当禁用所有标志(false)时,编码器控制频率
  351. */
  352. void disableCommands()
  353. {
  354.   cmdBand = false;
  355.   bfoOn = false;
  356.   cmdVolume = false;
  357.   cmdAgc = false;
  358.   cmdBandwidth = false;
  359.   cmdStep = false;
  360.   cmdMode = false;
  361.   cmdMenu = false;
  362.   cmdSoftMuteMaxAtt = false;
  363.   cmdRds = false;
  364.   cmdAvc =  false;
  365.   countClick = 0;

  366.   showCommandStatus((char *) "VFO ");
  367. }



  368. /**
  369. *通过中断读取编码器
  370. *使用旋转。h和扶轮社。通过中断处理编码器的cpp实现
  371. * if you do not add ICACHE_RAM_ATTR declaration, the system will reboot during attachInterrupt call.
  372. * With ICACHE_RAM_ATTR macro you put the function on the RAM.
  373. */
  374. void  rotaryEncoder()
  375. { // 旋转编码器事件
  376.   uint8_t encoderStatus = encoder.process();
  377.   if (encoderStatus)//如果编码器状态
  378.     encoderCount = (encoderStatus == DIR_CW) ? 1 : -1;//编码器计数=(编码器状态==DIR_CW)?1 : -1;

  379. //以下背光控制
  380. digitalWrite(8,HIGH);
  381. ptime=millis();
  382. //以上背光控制   
  383. }

  384. /**
  385. * 在显示屏上显示频率信息
  386. */
  387. void showFrequency()
  388. {
  389.   char tmp[15];
  390.   char bufferDisplay[15];
  391.   char *unit;
  392.   int col = 4;
  393.   sprintf(tmp, "%5.5u", currentFrequency);
  394.   bufferDisplay[0] = (tmp[0] == '0') ? ' ' : tmp[0];
  395.   bufferDisplay[1] = tmp[1];
  396.   if (rx.isCurrentTuneFM())
  397.   {
  398.     bufferDisplay[2] = tmp[2];
  399.     bufferDisplay[3] = '.';
  400.     bufferDisplay[4] = tmp[3];
  401.     if ( fmRDS ) {
  402.       col = 0;
  403.       unit = (char *)" ";
  404.     } else {
  405.       unit = (char *)"MHz";
  406.     }
  407.   }
  408.   else
  409.   {
  410.     if (currentFrequency < 1000)
  411.     {
  412.       bufferDisplay[1] = ' ';
  413.       bufferDisplay[2] = tmp[2];
  414.       bufferDisplay[3] = tmp[3];
  415.       bufferDisplay[4] = tmp[4];
  416.     }
  417.     else
  418.     {
  419.       bufferDisplay[2] = tmp[2];
  420.       bufferDisplay[3] = tmp[3];
  421.       bufferDisplay[4] = tmp[4];
  422.     }
  423.     unit = (char *)"kHz";
  424.   }
  425.   bufferDisplay[5] = '\0';
  426.   strcat(bufferDisplay, unit);
  427.   lcd.setCursor(col, 1);
  428.   lcd.print(bufferDisplay);
  429.   showMode();
  430. }

  431. /**
  432. * 显示当前模式
  433. */
  434. void showMode()
  435. {
  436.   char *bandMode;

  437.    
  438.   if (currentFrequency < 520)
  439.     bandMode = (char *)"LW  ";
  440.   else
  441.     bandMode = (char *)bandModeDesc[currentMode];
  442.   lcd.setCursor(0, 0);
  443.   lcd.print(bandMode);

  444.   if ( currentMode == FM && fmRDS ) return;
  445.   
  446.   lcd.setCursor(0, 1);
  447.   lcd.print(band[bandIdx].bandName);
  448. }

  449. /**
  450. * 在显示屏上显示一些基本信息
  451. */
  452. void showStatus()
  453. {
  454.   lcd.clear();
  455.   showFrequency();
  456.   showRSSI();
  457. }

  458. /**
  459. *  显示当前带宽状态
  460. */
  461. void showBandwidth()
  462. {
  463.   char *bw;
  464.   char bandwidth[20];
  465.   if (currentMode == LSB || currentMode == USB)
  466.   {
  467.     bw = (char *)bandwidthSSB[bwIdxSSB].desc;
  468.     showBFO();
  469.   }
  470.   else if (currentMode == AM)
  471.   {
  472.     bw = (char *)bandwidthAM[bwIdxAM].desc;
  473.   }
  474.   else
  475.   {
  476.     bw = (char *)bandwidthFM[bwIdxFM].desc;
  477.   }

  478.   sprintf(bandwidth, "BW: %s", bw);
  479.   lcd.clear();
  480.   lcd.setCursor(0, 0);
  481.   lcd.print(bandwidth);
  482. }

  483. /**
  484. *  显示当前的RSSI和SNR状态
  485. */
  486. void showRSSI()
  487. {
  488.   int rssiAux = 0;
  489.   char sMeter[7];

  490.   if (currentMode == FM)
  491.   {
  492.     lcd.setCursor(14, 0);
  493.     lcd.print((rx.getCurrentPilot()) ? "ST" : "MO");
  494.     lcd.setCursor(10, 0);
  495.     if ( fmRDS ) {
  496.       lcd.print("RDS");
  497.       return;
  498.     }
  499.     else
  500.       lcd.print("   ");
  501.   }

  502.    
  503.   if (rssi < 2)
  504.     rssiAux = 4;
  505.   else if (rssi < 4)
  506.     rssiAux = 5;
  507.   else if (rssi < 12)
  508.     rssiAux = 6;
  509.   else if (rssi < 25)
  510.     rssiAux = 7;
  511.   else if (rssi < 50)
  512.     rssiAux = 8;
  513.   else
  514.     rssiAux = 9;

  515.   sprintf(sMeter, "S%1.1u%c", rssiAux, (rssi >= 60) ? '+' : '.');
  516.   lcd.setCursor(13, 1);
  517.   lcd.print(sMeter);
  518. }

  519. /**
  520. *    显示当前AGC和衰减状态
  521. */
  522. void showAgcAtt()
  523. {
  524.   char sAgc[15];
  525.   lcd.clear();
  526.   rx.getAutomaticGainControl();
  527.   if ( !disableAgc /*agcNdx == 0 && agcIdx == 0 */ )
  528.     strcpy(sAgc, "AGC ON");
  529.   else
  530.     sprintf(sAgc, "ATT: %2.2d", agcNdx);

  531.   lcd.setCursor(0, 0);
  532.   lcd.print(sAgc);
  533. }


  534. /**
  535. *  显示当前步骤
  536. */
  537. void showStep()
  538. {
  539.   char sStep[15];

  540.   sprintf(sStep, "Stp:%4d", (currentMode == FM)? (tabFmStep[currentStepIdx] *10) : tabAmStep[currentStepIdx] );
  541.   lcd.setCursor(0, 0);
  542.   lcd.print(sStep);
  543. }

  544. /**
  545. *  显示当前BFO值
  546. */
  547. void showBFO()
  548. {
  549.   char bfo[15];
  550.   if (currentBFO > 0)
  551.     sprintf(bfo, "BFO:+%4.4d", currentBFO);
  552.   else
  553.     sprintf(bfo, "BFO:%4.4d", currentBFO);

  554.   lcd.clear();
  555.   lcd.setCursor(0, 0);
  556.   lcd.print(bfo);
  557.   elapsedCommand = millis();
  558. }

  559. /*
  560. * 在LCD上显示音量
  561. */
  562. void showVolume()
  563. {
  564.   char volAux[12];
  565.   sprintf(volAux, "VOLUME: %2u", rx.getVolume());
  566.   lcd.clear();
  567.   lcd.setCursor(0, 0);
  568.   lcd.print(volAux);
  569. }

  570. /**
  571. * 显示柔和的静音
  572. */
  573. void showSoftMute()
  574. {
  575.   char sMute[18];
  576.   sprintf(sMute, "Soft Mute: %2d", softMuteMaxAttIdx);
  577.   lcd.clear();
  578.   lcd.setCursor(0, 0);
  579.   lcd.print(sMute);
  580. }


  581. /**
  582. * Show Soft Mute
  583. */
  584. void showAvc()
  585. {
  586.   char sAvc[18];
  587.   sprintf(sAvc, "AVC: %2d", avcIdx);
  588.   lcd.clear();
  589.   lcd.setCursor(0, 0);
  590.   lcd.print(sAvc);
  591. }



  592. /**
  593. * 显示RDS开或关
  594. */
  595. void showRdsSetup()
  596. {
  597.   char sRdsStatus[10];
  598.   sprintf(sRdsStatus, "RDS: %s", (fmRDS)? "ON ": "OFF");
  599.   lcd.clear();
  600.   lcd.setCursor(0, 0);
  601.   lcd.print(sRdsStatus);  

  602. }

  603. /***************  
  604. *   RDS
  605. *   
  606. */

  607. char *stationName;
  608. char bufferStatioName[20];

  609. void clearRDS() {
  610.    stationName = (char *) "           ";
  611.    showRDSStation();
  612. }

  613. void showRDSStation()
  614. {
  615.     int col = 8;
  616.     for (int i = 0; i < 8; i++ ) {
  617.       if (stationName[i] != bufferStatioName[i] ) {
  618.         lcd.setCursor(col + i, 1);
  619.         lcd.print(stationName[i]);
  620.         bufferStatioName[i] = stationName[i];
  621.       }
  622.     }
  623.    
  624.     delay(100);
  625. }


  626. /*
  627. * 检查电台名称是否可用
  628. */
  629. void checkRDS()
  630. {
  631.   rx.getRdsStatus();
  632.   if (rx.getRdsReceived())
  633.   {
  634.     if (rx.getRdsSync() && rx.getRdsSyncFound() && !rx.getRdsSyncLost() && !rx.getGroupLost() )
  635.     {
  636.       stationName = rx.getRdsText0A();
  637.       if (stationName != NULL )
  638.       {
  639.         showRDSStation();
  640.       }
  641.     }
  642.   }
  643. }


  644. /**
  645. *   设置波段向上(1)或向下(!1)
  646. */
  647. void setBand(int8_t up_down)
  648. {
  649.   band[bandIdx].currentFreq = currentFrequency;
  650.   band[bandIdx].currentStepIdx = currentStepIdx;
  651.   if (up_down == 1)
  652.     bandIdx = (bandIdx < lastBand) ? (bandIdx + 1) : 0;
  653.   else
  654.     bandIdx = (bandIdx > 0) ? (bandIdx - 1) : lastBand;
  655.   useBand();
  656.   delay(MIN_ELAPSED_TIME); // 再等一会儿,等待释放按钮。
  657. }

  658. /**
  659. * 将收音机切换到当前波段
  660. */
  661. void useBand()
  662. {
  663.   if (band[bandIdx].bandType == FM_BAND_TYPE)
  664.   {
  665.     currentMode = FM;
  666.     rx.setTuneFrequencyAntennaCapacitor(0);
  667.     rx.setFM(band[bandIdx].minimumFreq, band[bandIdx].maximumFreq, band[bandIdx].currentFreq, tabFmStep[band[bandIdx].currentStepIdx]);
  668.     rx.setSeekFmLimits(band[bandIdx].minimumFreq, band[bandIdx].maximumFreq);
  669.     rx.setRdsConfig(1, 2, 2, 2, 2);
  670.     rx.setFifoCount(1);
  671.    
  672.     bfoOn = ssbLoaded = false;
  673.     bwIdxFM = band[bandIdx].bandwidthIdx;
  674.     rx.setFmBandwidth(bandwidthFM[bwIdxFM].idx);   
  675.   }
  676.   else
  677.   {

  678.     disableAgc = band[bandIdx].disableAgc;
  679.     agcIdx = band[bandIdx].agcIdx;
  680.     agcNdx = band[bandIdx].agcNdx;
  681.     avcIdx = band[bandIdx].avcIdx;
  682.    
  683.     // set the tuning capacitor for SW or MW/LW
  684.     rx.setTuneFrequencyAntennaCapacitor((band[bandIdx].bandType == MW_BAND_TYPE || band[bandIdx].bandType == LW_BAND_TYPE) ? 0 : 1);
  685.     if (ssbLoaded)
  686.     {
  687.       rx.setSSB(band[bandIdx].minimumFreq, band[bandIdx].maximumFreq, band[bandIdx].currentFreq, tabAmStep[band[bandIdx].currentStepIdx], currentMode);
  688.       rx.setSSBAutomaticVolumeControl(1);
  689.       rx.setSsbSoftMuteMaxAttenuation(softMuteMaxAttIdx); // Disable Soft Mute for SSB
  690.       bwIdxSSB = band[bandIdx].bandwidthIdx;
  691.       rx.setSSBAudioBandwidth(bandwidthSSB[bwIdxSSB].idx);
  692.       delay(500);
  693.       rx.setSsbAgcOverrite(disableAgc, agcNdx);
  694.     }
  695.     else
  696.     {
  697.       currentMode = AM;
  698.       rx.setAM(band[bandIdx].minimumFreq, band[bandIdx].maximumFreq, band[bandIdx].currentFreq, tabAmStep[band[bandIdx].currentStepIdx]);
  699.       bfoOn = false;
  700.       bwIdxAM = band[bandIdx].bandwidthIdx;
  701.       rx.setBandwidth(bandwidthAM[bwIdxAM].idx, 1);
  702.       rx.setAmSoftMuteMaxAttenuation(softMuteMaxAttIdx); // Soft Mute for AM or SSB
  703.       rx.setAutomaticGainControl(disableAgc, agcNdx);

  704.     }
  705.     rx.setSeekAmLimits(band[bandIdx].minimumFreq, band[bandIdx].maximumFreq); // Consider the range all defined current band
  706.     rx.setSeekAmSpacing(5); // Max 10kHz for spacing
  707.     rx.setAvcAmMaxGain(avcIdx);
  708.   }
  709.   delay(100);
  710.   currentFrequency = band[bandIdx].currentFreq;
  711.   currentStepIdx = band[bandIdx].currentStepIdx;

  712.   rssi = 0;
  713.   showStatus();
  714.   showCommandStatus((char *) "Band");
  715. }


  716. void loadSSB() {
  717.    rx.setI2CFastModeCustom(400000); // You can try rx.setI2CFastModeCustom(700000); or greater value
  718.    rx.loadPatch(ssb_patch_content, size_content, bandwidthSSB[bwIdxSSB].idx);
  719.    rx.setI2CFastModeCustom(100000);  
  720.    ssbLoaded =  true;
  721. }

  722. /**
  723. * 切换带宽
  724. */
  725. void doBandwidth(int8_t v)
  726. {
  727.     if (currentMode == LSB || currentMode == USB)
  728.     {
  729.       bwIdxSSB = (v == 1) ? bwIdxSSB + 1 : bwIdxSSB - 1;

  730.       if (bwIdxSSB > maxSsbBw)
  731.         bwIdxSSB = 0;
  732.       else if (bwIdxSSB < 0)
  733.         bwIdxSSB = maxSsbBw;

  734.       rx.setSSBAudioBandwidth(bandwidthSSB[bwIdxSSB].idx);
  735.       // If audio bandwidth selected is about 2 kHz or below, it is recommended to set Sideband Cutoff Filter to 0.
  736.       if (bandwidthSSB[bwIdxSSB].idx == 0 || bandwidthSSB[bwIdxSSB].idx == 4 || bandwidthSSB[bwIdxSSB].idx == 5)
  737.         rx.setSBBSidebandCutoffFilter(0);
  738.       else
  739.         rx.setSBBSidebandCutoffFilter(1);

  740.       band[bandIdx].bandwidthIdx = bwIdxSSB;
  741.     }
  742.     else if (currentMode == AM)
  743.     {
  744.       bwIdxAM = (v == 1) ? bwIdxAM + 1 : bwIdxAM - 1;

  745.       if (bwIdxAM > maxAmBw)
  746.         bwIdxAM = 0;
  747.       else if (bwIdxAM < 0)
  748.         bwIdxAM = maxAmBw;

  749.       rx.setBandwidth(bandwidthAM[bwIdxAM].idx, 1);
  750.       band[bandIdx].bandwidthIdx = bwIdxAM;
  751.       
  752.     } else {
  753.     bwIdxFM = (v == 1) ? bwIdxFM + 1 : bwIdxFM - 1;
  754.     if (bwIdxFM > maxFmBw)
  755.       bwIdxFM = 0;
  756.     else if (bwIdxFM < 0)
  757.       bwIdxFM = maxFmBw;

  758.     rx.setFmBandwidth(bandwidthFM[bwIdxFM].idx);
  759.     band[bandIdx].bandwidthIdx = bwIdxFM;
  760.   }
  761.   showBandwidth();
  762.   delay(MIN_ELAPSED_TIME); // waits a little more for releasing the button.
  763. }

  764. /**
  765. * 在显示屏上显示cmd。这意味着你在设置一些东西。
  766. */
  767. void showCommandStatus(char * currentCmd)
  768. {
  769.   lcd.setCursor(5, 0);
  770.   lcd.print(currentCmd);
  771. }

  772. /**
  773. * Show menu options
  774. */
  775. void showMenu() {
  776.   lcd.clear();
  777.   lcd.setCursor(0, 0);
  778.   lcd.setCursor(0, 1);
  779.   lcd.print(menu[menuIdx]);
  780.   showCommandStatus( (char *) "Menu");
  781. }

  782. /**
  783. *  AGC和衰减设置
  784. */
  785. void doAgc(int8_t v) {
  786.   agcIdx = (v == 1) ? agcIdx + 1 : agcIdx - 1;
  787.   if (agcIdx < 0 )
  788.     agcIdx = 37;
  789.   else if ( agcIdx > 37)
  790.     agcIdx = 0;
  791.   disableAgc = (agcIdx > 0); // if true, disable AGC; esle, AGC is enable
  792.   if (agcIdx > 1)
  793.     agcNdx = agcIdx - 1;
  794.   else
  795.     agcNdx = 0;
  796.   if ( currentMode == AM )
  797.      rx.setAutomaticGainControl(disableAgc, agcNdx); // if agcNdx = 0, no attenuation
  798.   else
  799.     rx.setSsbAgcOverrite(disableAgc, agcNdx, 0B1111111);

  800.   band[bandIdx].disableAgc = disableAgc;
  801.   band[bandIdx].agcIdx = agcIdx;
  802.   band[bandIdx].agcNdx = agcNdx;

  803.   showAgcAtt();
  804.   delay(MIN_ELAPSED_TIME); // 再等一会儿,等待释放按钮。
  805.   elapsedCommand = millis();
  806. }


  807. /**
  808. * 切换当前步骤
  809. */
  810. void doStep(int8_t v)
  811. {
  812.     if ( currentMode == FM ) {
  813.       idxFmStep = (v == 1) ? idxFmStep + 1 : idxFmStep - 1;
  814.       if (idxFmStep > lastFmStep)
  815.         idxFmStep = 0;
  816.       else if (idxFmStep < 0)
  817.         idxFmStep = lastFmStep;
  818.         
  819.       currentStepIdx = idxFmStep;
  820.       rx.setFrequencyStep(tabFmStep[currentStepIdx]);
  821.       
  822.     } else {
  823.       idxAmStep = (v == 1) ? idxAmStep + 1 : idxAmStep - 1;
  824.       if (idxAmStep > lastAmStep)
  825.         idxAmStep = 0;
  826.       else if (idxAmStep < 0)
  827.         idxAmStep = lastAmStep;

  828.       currentStepIdx = idxAmStep;
  829.       rx.setFrequencyStep(tabAmStep[currentStepIdx]);
  830.       rx.setSeekAmSpacing(5); // Max 10kHz for spacing
  831.     }
  832.     band[bandIdx].currentStepIdx = currentStepIdx;
  833.     showStep();
  834.     delay(MIN_ELAPSED_TIME); // 再等一会儿,等待释放按钮。
  835.     elapsedCommand = millis();
  836. }

  837. /**
  838. * Switches to the AM, LSB or USB modes
  839. */
  840. void doMode(int8_t v)
  841. {
  842.   if (currentMode != FM)
  843.   {
  844.     if (v == 1)  { // clockwise
  845.       if (currentMode == AM)
  846.       {
  847.         // If you were in AM mode, it is necessary to load SSB patch (avery time)
  848.         loadSSB();
  849.         ssbLoaded = true;
  850.         currentMode = LSB;
  851.       }
  852.       else if (currentMode == LSB)
  853.         currentMode = USB;
  854.       else if (currentMode == USB)
  855.       {
  856.         currentMode = AM;
  857.         bfoOn = ssbLoaded = false;
  858.       }
  859.     } else { // and counterclockwise
  860.       if (currentMode == AM)
  861.       {
  862.         // If you were in AM mode, it is necessary to load SSB patch (avery time)
  863.         loadSSB();
  864.         ssbLoaded = true;
  865.         currentMode = USB;
  866.       }
  867.       else if (currentMode == USB)
  868.         currentMode = LSB;
  869.       else if (currentMode == LSB)
  870.       {
  871.         currentMode = AM;
  872.         bfoOn = ssbLoaded = false;
  873.       }
  874.     }
  875.     // Nothing to do if you are in FM mode
  876.     band[bandIdx].currentFreq = currentFrequency;
  877.     band[bandIdx].currentStepIdx = currentStepIdx;
  878.     useBand();
  879.   }
  880.   delay(MIN_ELAPSED_TIME); // waits a little more for releasing the button.
  881.   elapsedCommand = millis();
  882. }

  883. /**
  884. * Sets the audio volume
  885. */
  886. void doVolume( int8_t v ) {
  887.   if ( v == 1)
  888.     rx.volumeUp();
  889.   else
  890.     rx.volumeDown();

  891.   showVolume();
  892.   delay(MIN_ELAPSED_TIME); // waits a little more for releasing the button.
  893. }

  894. /**
  895. *  This function is called by the seek function process.
  896. */
  897. void showFrequencySeek(uint16_t freq)
  898. {
  899.   currentFrequency = freq;
  900.   showFrequency();
  901. }

  902. /**
  903. *  Find a station. The direction is based on the last encoder move clockwise or counterclockwise
  904. */
  905. void doSeek()
  906. {
  907.   if ((currentMode == LSB || currentMode == USB)) return; // It does not work for SSB mode

  908.   lcd.clear();
  909.   rx.seekStationProgress(showFrequencySeek, seekDirection);
  910.   showStatus();
  911.   currentFrequency = rx.getFrequency();
  912.   
  913. }

  914. /**
  915. * Sets the Soft Mute Parameter
  916. */
  917. void doSoftMute(int8_t v)
  918. {
  919.   softMuteMaxAttIdx = (v == 1) ? softMuteMaxAttIdx + 1 : softMuteMaxAttIdx - 1;
  920.   if (softMuteMaxAttIdx > 32)
  921.     softMuteMaxAttIdx = 0;
  922.   else if (softMuteMaxAttIdx < 0)
  923.     softMuteMaxAttIdx = 32;

  924.   rx.setAmSoftMuteMaxAttenuation(softMuteMaxAttIdx);
  925.   showSoftMute();
  926.   elapsedCommand = millis();
  927. }


  928. /**
  929. * 设置自动音量控制的最大增益。
  930. */
  931. void doAvc(int8_t v)
  932. {
  933.   avcIdx = (v == 1) ? avcIdx + 2 : avcIdx - 2;
  934.   if (avcIdx > 90)
  935.     avcIdx = 12;
  936.   else if (avcIdx < 12)
  937.     avcIdx = 90;

  938.   rx.setAvcAmMaxGain(avcIdx);

  939.   band[bandIdx].avcIdx = avcIdx;

  940.   showAvc();
  941.   elapsedCommand = millis();
  942. }


  943. /**
  944. * 打开或关闭RDS
  945. */
  946. void doRdsSetup(int8_t v)
  947. {
  948.   fmRDS = (v == 1)? true:false;
  949.   showRdsSetup();
  950.   elapsedCommand = millis();
  951. }


  952. /**
  953. * 菜单选项选择
  954. */
  955. void doMenu( int8_t v) {
  956.   menuIdx = (v == 1) ? menuIdx + 1 : menuIdx - 1;
  957.   if (menuIdx > lastMenu)
  958.     menuIdx = 0;
  959.   else if (menuIdx < 0)
  960.     menuIdx = lastMenu;

  961.   showMenu();
  962.   delay(MIN_ELAPSED_TIME); // waits a little more for releasing the button.
  963.   elapsedCommand = millis();
  964. }



  965. /**
  966. * Return true if the current status is Menu command
  967. */
  968. bool isMenuMode() {
  969.   return (cmdMenu | cmdStep | cmdBandwidth | cmdAgc | cmdVolume | cmdSoftMuteMaxAtt | cmdMode | cmdRds | cmdAvc);
  970. }


  971. /**
  972. * 启动菜单操作过程
  973. */
  974. void doCurrentMenuCmd() {
  975.   disableCommands();
  976.   switch (currentMenuCmd) {
  977.      case 0:                 // VOLUME
  978.       cmdVolume = true;
  979.       showVolume();
  980.       break;
  981.     case 1:
  982.       cmdRds = true;
  983.       showRdsSetup();
  984.       break;
  985.     case 2:                 // STEP
  986.       cmdStep = true;
  987.       showStep();
  988.       break;
  989.     case 3:                 // MODE
  990.       cmdMode = true;
  991.       lcd.clear();
  992.       showMode();
  993.       break;
  994.     case 4:
  995.         bfoOn = true;
  996.         if ((currentMode == LSB || currentMode == USB)) {
  997.           showBFO();
  998.         }
  999.       // showFrequency();
  1000.       break;      
  1001.     case 5:                 // BW
  1002.       cmdBandwidth = true;
  1003.       showBandwidth();
  1004.       break;
  1005.     case 6:                 // AGC/ATT
  1006.       cmdAgc = true;
  1007.       showAgcAtt();
  1008.       break;
  1009.     case 7:
  1010.       cmdSoftMuteMaxAtt = true;
  1011.       showSoftMute();  
  1012.       break;
  1013.     case 8:
  1014.       cmdAvc =  true;
  1015.       showAvc();
  1016.       break;  
  1017.     case 9:
  1018.       seekDirection = 1;
  1019.       doSeek();
  1020.       break;  
  1021.     case 10:
  1022.       seekDirection = 0;
  1023.       doSeek();
  1024.       break;   
  1025.     default:
  1026.       showStatus();
  1027.       break;
  1028.   }
  1029.   currentMenuCmd = -1;
  1030.   elapsedCommand = millis();
  1031. }




  1032. /**
  1033. * Main loop
  1034. */
  1035. void loop()
  1036. {

  1037. if(millis()-ptime>5000) digitalWrite(8,LOW);

  1038.   // 检查编码器是否移动.
  1039.   if (encoderCount != 0)
  1040.   {
  1041.     if (bfoOn & (currentMode == LSB || currentMode == USB))
  1042.     {
  1043.       currentBFO = (encoderCount == 1) ? (currentBFO + currentBFOStep) : (currentBFO - currentBFOStep);
  1044.       rx.setSSBBfo(currentBFO);
  1045.       showBFO();

  1046.   


  1047.       
  1048.     }


  1049.   
  1050.     else if (cmdMenu)
  1051.       doMenu(encoderCount);
  1052.     else if (cmdMode)
  1053.       doMode(encoderCount);
  1054.     else if (cmdStep)
  1055.       doStep(encoderCount);
  1056.     else if (cmdAgc)
  1057.       doAgc(encoderCount);
  1058.     else if (cmdBandwidth)
  1059.       doBandwidth(encoderCount);
  1060.     else if (cmdVolume)
  1061.       doVolume(encoderCount);
  1062.     else if (cmdSoftMuteMaxAtt)
  1063.       doSoftMute(encoderCount);
  1064.     else if (cmdAvc)
  1065.       doAvc(encoderCount);      
  1066.     else if (cmdBand)
  1067.       setBand(encoderCount);
  1068.     else if (cmdRds )
  1069.       doRdsSetup(encoderCount);  
  1070.     else
  1071.     {
  1072.       if (encoderCount == 1)
  1073.       {
  1074.      
  1075.         rx.frequencyUp();
  1076.       }
  1077.       else
  1078.       {
  1079.         rx.frequencyDown();
  1080.       }
  1081.       // 仅当当前频率发生变化时才显示
  1082.       currentFrequency = rx.getFrequency();
  1083.       showFrequency();
  1084.     }
  1085.     encoderCount = 0;
  1086.     resetEepromDelay();
  1087.   }
  1088.   else
  1089.   {
  1090.     if (digitalRead(ENCODER_PUSH_BUTTON) == LOW)
  1091.     {





  1092.       
  1093.       countClick++;
  1094.       if (cmdMenu)
  1095.       {
  1096.         currentMenuCmd = menuIdx;
  1097.         doCurrentMenuCmd();
  1098.       }
  1099.       else if (countClick == 1)
  1100.       { // 只要点击一下,你就可以通过旋转编码器来选择波段
  1101.         if (isMenuMode())
  1102.         {
  1103.           disableCommands();
  1104.           showStatus();
  1105.           showCommandStatus((char *)"VFO ");
  1106.         }
  1107.         else if ( bfoOn ) {
  1108.           bfoOn = false;
  1109.           showStatus();
  1110.         }
  1111.         else
  1112.         {
  1113.           cmdBand = !cmdBand;
  1114.           showCommandStatus((char *)"Band");
  1115.         }
  1116.       }
  1117.       else
  1118.       { // 如果在1/2秒内点击超过一次,请转到菜单。
  1119.         cmdMenu = !cmdMenu;
  1120.         if (cmdMenu)
  1121.           showMenu();
  1122.       }
  1123.       delay(MIN_ELAPSED_TIME);
  1124.       elapsedCommand = millis();
  1125.     }
  1126.   }

  1127.   // 仅当此条件发生变化时才显示RSSI状态
  1128.   if ((millis() - elapsedRSSI) > MIN_ELAPSED_RSSI_TIME * 6)
  1129.   {
  1130.     rx.getCurrentReceivedSignalQuality();
  1131.     int aux = rx.getCurrentRSSI();
  1132.     if (rssi != aux && !isMenuMode())
  1133.     {
  1134.       rssi = aux;
  1135.       showRSSI();
  1136.     }
  1137.     elapsedRSSI = millis();
  1138.   }

  1139.   // Disable commands control
  1140.   if ((millis() - elapsedCommand) > ELAPSED_COMMAND)
  1141.   {
  1142.     if ((currentMode == LSB || currentMode == USB) )
  1143.     {
  1144.       bfoOn = false;
  1145.       // showBFO();
  1146.       showStatus();
  1147.     } else if (isMenuMode())
  1148.       showStatus();
  1149.     disableCommands();
  1150.     elapsedCommand = millis();
  1151.   }

  1152.   if ((millis() - elapsedClick) > ELAPSED_CLICK)
  1153.   {
  1154.     countClick = 0;
  1155.     elapsedClick = millis();
  1156.   }

  1157.   // 仅当当前频率发生变化时才显示
  1158.   if (itIsTimeToSave)
  1159.   {
  1160.     if ((millis() - storeTime) > STORE_TIME)
  1161.     {
  1162.       saveAllReceiverInformation();
  1163.       storeTime = millis();
  1164.       itIsTimeToSave = false;
  1165.     }
  1166.   }

  1167.   if (currentMode == FM && fmRDS && !isMenuMode() )
  1168.   {
  1169.       if (currentFrequency != previousFrequency)
  1170.       {
  1171.         clearRDS();
  1172.         previousFrequency = currentFrequency;
  1173.        }
  1174.       else
  1175.       {
  1176.         checkRDS();
  1177.       }
  1178.   }  

  1179.   delay(2);
  1180. }
复制代码
加进去后报错:C:\Users\xgm\Documents\Arduino\libraries\PU2CLR_SI4735\examples\SI47XX_02_for_Mirko_Pavleski_radio\MIRKO_V2.1____\MIRKO_V2.1____.ino: In function 'void rotaryEncoder()':
MIRKO_V2.1____:530:1: error: 'ptime' was not declared in this scope
ptime=millis();
^~~~~
C:\Users\xgm\Documents\Arduino\libraries\PU2CLR_SI4735\examples\SI47XX_02_for_Mirko_Pavleski_radio\MIRKO_V2.1____\MIRKO_V2.1____.ino: In function 'void loop()':
MIRKO_V2.1____:1269:13: error: 'ptime' was not declared in this scope
if(millis()-ptime>5000) digitalWrite(8,LOW);
             ^~~~~
"SI4735.h" 对应多个库
已使用: C:\Users\xgm\Documents\Arduino\libraries\PU2CLR_SI4735
未使用:C:\Users\xgm\Documents\Arduino\libraries\arduino_828790
exit status 1
'ptime' was not declared in this scope

MIRKO_V2.1____.rar

26.75 KB, 下载次数: 0

发表于 2022-3-24 05:54 | 显示全部楼层
xgm1818 发表于 2022-3-23 21:22
加进去后报错:C:%users\xgm\Documents\Arduino\libraries\PU2CLR_SI4735\examples\SI47XX_02_for_Mirko_ ...

程序开头要加uint32_t ptime=0;
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 11:46 , Processed in 0.146996 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表