Перейти к содержанию

eternal_ego

Members
  • Постов

    1
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные eternal_ego

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

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

×
×
  • Создать...