Как-то замысловато вы проверяете флаг. Зачем инвертировать содержимое регистра при проверке всего лишь одного бита? Кроме затрудения понимания смыла это операция еще и оверхед на пару команд создает. Сравните сами
Код
// 55 while (~I2CIFG&ARDYIFG); // ВОТ ЗДЕСЬ ФЛАГ НЕ ВЫСТАВЛЯЕТСЯ (иногда реальные данные уходят и ложаться в микруху
??i2c_write_byte_0:
MOV.B &0x51, R11
XOR.B #0xff, R11
BIT.B #0x8, R11
JNE ??i2c_write_byte_0
Попробуйте написать попроще, например, так
Код
while ((I2CIFG&ARDYIFG)==0);
Получится
Код
// 55 while ((I2CIFG&ARDYIFG)==0); // ВОТ ЗДЕСЬ ФЛАГ НЕ ВЫСТАВЛЯЕТСЯ (иногда реальные данные уходят и ложаться в микруху
??i2c_write_byte_0:
BIT.B #0x8, &0x51
JNC ??i2c_write_byte_0
Явное сравнение с нулем всегда более корректно компилируется и более доступно для понимания смысла операции.
По самой проверке флага, который якобы не устанавливается.
Вы внимательно прочитали описание событий по которому ARDYIFG устанавливается? Раздел
15.2.8 I2C Interrupts из User's Guide.
Кроме того в строке
Код
I2CIE = RXRDYIE + RXRDYIE + NACKIE;
У вас дважды суммируется флаг RXRDYIE, что дает неправильную маску для I2CIE (0x22, вместо желаемых 0x12).
Вся процедура инициализации неправильно построена. См. пояснения в разделе
15.2.1 I2C Module Initialization из User's Guide. Там приведен вполне конкретный порядок для инициализации регистров USART в режиме I2C.
Ну и другое по мелочи. Типа вроде как используете прерывания, а процедуру обработки прерываний от I2C здесь не привели.