Цитата(medved @ Mar 25 2007, 15:27)

Сразу вопрос: Формирование ведущим START-условие выполнено???" На Ведущем выполнена обработка прерывания после формирования старт условия (запись байта в регистр передачи)??? В каком состоянии на ведомом бит BF и SSPOV(SSPSTAT<0>,SSPSTAT<6>) перед приемом данных??? Формируется ли прерывание на ведомом (может просто не разрешил переферию)???? И если формируется, то что дает чтение SSРBUF на ведомом??? Как видите вопрос задан слишком обще, требуются уточнения.
Отвечу своими кодами )))
Это для главного
#include <16F873A.h>
#device ICD=TRUE
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES BROWNOUT //Reset when brownout detected
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#use delay(clock=8000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
//#use i2c(Master,Slow,sda=PIN_B1,scl=PIN_B4)
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3,force_hw)
void main()
{ BYTE data='5',data2,sec_data='1';
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
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);
// enable_interrupts(INT_SSP);
// enable_interrupts(GLOBAL);
// TODO: USER CODE!!
while(true)
{
/*i2c_start(); // Issues a start command when in the I2C master mode.
// i2c_write(0xA0);// Device address
i2c_write(data); // Sends a single byte over the I2C interface.
i2c_stop(); //Issues a stop command when in the I2C master mode.
delay_ms(2);
data=data+1;
*/
/* i2c_start();
i2c_write(0xa0); // Device address
i2c_write(data); // Data to device
i2c_start(); // Restart
i2c_write(0xa1); // to change data direction
data2=i2c_read(0); // Now read from slave
i2c_stop();*/
//my
/* putc(data2-0x80);
printf(" ");
data++;
delay_ms(500);*/
////////////////////////// to secomd MCU
i2c_start();
i2c_write(0x14); // Device address
i2c_write(sec_data); // Data to device
i2c_start(); // Restart
i2c_write(0x15); // to change data direction
data2=i2c_read(0); // Now read from slave
i2c_stop();
//my
putc(sec_data-0x80);
printf("1 ");
sec_data++;
delay_ms(500);
}
}
Для слэйв МК-ов(я сделал пока тоже 873 так как в протэусе нет 818-го)
#include <16F873A.h>
#device ICD=TRUE
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES DEBUG //Debug mode for use with ICD
#FUSES BROWNOUT //Reset when brownout detected
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#use delay(clock=8000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
//#use i2c(Slave,sda=PIN_B1,scl=PIN_B4,address=0xA0)
#use i2c(Slave,Fast,sda=PIN_C4,scl=PIN_C3,force_hw,address=0xa0)
int1 InterruptWAS=0,KOTdata=0;
BYTE KOTObuf;
#INT_SSP
void ssp_interupt ()
{
BYTE incoming, state;
state = i2c_isr_state();
if(state < 0x80) //Master is sending data
{
incoming = i2c_read();
/* if(state == 1) //First received byte is address
address = incoming;
if(state == 2) //Second received byte is data
buffer[address] = incoming;*/
KOTObuf=incoming;
}
if(state == 0x80) //Master is requesting data
{
//i2c_write(buffer[address]);
//my
i2c_write(KOTObuf);
KOTdata=1;
}
InterruptWAS=1;
}
void main()
{ //int8 out_value=0;
//int i;
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
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);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
// TODO: USER CODE!!
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
while (TRUE)
{ while(InterruptWAS)
{ //printf("s");
if(KOTdata)putc(KOTObuf);
output_a(0b01010101);
output_toggle(PIN_B5); //Mignem Diodom
InterruptWAS=0;
KOTdata=0;
}
}
}
Из выше вставленного точно выполняется:
1. Переход в прерывание от SSP(в данном случае I2C)
2.Передаются и принимаются данные со слэйв контроллера, но при передаче на main почему-то к символу прибавляется 0х80(в HEX) при передаче букв, а с цифрами всё нормально.
Не могу сделать:
Для второго слэйва в программе меняется только адресс(скажем 0x15) и при передаче с главного на оба контроллера поочереди вызывает белеберду какую-то.
Проблема где то тут(вроде ) Я не понимаю участок кода(он из примера) про инициализацию приёма данных slave->master с master контроллера:
i2c_write(0xa1); // to change data direction непонимаю почему 41???
data2=i2c_read(0); // Now read from slave
С одним контроллером ругаться уже по I2C можно, только какие адреса допустимы и как реализовать общеее сообщение???? (я понял что надо адресс 0х00 и тогда все долны слушать)
ВотЪ