Код слейва:
Код
#include <xc.h>
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config VCAPEN = OFF // Voltage Regulator Capacitor Enable bit (VCAP pin function disabled)
#pragma config STVREN = OFF // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#define _XTAL_FREQ 8000000
#define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
#define __delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4.0)))
unsigned char Tmp;
void interrupt isr(void)
{ if (SSPIF)
{ Tmp=SSPBUF;
SSPIF=0;
}
if (BCLIF)
{ Tmp=1;
BCLIF=0;
}
}
void main(void)
{ OSCCON = 0b01110010; // Internal OSC @ 8MHz
ADCON0bits.ADON=0; //ADC disable
ANSELC=0; //ADC mode of Pin disable;
SSPCON1=0b00110110; //I2C slave 7-bit adress, SCL release control
SSPCON2=0b00000001; //stretch enabled
SSPCON3=0b00011100; //Buffer overvrite enable, SDAHT=1, Slave bus col ena
SSPSTAT=0b10000000; //slew rate control disabled
SSPADD=0x30; //adress
SSPIF = 0; // Clear the serial port interrupt flag
BCLIF = 0; // Clear the bus coll interrupt flag
BCLIE = 1; // Enable bus collision interrupts
SSPIE = 1; // Enable serial port interrupts
PEIE = 1; // Enable peripheral interrupts
GIE = 1; // Enable global interrupts
PORTC = 0x00; // Clear PORTC
LATC = 0x00; // Clear PORTC latches
TRISC = 0b00011000; // Set RC3, RC4 as inputs for I2C
PORTB=0x00;
LATB=0x00;
TRISB=0x00;
PORTA=0x00;
LATA=0x00;
TRISA=0x00;
__delay_ms(500);
do{
PORTAbits.RA5=1; //green led
__delay_ms(100);
PORTAbits.RA5=0;
__delay_ms(100);
}while(1);
}
Делается однократный кадр:

Причем SCL в нуле точно удерживает слейв. Куда бы посмотреть?
Цитата(Voldemari4 @ Jun 2 2014, 10:02)

Добавьте ожидание пока SEN и PEN обнуляться. А то у вас получается еще стоповое событие не закончилось, а вы уже старт опять начинаете.
Да-да, тоже верно!
Код
do{
SSPCON2bits.SEN = 1; // set start bit
do{}while(SSPCON2bits.SEN);
do{}while(!Tmp);
Tmp=0;
SSPBUF=0x30;
do{}while(!Tmp);
Tmp=0;
SSPBUF=0x55;
do{}while(!Tmp);
Tmp=0;
SSPCON2bits.PEN = 1; // set stop bit
do{}while(SSPCON2bits.PEN);
PORTBbits.RB4=1; //green led
}while(1);
Причем, нормально делает посылки если после старт бита именно оба условия есть. Если убрать ожидание флага прерывания, по в передаче только один байт адреса. А если убрать ожидание сброса старт бита, то в передаче только байт 0x55! Как такое поведение можно объяснить?
Надо вернуться к слейву и разобраться, почему он SCL удерживает (при подключенном слейве картинка не изменилась: старт, адрес и обе линии в нуле). // Тут, если включен SEN (затягивание передачи слейвом), то надо выставлять CKP после каждого приема байта.
В общем, передача идет.
Сообщение отредактировал animal - Jun 2 2014, 02:40