Hola compañeros.
Aunque este es un tema ya muy trillado, apenas me inicié hace poco en el uso de este protocolo. Despues de muchos dolores de cabeza, por fin pude comunicar los dos pic.
Las conexiones son por defecto del spi1.
MAESTR0:
#include <16F1827.h>
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
//#FUSES PLL_SW //PLL Off
#FUSES PLL //PLL On
#FUSES NOWDT //No Watch Dog Timer
#FUSES PUT //Power Up Timer
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES PROTECT //Code protected from reads
#FUSES NOCPD //No EE protection
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOCLKOUT //No out clock
#FUSES NOIESO
#FUSES NOFCMEN
#FUSES WRT
#FUSES NOSTVREN
#FUSES BORV25
#FUSES NODEBUG
#FUSES NOLVP
//#use fast_io(A) con esta directiva no funciona
//#use fast_io(B)
#USE STANDARD_IO(A)
#USE STANDARD_IO(B)
#use delay(int=32000000)
#byte PORTA = 0x0C // Registro de direccionamiento Puerto A
#byte PORTB = 0x0D // Registro de direccionamiento Puerto B
#byte LATA = 0x10C // Registro de direccionamiento Puerto A
#byte LATB = 0x10D // Registro de direccionamiento Puerto B
#define k_tmr2 1000
#rom 0xF000={00}
#rom 0xF001={2}
#define LCD_DB4 PIN_B7
#define LCD_DB5 PIN_B6
#define LCD_DB6 PIN_A7
#define LCD_DB7 PIN_A4
#define LCD_RS PIN_A1
#define LCD_E PIN_A0
#include <flex_lcd1.c>
#define CS pin_B5 // CS pin
int8 dato_tx,dato_rx;
int8 segundos,medio_seg,s_segundos;
int16 v_tmr2;
#INT_TIMER2
void timer2_isr(){
v_tmr2++;
if (v_tmr2>=k_tmr2){
v_tmr2=0;
segundos++;
if (segundos>59){
segundos=0;
}
if (v_tmr2==500)medio_seg++;
if (v_tmr2==0)medio_seg++;
}
}
void limpiar_lcd(){
lcd_putc("\f"); //Limpia LCD
}
void pant_ppal(){
limpiar_lcd();
lcd_putc("Spi master\n");
lcd_putc("Esperando...");
}
void write_spi(int8 data_write){
output_low(CS); //CS = 0;
SPI_Write(data_write); // write data in register
output_high(CS); //;CS = 1;
}
int8 read_spi(){
int8 data_r = 0;
output_low(CS); //CS = 0;
data_r = SPI_Read(0); // read data from register
output_high(CS); // CS = 1;
return data_r;
}
///////////////////////////PROGRAMA PRINCIPAL///////////////////////////////////
void main(){
#ZERO_RAM
SET_TRIS_A(0b00100000);
SET_TRIS_B(0b00001011);
LATA=0;
LATB=0;
setup_comparator(NC_NC_NC_NC);
setup_spi(SPI_MASTER| SPI_SAMPLE_AT_END |SPI_DO_B2|SPI_SS_B5|SPI_CLK_DIV_64);
setup_dac(DAC_OFF);
setup_oscillator(OSC_8MHZ | OSC_NORMAL | OSC_PLL_ON);
setup_vref(VREF_OFF);
setup_adc(ADC_OFF);
setup_timer_2(T2_DIV_BY_4,124,16);
enable_interrupts(int_timer2);
enable_interrupts(global);
delay_ms(500);
lcd_init(); //Inicia LCD
pant_ppal();
while(true){ // Infinite loop
if (s_segundos!=segundos){
s_segundos=segundos;
write_spi(dato_tx);
delay_us(50);
dato_rx=read_spi();
lcd_gotoxy(14,1);
printf(lcd_putc, "%3u" ,dato_tx);
lcd_gotoxy(14,2);
printf(lcd_putc, "%3u" ,dato_rx);
dato_tx++;
}
}
}
------------------------------------------------------------------------------------------------------------------------------
ESCLAVO:
#include <16F1827.h>
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES PLL //PLL On
#FUSES NOWDT //No Watch Dog Timer
#FUSES PUT //Power Up Timer
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES PROTECT //Code protected from reads
#FUSES NOCPD //No EE protection
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOCLKOUT //No out clock
#FUSES NOIESO
#FUSES NOFCMEN
#FUSES WRT
#FUSES NOSTVREN
#FUSES BORV25
#FUSES NODEBUG
#FUSES NOLVP
//#use fast_io(A)
//#use fast_io(B)
#USE STANDARD_IO(A)
#USE STANDARD_IO(B)
#use delay(int=32000000)
#byte PORTA = 0x0C // Registro de direccionamiento Puerto A
#byte PORTB = 0x0D // Registro de direccionamiento Puerto B
#byte LATA = 0x10C // Registro de direccionamiento Puerto A
#byte LATB = 0x10D // Registro de direccionamiento Puerto B
#byte SSP1BUF = getenv("SFR:SSP1BUF")
#define k_tmr2 1000
#define LCD_DB4 PIN_B7
#define LCD_DB5 PIN_B6
#define LCD_DB6 PIN_A7
#define LCD_DB7 PIN_A4
#define LCD_RS PIN_A1
#define LCD_E PIN_A0
#include <flex_lcd1.c>
int8 dato_tx,dato_rx,var;
int8 segundos,medio_seg,estado_rx;
int16 v_tmr2;
#INT_TIMER2
void timer2_isr(){
v_tmr2++;
if (v_tmr2>=k_tmr2){
v_tmr2=0;
segundos++;
if (segundos>59){
segundos=0;
}
if (v_tmr2==500)medio_seg++;
if (v_tmr2==0)medio_seg++;
}
}
void limpiar_lcd(){
lcd_putc("\f"); //Limpia LCD
}
void pant_ppal(){
limpiar_lcd();
lcd_putc("Spi slave\n");
lcd_putc("Esperando...");
}
///////////////////////////PROGRAMA PRINCIPAL///////////////////////////////////
void main(){
#ZERO_RAM
SET_TRIS_A(0b00100000);
SET_TRIS_B(0b00111011);
LATA=0;
LATB=0;
setup_comparator(NC_NC_NC_NC);
setup_dac(DAC_OFF);
setup_oscillator(OSC_8MHZ | OSC_NORMAL | OSC_PLL_ON);
setup_vref(VREF_OFF);
setup_adc(ADC_OFF);
setup_timer_2(T2_DIV_BY_4,124,16);
enable_interrupts(int_timer2);
enable_interrupts(global);
delay_ms(500);
lcd_init(); //Inicia LCD
pant_ppal();
//setup_spi(SPI_SLAVE| SPI_XMIT_H_TO_L |SPI_DO_B2|SPI_SS_B5); // No funciona!!!
setup_spi(SPI_SLAVE| SPI_SAMPLE_AT_MIDDLE|SPI_DO_B2|SPI_SS_B5); // Funciona!!!
while(true){
if (spi_data_is_in()){
if (estado_rx==0){
dato_rx=SPI_Read();
dato_tx=dato_rx+20;
SSP1BUF=dato_tx;
estado_rx=1;
}else if (estado_rx==1){
var=SPI_Read();
estado_rx=0;
lcd_gotoxy(14,1);
printf(lcd_putc, "%3u" ,dato_rx);
lcd_gotoxy(14,2);
printf(lcd_putc, "%3u" ,dato_tx);
}
}
}
}