Hola amigos,
Estoy tratando de comunicar dos 16f876 por medio de SPI (pq ademas quiero grabar una MMC con SPI) usando CCS. Logro enviar datos desde el maestro a esclavo sin ningún problema, pero no he podido lograr que el esclavo responda al maestro de forma adecuada. La idea es enviar un número al PIC esclavo y que este responda de acuerdo a ello. El PIC maestro aumenta un contador al recibir una interrupción del puerto B y envía dicho número al PIC esclavo, esto funciona sin ningún problema.
Ahora bien, de acuerdo al número que recibe el esclavo, debe enviar un valor de vuelta al PIC maestro que obtiene de un arreglo. Que es lo que no funciona.
Traté de simular un modo "framed SPI" utilizando un PIN extra (RC6) para hacer que cuando sea HIGH el PIC maestro envíe el clock de lectura (spi_read()). El PIC maestro lee el bit "framed" como otra interrupción en el puerto B (RB5). En el fondo con esto hago que el esclavo solicite un clock de lectura. Sin embargo esto no me ha funcionado. Les adjunto el código.
MAESTRO
#include "H:\Diseño\LCD\testSPI_2\master_3.h"
#include <stdio.h>
#include "H:\Diseño\LCD\testSPI_2\flex_lcd_2.c"
char text0[]="\fSend1:";
char text1[3];
char text2[]="Rec1:";
int data_in=0, linea=0, flag=0, data=0;
int index[]={0,0};
byte port_b, last_b;
void print_linea(int lin, int data);
//void linea2();
#int_RB
void RB_isr()
{
byte changes;
port_b=input_b();
changes = last_b ^ port_b;
last_b = port_b;
if (bit_test(changes,4) && !bit_test(last_b,4))
{
linea=1;
flag=2;
}
if (bit_test(changes,5) && !bit_test(last_b,5))
{
data_in=spi_read(0);
}
// delay_ms(200); //Desahbilita la interrupcion del flanco de bajada.
}
#int_EXT
void EXT_isr()
{
linea=0;
flag=1;
}
void print_linea(int lin, int data)
{
if(index[lin]==6) index[lin]=0;
spi_write(index[lin]);
sprintf(text1,"%2d",data);
lcd_put_string_xy(text1,10,lin+1);
index[lin]++;
}
void main()
{
lcd_init();
lcd_setcursor(0,0);
last_b=input_b();
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
enable_interrupts(INT_RB);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
lcd_put_string(text0);
lcd_put_string_xy(text2,1,2);
sprintf(text1,"%2d",index[0]);
lcd_put_string_xy(text1,10,1);
sprintf(text1,"%2d",index[1]);
lcd_put_string_xy(text1,10,2);
//data_in=spi_read(0);
while(1)
{
if(flag==1)
{
print_linea(linea, data_in);
flag=0;
}
if(flag==2)
{
print_linea(linea, data_in);
flag=0;
}
}
}
ESCLAVO
#include "H:\Diseño\LCD\testSPI_2\slave_3.h"
#include <stdio.h>
#include "H:\Diseño\LCD\testSPI_2\flex_lcd_2.c"
int index;
int data_out[]={2,4,6,8,10};
char text1[3];
char text2[]="\fRecibido:";
char text3[]="Enviado:";
void outspi();
#int_SSP
SSP_isr()
{
if(spi_data_is_in()) index=spi_read();
sprintf(text1,"%2d",index);
lcd_put_string_xy(text1,10,1);
}
void outspi()
{
spi_write(data_out[index]);
output_high(PIN_C6);
output_low(PIN_C6);
}
void main()
{
lcd_init();
lcd_setcursor(0,0);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(SPI_SLAVE|SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
lcd_put_string(text2);
lcd_put_string_xy(text3,1,2);
spi_write(data_out[index]);
while(1)
{
// outspi();
}
}
Ojalá alguno de ustedes me peuda ayudar. Se me olvidaba utilizo la flex_lcd_2.c configurada como 6 pines del puerto A en orden correlativo.
Saludos!!!