Jump to content
Sign in to follow this  
eternal_ego

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

Recommended Posts

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

Имеется контроллер 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

Edited by eternal_ego

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...