The code of the DIY amplifier has grown much, it is harder and harder to debug it and keep in the order. So first of all I have added the audioprocessor part to the existing code, not much to discuss it is already been considered. Only one thing – I added the display LCD functions instead of the uart menu. I still want to have the USB connectivity so I can take control over amp from the PC. The plan is to use the FT232 with the virtual com port. Of coarse, it would be a nicer way to use PIC18 with USB on-board, but at the moment of time I did not have the experience with it, and now, when I actually have it – I would still go the virtual com path, usb has too much of the hustle to implement and handle nicely, besides it is not free for use as usual usb.
We will be using interrupts to control the virtual com port:
if (RCIF) { if (!UartBytes[0]) UartBytes[0] = getch(); else { UartBytes[1] = getch(); UartRecieve = 1; } }
The RCIE has been enabled before, of coarse. For the data exchange I created two variables in the UartBytes array – the first one is a command and the second one is the value. After the second variable value is acquired the UartRecieve flag is settled. This is handled then in the main cycle.
if (UartRecieve) { temp = UartBytes[0]; ComByte = UartBytes[1]; UartBytes[0] = 0; UartBytes[1] = 0; UartRecieve = 0; switch (temp) { case 49 : SetHour(ComByte); //установка часов break; case 50 : SetMin(ComByte); //установка минут break; case 51 : SetSeconds(ComByte); //установка секунд break; case 52 : if (ComByte < 10) //установка громкости volume = ComByte; else volume = 100 - ComByte; VL(volume); VR(volume); break;</pre> case 53 : if (ComByte <= 15) //установка басов bass = ComByte; else bass = 100 - ComByte; BassSetup(bass); break; case 54 : if (ComByte <= 12) //установка тембра treble = treble; else treble = 100 - treble; break; case 55 : if (ComByte == 0xFF) //приглушение mute(); else { TRISB2 = 1; TRISB1 = 1; volume_flag = 1; bass_flag = 0; treble_flag = 0; source_flag = 0; mode_flag = 0; menu(0); muteIR = 0; } break; case 56 : SwFuncByte = ComByte; //источник и режим I2CStart(); I2CSend(0x82); I2CSend(0x08); I2CSend(SwFuncByte); I2CStop(); break; case 57 : //Alarm //будущая функция будильника break; case 58 : //StBy //будущая функция режима ожидания break; case 59 : //Radio //будущее радио break; case 60 : printf("\r\n%d", ReadHour()); //читаем часы break; case 61 : printf("\r\n%d", ReadMin()); //читаем минуты break; case 62 : printf("\r\n%d", ReadSeconds()); //читаем секунды break; case 63 : printf("\r\n%d", volume); //читаем громкость break; case 64 : printf("\r\n%d", bass); //читаем басы break; case 65 : printf("\r\n%d", treble); //читаем тембр break; case 66 : printf("\r\n%d", SwFuncByte); //читаем источник и режим break; case 67 : printf("\r\nalarm"); //читаем будильник break; case 68 : printf("\r\nstby"); //читаем в режиме ожидания мы или нет break; case 69 : printf("\r\nradio"); //читаем радиостанцию break; } }
I decided also to add the alarm, which can be settled to play the radio station – the real one or the internet radio station, just dreaming now I guess…
I also caught a bug, when I was compiling the code I got the “Possible hardware stack overflow” warning which I ignored firstly. But after more and more command have been added I started to get random symbols flying everywhere – LCD and the terminal, all magically fixed and disappeared as soon as I got rid of those warnings.
Now, the EEPROM turn, what do we need to save?
1. Volume
2. Bass
3. Treble
4. SwFuncByte value (the source, the mode and mute status)
5. StBy status
6. Alarm time
7. Radio station
For the beginning I took first 4 items and wrote their value to EEPROM by standard functions, like that:
eeprom_write(0x00, 0x02); //volume eeprom_write(0x01, 0x00); //bas eeprom_write(0x02, 0x00); //treble eeprom_write(0x03, 0b11001110); //SwFuncByte
Checking after the uC restart:
Looks right, now lets move it to a separate function.
void SaveState() //Сохранение значений в EEPROM { eeprom_write(0x00, volume); //volume eeprom_write(0x01, bass); //bass eeprom_write(0x02, treble); //treble eeprom_write(0x03, SwFuncByte); //SwFuncByte }
Now we need to create the init function which will include the eeprom reading:
void InitAmp() //Инициализаця рабочих переменных из EEPROM { volume = eeprom_read(0x00); bass = eeprom_read(0x01); treble = eeprom_read(0x02); SwFuncByte = eeprom_read(0x03); }
Still to decide when we should save values to the EEPROM.
A short demonstration: