#include <16F877A.h>
#device adc=8
#FUSES NOWDT, XT, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4000000)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
//Definimos los nombres de los puertos de salida.
#define CS PIN_D0
#define SDO PIN_D1
#define CLK PIN_D2
#define LOUD PIN_D3
#define RY_PW PIN_C5
#define RY_AU PIN_C6
#define TUNER PIN_C0
#define CD PIN_C1
#define PHONO PIN_C2
#define LINE PIN_C3
#define TAPE PIN_C4
//Declaración de variables
int key_val, keyboard, x, mode, vol=0, bass=125, treble=125, fun_u, fun_d, vol_u, vol_d;
int auxa, auxb, enca, encb, dc_det, oc_det;
int power=0, tp=0, ld=0, mt=0, a=0;
//Cargamos los drivers
#include <LCD420.C>
#include <AD5200.C>
#include <PROTECT.C>
//Iniciamos programa principal
void main(){
//Configuramos los pueros I/O
set_tris_A(1);
set_tris_B(0);
set_tris_C(0);
set_tris_D(0);
//Inicializamos las salidas en 0
output_c(0x00);
//Configuramos puertos analogicos
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
lcd_init();
for(;;){
//Leemos las condiciones del puerto A para los encoders y la protección del amplificador
//Lee el flanco de subida del selector de entradas.
set_adc_channel(0);
fun_u = read_adc();
//Lee el flanco de bajada del selector de entradas.
set_adc_channel(1);
fun_d = read_adc();
//Lee el flanco de subida del multicontrol de audio.
set_adc_channel(2);
vol_u = read_adc();
//Lee el flanco de subida del multicontrol de audio.
set_adc_channel(3);
vol_d = read_adc();
//Lee los botones del teclado.
set_adc_channel(4);
key_val = read_adc();
//Lee condiciones del detector de sobrecargas.
set_adc_channel(5);
oc_det = read_adc();
//Detectamos si hay DC en la salida.
set_adc_channel(6);
dc_det = read_adc();
//Lectura del teclado obteniendo el valor del ADC 3, usando un divisor de tensión.
if(key_val > 24 && key_val < 26){keyboard = 1;}
else if(key_val > 31 && key_val < 33){keyboard = 2;}
else if(key_val > 45 && key_val < 47){keyboard = 3;}
else if(key_val > 51 && key_val < 53){keyboard = 4;}
else if(key_val > 73 && key_val < 75){keyboard = 5;}
if(keyboard == 3 && power == 0){
output_high(RY_PW);
power = 1;
} //Power
else if(keyboard == 3 && power == 1){
output_low(RY_PW);
output_low(RY_AU);
power = 0;
}
//Encendemos el equipo
if(power == 1){
//Iniciamos la protección del amplificador
switch(protect(dc_det,oc_det)){
case 1:
//Si hay DC en la salida, se muestra un mensaje en pantalla y luego apaga el amplificador.
lcd_putc("\f");
output_low(RY_AU);
lcd_gotoxy(5,1);
printf(lcd_putc, "Protect!");
lcd_gotoxy(5,2);
printf(lcd_putc, "SHUTDOWN");
delay_ms(2000);
output_low(RY_PW);
power = 0;
break;
case 2:
//Esto apaga el relé de audio y vuelve a reponer el amplificador luego que a padado el peligro.
lcd_putc("\f");
output_low(RY_AU);
lcd_gotoxy(5,1);
printf(lcd_putc, "Protect!");
lcd_gotoxy(5,2);
printf(lcd_putc, "OVERLOAD");
break;
default:
//Si todo marcha bien, cargamos el mensaje de bienvenida.
//Esto evita que el mensaje se muestre una y otra vez después que ya inició el amplificador.
if(a == 0){
lcd_gotoxy(5,1);
printf(lcd_putc, "Welcome!");
delay_ms(3000);
output_high(RY_AU);
}
a = a+1;
break;
}
//Pasado el auto-test, iniciamos las funciones del amplificador.
//Obtenido los valores de los ADC 0 y 1, convertimos ambas entradas en un número binário.
if(fun_u<=1 && fun_d<=1){enca = 3;}
else if(fun_u<=1 && fun_d>=70){enca = 2;}
else if(fun_u>=70 && fun_d<=0){enca = 1;}
else{enca=0;}
//Obtenido el valor de entrada, procedemos a leer el encoder para el selector de entradas.
auxa = enca;
if((auxa == 2) && (enca == 3)){x++;} //Si el flanco es de subida, subimos un valor.
if((auxa == 3) && (enca == 2)){x--;} //Si el flanco es de bajada, restamos un valor.
if(x < 3){x=0;} //Si llega la última posición, volvemos al principio.
if(x > 0){x=3;} //Si llega la primera posición, volvemos al final.
//Tape control.
if(keyboard == 1 && tp == 0){
output_high(TAPE);
tp = 1;
}
else if(keyboard == 1 && power == 1){
output_low(TAPE);
tp = 0;
}
//Obtenido los valores del rotary encoder, lo cargamos para seleccionar las entradas.
switch(x){
case 1:
output_low(TUNER);
output_high(CD);
output_low(PHONO);
output_low(LINE);
if(tp == 1){
lcd_gotoxy(1,1);
printf(lcd_putc, "CD < Tape");
}
else{
lcd_gotoxy(1,1);
printf(lcd_putc, "CD");
}
break;
case 2:
output_low(TUNER);
output_low(CD);
output_high(PHONO);
output_low(LINE);
if(tp == 1){
lcd_gotoxy(1,1);
printf(lcd_putc, "Phono < Tape");
}
else{
lcd_gotoxy(1,1);
printf(lcd_putc, "Phono");
}
break;
case 3:
output_low(TUNER);
output_low(CD);
output_low(PHONO);
output_high(LINE);
if(tp == 1){
lcd_gotoxy(1,1);
printf(lcd_putc, "Line < Tape");
}
else{
lcd_gotoxy(1,1);
printf(lcd_putc, "Line");
}
break;
default:
output_high(TUNER);
output_low(CD);
output_low(PHONO);
output_low(LINE);
if(tp == 1){
lcd_gotoxy(1,1);
printf(lcd_putc, "Tuner < Tape");
}
else{
lcd_gotoxy(1,1);
printf(lcd_putc, "Tuner");
}
break;
}
//Obtenido los valores de los ADC 2 y 3, convertimos ambas entradas en un número binário.
if(vol_u<=1 && vol_d<=1){encb = 3;}
else if(vol_u<=1 && vol_d>=70){encb = 2;}
else if(vol_u>=70 && vol_d<=0){encb = 1;}
else{encb=0;}
//Estas son las funciones generales del control de audio.
//Si el MUTE está activado, se inhiben las funciones de audio.
if(mt == 0){
/*Función Loudness
Si presionamos el botón "Loudness", mostramos el mensaje en pantalla
y luego volvemos a carga el menú de control de audio. */
if(keyboard == 4 && ld == 0){
output_high(LOUD);
ld = 1;
lcd_gotoxy(1,2);
printf(lcd_putc, " Loudnees On ");
delay_ms(1000);
}
else if(keyboard == 4 && ld == 1){
output_low(LOUD);
ld = 0;
lcd_gotoxy(1,2);
printf(lcd_putc, " Loudnees Off ");
delay_ms(1000);
}
else{
//Si el botón de "Loudness" no está presionado, controlamos las opciones de audio.
//Menú de funciones de audio del multi jog.
//Selector de modo
if(keyboard == 5){
mode++;
if(mode > 3){mode = 0;}
}
switch(mode){
case 1:
//Control de bajos, obtenido a partir del valor del encoder B.
auxb = encb;
if((auxb == 2) && (encb == 3)){
if(bass == 256){bass = bass;}
else{bass = bass + 25;}
}
if((auxb == 3) && (encb == 2)){
if(bass == 0){bass = bass;}
else{bass = bass - 25;}
}
digi_pots(3,bass);
digi_pots(4,bass);
lcd_gotoxy(1,2);
printf(lcd_putc, "Bass %d dB",((bass-125)/10));
break;
case 2:
//Control de agudos, obtenido a partir del valor del encoder B.
auxb = encb;
if((auxb == 2) && (encb == 3)){
if(treble == 256){treble = treble;}
else{treble = treble + 25;}
}
if((auxb == 3) && (encb == 2)){
if(treble == 0){treble = treble;}
else{treble = treble - 25;}
}
digi_pots(1,treble);
digi_pots(2,treble);
lcd_gotoxy(1,2);
printf(lcd_putc, "Treble %d dB",((treble-125)/10));
break;
default:
//Control de volumen, obtenido a partir del valor del encoder B.
auxb = encb;
if((auxb == 2) && (encb == 3)){
if(vol == 256){vol = vol;}
else{vol = vol + 4;}
}
if((auxb == 3) && (encb == 2)){
if(vol == 0){vol = vol;}
else{vol = vol - 4;}
}
digi_pots(5,vol);
digi_pots(6,vol);
break;
}
}
}
//Función Mute
if((keyboard == 2 && mt == 0) || mt == 1){
digi_pots(5,0);
digi_pots(6,0);
mt = 1;
lcd_gotoxy(1,2);
printf(lcd_putc, " Mute ");
}
else if(keyboard == 2 && mt == 1){
digi_pots(5,vol);
digi_pots(6,vol);
mt = 0;
mode = 0;
lcd_gotoxy(1,2);
printf(lcd_putc, "Volume %d",((vol-0)/4));
delay_ms(1000);
}
else{
lcd_gotoxy(1,2);
printf(lcd_putc, "Volume %d",((vol-0)/4));
}
}
else{
output_low(RY_PW);
output_low(RY_AU);
a = 0;
}
}
}