eternal_ego

Nec 78K0R - Работа С I2C

1 сообщение в этой теме

eternal_ego    0

Доброе время суток :)

Имеется контроллер NEC uPD78F1146, отладчик Minicube (версия прошивки 5.00), среда разработки IAR (4.62.5.50016). Интересует интерфейс I2C, для работы с которым существует код-пример работы с сайта NEC. К сожалению, в работоспособности этого кода убедиться не удалось: после инициализации выполнение программы зацикливается навечно в ожидании флага IICIF0.

К сообщению приложен архивчик с примером от NEC.

Здесь приведу процедуру инициализации, как она есть у меня в проекте:

void i2c_init(void)

{

IIC0EN = 1;

IICX0 = 0x00;

IICCL0 = 0x0A;

/* CLD0=0: SCL0 pin was detected at low level

DAD0=0: SDA0 pin was detected at low level

SMC0=1: operates in fast mode

DFC0=0: digital filter off

CL01=1, CL00=0: transfer clock = fCLK/96 */

SVA0 = 0x00;

IICF0 = 0x00;

/* STCF=0: clear STT0 (start condition) flag

IICBSY=0: clear IICBSY (I2C bus status) flag

STCEN=0: after operation is enabled (IICE0=1), enable generation of a start condition upon detection of s stop condition

IICRSV=0: enable communication reservation */

IICC0 = 0x1C;

/* IICE0=0: stop I2C operation

LREL0=0: exit from communication: normal operation

WREL0=0: do not cancel wait

SPIE0=1: enable generation of interrupt request when stop condition is detected

WTIM0=1: interrupt request is generated at the ninth clock's falling edge

ACKE0=1: enable acknowledge

STT0=0: do not generate a start condition

SPT0=0: stop condition is not generated */

IICE0 = 1;

P6 = 0x00;

/* P61/SDA0 = low level

P60/SCL0 = low level */

PM6 &= 0xFE;

/* SCL0: output mode */

PM6 &= 0xFD;

/* SDA0: output mode */

IICIF0 = 0;

/* clear interrupt request flag (INTIIC0) */

if(STCEN == 1){

return;

}

SPT0=1;

while(IICIF0 == 0){

/* INTIIC0 occurs? */

__no_operation();

}

IICIF0 = 0;

}

Собственно, в последнем while код и зацикливается, IICIF0 не ставится в единицу. Почему - непонятно.

Прерывание по IIC0 заведено, но оно не вызывается:

#pragma vector=INTIIC0_vect

__interrupt static void i2c_interrupt(void)

{

i2c_int = true;

IICIF0 = 0;

}

Перед этим необходима настройка контроллера на осциллятор (используется внешний 20МГц), это сделано так:

OSMC = 0x01; // Operation speed mode control register

// frequency higher than 10MHz

// OSTS = 0x01; // Set osc. stabilization time selection

// to 2^18/fx

CMC = 0x51; // Clock operation mode register

// X1 osc. mode, XT1 osc. mode, fx > 10MHz

CKC = 0x08; // System clock control register

// fclk = fih

CSC = 0x00; // enable X1 , XT1 operation

while(OSTC < 0x80) // Wait until fX1 clock stabilization

{ // time has been elapsed

__no_operation();

}

OSTS = 0x07;

CKC = 0x18; // System clock control register

// fclk = fmx = 20MHz

CSC = 0x01;

__enable_interrupt();

Буду благодарен за помощь с разбирательством - что тут не так, и как заставить I2C работать :)

K0R_iic0_master_C_prj.zip

Изменено пользователем eternal_ego

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Быстрый заказ печатных плат

Полный цикл производства PCB по низким ценам!

  • x
    мм
Заказать Получить купон на $5.00

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас