|
Проблема с I2C в MSP430F2617, Протокол не функционирует как положено. |
|
|
|
Oct 6 2010, 13:02
|

Участник

Группа: Участник
Сообщений: 27
Регистрация: 28-04-10
Из: город Харьков
Пользователь №: 56 948

|
Пришлось по необходимости заняться МК MSP430F2617. К счастью, для чайников в среде IAR есть примеры. Все примеры удалось запустить и отработать, кроме примера по I2C, хотя он там нужен. Привожу код в примере #include "msp430x26x.h"
unsigned char TXData; unsigned char TXByteCtr;
void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT P3SEL |= 0x06; // Assign I2C pins to USCI_B0 UCB0CTL1 |= UCSWRST; // Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz UCB0BR1 = 0; UCB0I2CSA = 0x48; // Slave Address is 048h UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation IE2 |= UCB0TXIE; // Enable TX interrupt
TXData = 0x01; // Holds TX data
while (1) { TXByteCtr = 1; // Load TX byte counter while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts // Remain in LPM0 until all data // is TX'd TXData++; // Increment data byte } }
//------------------------------------------------------------------------------ // The USCIAB0TX_ISR is structured such that it can be used to transmit any // number of bytes by pre-loading TXByteCtr with the byte count. //------------------------------------------------------------------------------ #pragma vector = USCIAB0TX_VECTOR __interrupt void USCIAB0TX_ISR(void) { if (TXByteCtr) // Check TX byte counter { UCB0TXBUF = TXData; // Load TX buffer TXByteCtr--; // Decrement TX byte counter } else { UCB0CTL1 |= UCTXSTP; // I2C stop condition IFG2 &= ~UCB0TXIFG; // Clear USCI_B0 TX int flag __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 } }
В комментарии указано: "Этот демо связывает два MSP430 по шине I2C. Мaster передает slave. Это код для master. Он постоянно передает 00h, 01h, ..., 0ffh и демонстрирует, как подключить I2C master transmitter для передачи одного байта using прерывание USCI_B0 TX." Так вот, я запустил этот пример, и он НЕ работает так, как написано в комментарии. В чем может быть дело?
|
|
|
|
|
 |
Ответов
|
Oct 6 2010, 13:22
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Во-первых, нужно напомнить, что шина I2C обязательно требует pull-up резисторов на обеих линиях (SCL и SDA). Во-вторых, этот пример слишком упрощен. Автомат состояний шины I2C гораздо сложнее и в идеале его нужно реализовывать полностью (назначить действие для каждого возможного варианта состояния шины). В-третьих, нужно обязательно реализовать функцию Bus clear, описанную в спецификации I2C, вызываемую по тайм-ауту неактивности занятой шины. С такой необходимостью мы сталкивались неоднократно и поэтому реализуем ее всегда. Как минимум один раз, после подачи питания на устройства, подключенные к шине I2C, функцию Bus clear необходимо вызывать всегда.
|
|
|
|
|
Oct 6 2010, 14:19
|

Участник

Группа: Участник
Сообщений: 27
Регистрация: 28-04-10
Из: город Харьков
Пользователь №: 56 948

|
Цитата(rezident @ Oct 6 2010, 16:22)  Во-первых, нужно напомнить, что шина I2C обязательно требует pull-up резисторов на обеих линиях (SCL и SDA). Во-вторых, этот пример слишком упрощен. Автомат состояний шины I2C гораздо сложнее и в идеале его нужно реализовывать полностью (назначить действие для каждого возможного варианта состояния шины). В-третьих, нужно обязательно реализовать функцию Bus clear, описанную в спецификации I2C, вызываемую по тайм-ауту неактивности занятой шины. С такой необходимостью мы сталкивались неоднократно и поэтому реализуем ее всегда. Как минимум один раз, после подачи питания на устройства, подключенные к шине I2C, функцию Bus clear необходимо вызывать всегда. Может, он и упрощен, но делать то, что указано в комментарии, он обязан (я так полагал). Но он вообще заходит в прерывание один раз, а потом "уходит в подполье", откуда его отладчиком IAR не вытащить. А эта функция BUS CLEAR, она описана в спецификации? Очевидно, имеются в виду внешние - на плате - резисторы, подтягивающие провода SCK и SDA к напряжению питания, то есть к "1"?
|
|
|
|
|
Oct 6 2010, 14:29
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Lemist @ Oct 6 2010, 19:53)  Может, он и упрощен, но делать то, что указано в комментарии, он обязан (я так полагал). Но он вообще заходит в прерывание один раз, а потом "уходит в подполье", откуда его отладчиком IAR не вытащить. Поясните более понятно, что именно не работает? Активности на шине I2C никакой нету? Или дебаггер не работает? Если только второе, то уберите из программы все команды перехода в режим энергосбережения. То бишь команду Код __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts замените на Код __bis_SR_register(GIE); // Enable interrupts Цитата(Lemist @ Oct 6 2010, 19:53)  А эта функция BUS CLEAR, она описана в спецификации? Да, конечно же. Раздел 3.16 Bus clear. Для выведения зависшего слейва из "ступора" и разблокирования шины SDA необходимо, не создавая старт- или стоп-условий, сгенерировать на шине SCL не менее 9 тактовых импульсов. Для этого в MSP430 удобнее перепрограммировать пин к которому подключена SCL как GPIO в режиме вывода и выдать последовательность из 9 тактовых импульсов частотой не выше 400кГц или 100кГц (в зависимости от типа подключенных устройств). После этого можно перевести пин обратно на функцию SCL и начать новую передачу. Цитата(Lemist @ Oct 6 2010, 20:19)  Очевидно, имеются в виду внешние - на плате - резисторы, подтягивающие провода SCK и SDA к напряжению питания, то есть к "1"? Да, внешние. Внутренние pull-up не позволяют работать на высокой скорости.
|
|
|
|
Сообщений в этой теме
Lemist Проблема с I2C в MSP430F2617 Oct 6 2010, 13:02 Lemist Гм, все оказалось донельзя тривиально. Как только ... Oct 6 2010, 16:26 Lemist Цитата(Lemist @ Oct 6 2010, 19:26) Гм, вс... Oct 7 2010, 10:12 rezident А 100кГц не устроит?
Код#define PIN_SCL (1U... Oct 7 2010, 12:08 Lemist Спасибо за код, должен сказать, что ничего военног... Oct 7 2010, 13:36 rezident Цитата(Lemist @ Oct 7 2010, 19:36) Вот та... Oct 7 2010, 16:29  Lemist Цитата(rezident @ Oct 7 2010, 19:29) Как ... Oct 8 2010, 08:14 Lemist Извините, что столь неугомонен, но с обменом по пр... Oct 8 2010, 11:57 rezident Цитата(Lemist @ Oct 8 2010, 17:57) Об это... Oct 8 2010, 12:06  Lemist Цитата(rezident @ Oct 8 2010, 15:06) Уваж... Oct 8 2010, 12:23   rezident Цитата(Lemist @ Oct 8 2010, 18:23) Как из... Oct 8 2010, 14:28   =DS= Разработчики USART MSP430 2xx заложили в него 2 ид... Oct 9 2010, 02:07    rezident Цитата(=DS= @ Oct 9 2010, 08:07) Кстати, ... Oct 9 2010, 18:49
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|