реклама на сайте
подробности

 
 
> MSP430 I2C & RTC зависаю на while ((~I2CIFG) &ARDYIFG);, Не выставляется флаг ...иногда
Bom_Shankar
сообщение Mar 12 2007, 17:00
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 20
Регистрация: 15-12-06
Пользователь №: 23 554



Уважаемые знатоки...внимание вопрос.
Почему-то первый раз проходя в отладчике это место, флаг выставляется, но в real-time не выставляется, и после второго раза пошагового исполнения всё равно зависаю на ожидании флага.
Вот код, может у меня глаз замылился уже, подскажите кто видит ошибку.
void i2c_write_byte (unsigned char SlaveAddress, unsigned char Addr, unsigned char Byte)
{
I2CIE |= TXRDYIE;
I2CIFG &= ~ARDYIFG;
I2CIFG &= ~TXRDYIFG;
I2CIFG &= ~RXRDYIFG;
i2c_finish = 0;
I2CSA = SlaveAddress;
I2CNDAT = 0x02;
i2c_tx_n = 1;
U0CTL |= MST;
i2c_buf[0] = Byte;
i2c_buf[1] = Addr;
I2CTCTL |= I2CTRX + I2CSTT;
while ((~I2CIFG) &ARDYIFG); // ВОТ ЗДЕСЬ ФЛАГ НЕ ВЫСТАВЛЯЕТСЯ (иногда реальные данные уходят //и ложаться в микруху
while (i2c_finish == 0);
}

void init_i2c(void)
{
P3SEL |= 0x0a; // Assign I2C pins to module
U0CTL |= I2C + SYNC ; // Switch USART0 to I2C mode
U0CTL &= ~I2CEN; // Recommended I2C init procedure
I2CTCTL = I2CSSEL_1; // ACLK
I2CPSC = 0x00; // I2C prescaler
I2CSCLH = 40; // High period of SCL
I2CSCLL = 40; // Low period of SCL // 7372800 / 22 = 335khz
I2CIE = RXRDYIE + RXRDYIE + NACKIE;
U0CTL |= I2CEN; // Enable I2C, 7 bit addr,
_EINT(); // Enable interrupts
}


Заранее большое спасибо.
shanti_shanti@mail.ru
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
rezident
сообщение Mar 12 2007, 19:24
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Как-то замысловато вы проверяете флаг. Зачем инвертировать содержимое регистра при проверке всего лишь одного бита? Кроме затрудения понимания смыла это операция еще и оверхед на пару команд создает. Сравните сами
Код
//   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 здесь не привели.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 18:52
Рейтинг@Mail.ru


Страница сгенерированна за 0.01349 секунд с 7
ELECTRONIX ©2004-2016