Поклонники продукции Microchip Technology Inc тусуются тут.
Ответить

Шина I2C и PIC18F45K22 - кто виноват- PIC или Я

Пт авг 14, 2020 10:42:07

Головоломка следующея
master (PIC18F45K50) -> slave (PIC18F45K22)

Master посылает данные (стандартные, я подключал трое девайса и они работает как надо):

i2c_start();
i2c_write(0xA4); // адрес Slave
i2c_write(0xF0); // запис регистъра на slave
i2c_repStart();
i2c_write(0xA5); // читание
data=i2c_read(0); // здесь Slave надо посылат данные
i2c_stop();

Slave:
PIC18F45k22, OSC = 16MHz, PLLx4 (т.е. 64МХц). Инициализация SSP1 (у него 2):

SSP1ADD = 0xA4; //Slave_address; //device address
SSP1CON1 = 0x36; //SSPEN =1 and set i2c to slave mode with 7 bit address
SSP1STAT = 0x00;
SSP1CON2 = 0x00;
SSP1CON3 = 0x00;
Я попробовал разные значения SSP1CON2 = 0x01; 0x81; SSP1CON3 = 0x30 и комбинации с ними.

Перерывы сделал ЗАПРЕТА.

Ну, написал код только для етого случая:

Код:
while(1)
{
   while (!SSP1STATbits.BF); // ждет първого байта
    temp = SSP1BUF;  // чтение первого байта (0хА4)
      SSP1CON1bits.CKP = 1;  // освобождение шин
   while (!SSP1STATbits.BF); // ждет второго байта
    temp = SSP1BUF;   // чтение второго байта (0хF0)
    SSP1CON1bits.CKP = 1; // освобождение шин
   while (!SSP1STATbits.BF); // ждет третого байта
    temp = SSP1BUF;  // чтение третого байта (0xA5)- команда за чтения для slave
      SSP1BUF = 0x44;  // зарежание буфера, я выбрал 0х44
       SSP1CON1bits.CKP = 1; // освобождение шин
    while (SSP1STATbits.BF); // ждем отправления байта
  led2s();  // включаем на 2с светодиод, что все прошло нормально, работает
};


С другими словами: мастер отправляет слейв-а: 0xA4;0xF0;0xA5 и ждет получения 0х44

Резултат: НЕТ
Изображение


Но, если выполнить это:
Код:
while(1)
{
   while (!SSP1STATbits.BF); // ждет първого байта
    temp = SSP1BUF;  // чтение первого байта (0хА4)
      SSP1CON1bits.CKP = 1;  // освобождение шин
   while (!SSP1STATbits.BF); // ждет второго байта
    temp = SSP1BUF;   // чтение второго байта (0хF0)
    SSP1CON1bits.CKP = 1; // освобождение шин
   while (!SSP1STATbits.BF); // ждет третого байта
    temp = SSP1BUF;  // чтение третого байта (0xA5)- команда за чтения для slave

         delay_uS(6);  // пауза, больше 6uS

      SSP1BUF = 0x44;  // зарежание буфера, я выбрал 0х44
       SSP1CON1bits.CKP = 1; // освобождение шин
    while (SSP1STATbits.BF); // ждем отправления байта
  led2s();  // включаем на 2с светодиод, что все прошло нормально, работает
};


все нормально:

Изображение


Я попробовал несколько настроек кварца 16МХц (PLL отключен), 8МХц- все так же.
Где я ошибаюсь или PIC что-то врет?
Если что-то не так- спрашивайте.

Re: Шина I2C и PIC18F45K22 - кто виноват- PIC или Я

Ср авг 19, 2020 16:05:42

Я понял кто виноват- никто, все верно. Вот что случилось:
Если пользоватся интерфейсом напрямо- нужна пауза длиной одного такта SCL. Я включил передатчик (master) на 500кГц и время ожидания уменшилось на 2мкс.
A для того, что у меня не делалась работа интерфейса внутри перерывания- причина прозаичная. Компилятор забыл вставить в конце обработки (ето самого перерыйрания) команда для возрата (RETFIE).
Также, у самого перерывание не нужно вставлять какое-то замедления, потому что сама обработка делает ето.
Ответить