|
странности в работе f5437a |
|
|
|
Dec 3 2013, 11:38
|
Местный
  
Группа: Участник
Сообщений: 314
Регистрация: 27-04-10
Пользователь №: 56 923

|
Здравствуйте!прошу помочь советом или направить в нужное русло, потому как у самого идеи уже кончились. был проект на 149-м MSP, переделали его под msp430f5437a, соответственно ничего существенного в коде программы не меняли, только ноги и некоторые названия регистров, и само собой, настройка PMM. проблема такова- есть прерывания по uart rx и tx, при срабатывании RX (прием кадра modbus ascii) кадр принимается нормально (несколько символов), затем по программе должен формироваться кадр ответа, но программа не доходит до нужной подпрограммы, она просто зависает каждый раз в разных местах, но чаще всего на обработке TX (даже когда прерывание TX я специально отключаю!). повторюсь-в коде ничего существенно не меняли. работал с отладчиком TI USB-FET. скорость uart 115200, пробовал и 9600. (но похоже он тут ни при чем) короче, в итоге устройство абсолютно нерабочее! прошу, подскажите пож. может кто-то испытывал подобные трудности. кристалл работал вначале от внешнего резонатора 25 Мгц, после проявления вышеописанных проблем я перевел его на DCO (2 мгц), стало лучше, но выполнение программы заканчивается все равно раньше конца подпрограммы (я смотрел пошагово отладчиком). может у кого были похожие симптомы? незнаю уже на кого грешить. спасибо всем
Сообщение отредактировал shide_3 - Dec 3 2013, 11:39
|
|
|
|
|
Dec 3 2013, 15:20
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(shide_3 @ Dec 3 2013, 16:38)  был проект на 149-м MSP, переделали его под msp430f5437a, соответственно ничего существенного в коде программы не меняли, только ноги и некоторые названия регистров, и само собой, настройка PMM. В MSP430F149 UART реализуется в модуле USART, а в MSP430F5438A UART в модуле USCI. У этих модулей, кроме названий регистров, немало и других отличий. Поэтому код, разработанный для USART, даже после переименования регистров, не будет рабоать с модулем USCI. Цитата из документа, описывающего переход от USART к USCI Migrating From MSP430F13x/14x to MSP430F23x/24x Цитата 3.2.1 UART Mode The operation of the MSP430F23x/24x USCI in UART mode and that of the MSP430F13x/14x USART are almost identical. The major differences are: • The MSP430F23x/24x USCI uses a different baud rate generator. It utilizes a new modulation scheme, provides a two-stage modulator, and can be used to implement an oversampling baud rate generation scheme. During application migration, the baud rate register settings need to be recalculated. However, it is safe to say that the USCI module can be used to generate the same target baud rate using the same clock source that the MSP430F13x/14x USART would be able to provide. • The start edge detection and clock activation schemes are different on the two devices. The MSP430F23x/24x features a simplified scheme whereby the USCI module automatically activates the USCI module clock source upon start edge detection and then provides an interrupt to wake up the CPU after the entire character has been received. On the MSP430F13x/14x UART, an interrupt is generated directly upon start edge detection, the application needs to handle the clock source activation itself, and then, as a second step, the character reception. • On the MSP430F23x/24x USCI, interrupt flags are no longer cleared automatically upon entering the interrupt service routine. Если хотите конкретной помощи. то приводите ваш код для инициализации USCI (конечно, если это не ASM  ).
|
|
|
|
|
Dec 3 2013, 15:28
|
Местный
  
Группа: Участник
Сообщений: 314
Регистрация: 27-04-10
Пользователь №: 56 923

|
void UART_Init(unsigned long BaudRate,unsigned char MbMode) { UCA0CTL1 |= UCSWRST; // **Put state machine in reset** UCA0CTL0 |= UCSPB + UC7BIT;//UCPEN + UCPAR ;//+ UCA0CTL1 |= UCSSEL_2; // SMCLK UCA0BR0 = 109;//0xD9;//109;//;//27 // 25MHz 115200 (see User's Guide) UCA0BR1 = 0;//0; // 25MHz 115200 UCA0MCTL |= UCBRS_2;//|= UCBRS_2; // UCA0MCTL |= UCBRS_4 + UCBRF_1 + UCOS16; // Modulation UCBRSx=1, UCBRFx=0 UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** UCA0IE |= UCRXIE ;//+ UCTXIE; // Enable USCI_A0 RX interrupt
// __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, interrupts enabled // __no_operation(); // For debugger
}//сейчас скорость 9600 от DCO 1048576 hz.
А,кстати, интеррапт флаги usci автоматически сбрасываются. это видно в отладке
вот инициализация остального:
void Peripheral_Setup(void) { unsigned int i;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT //============================================================================== // Perepherial setup // //============================================================================== P1SEL = 0x00; // no alt. functions P1OUT = 0x00; P1DIR = 0xFF; P2SEL = 0x00; // no alt. functions P2DIR = 0x00; // input direction
P3SEL = 0x00; // no alt. functions P3DIR = 0x00; P3SEL = bmTxD | bmRxD; // USART0 TXD/RXD alt. functions P3DIR = bmTxD; //TxD - out; RxD - in /////////////////////////////////////////////////////////////// //SetVcore (0x03); // UCSCTL6 &= ~XT2OFF; // Enable XT2 UCSCTL3 |= SELREF_2; // FLLref = REFO // Since LFXT1 is not used, // sourcing FLL with LFXT1 can cause // XT1OFFG flag to set UCSCTL4 |= SELA_2 + SELS_3 + SELM_3; // ACLK=REFO,SMCLK=DCO,MCLK=DCO UCSCTL6 &= ~XT2DRIVE_3; // Clear XT2drive field // Loop until XT1,XT2 & DCO stabilizes - in this case loop until XT2 settles /* do { UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG_L + DCOFFG); // Clear XT2,XT1,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags } while (SFRIFG1 & OFIFG); */ // Test oscillator fault flag
// UCSCTL6 &= ~XT2DRIVE0; // Decrease XT2 Drive according to // expected frequency // UCSCTL6 |= XTS; // // UCSCTL6 |= XT2DRIVE_3; // Set requested value // UCSCTL4 = SELS_5 + SELM_5; }
void SetVcore (unsigned int level) { //#ifdef MSP // Open PMM registers for write PMMCTL0_H = PMMPW_H; // Set SVS/SVM high side new level SVMHE = 1, SVSMHRRL SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level; // Set SVM low side to new level SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level; // Wait till SVM is settled while ((PMMIFG & SVSMLDLYIFG) == 0); // Clear already set flags PMMIFG &= ~(SVMLVLRIFG + SVMLIFG); // Set VCore to new level PMMCTL0_L = PMMCOREV0 * level; // Wait till new level reached if ((PMMIFG & SVMLIFG)) while ((PMMIFG & SVMLVLRIFG) == 0); // Set SVS/SVM low side to new level SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; // Lock PMM registers for write access PMMCTL0_H = 0x00; //#endif }
cейчас половина закомментирована, т.к. тактируемся от DCO
Сообщение отредактировал shide_3 - Dec 3 2013, 15:39
|
|
|
|
|
Dec 4 2013, 09:34
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Кварц 25МГц ни при чем. Генераторы и на бОльшей частоте могут работать. Сейчас нет времени досконально разбираться с инициализацией. Отмечу пока только то, за что глаз "зацепился". 1. При начальной инициализации нужно все регистры прописывать явными значениями, а не накладывать маски на якобы дефолтные состояния. Я уже давно и настоятельно это всем рекомендую  2. Зачем вы инициализируете UART в 7-ми битном режиме? Протокол Modbus 8-ми битные символы использует. 3. Работа модулятора в USCI отличается от работы модулятора в USART. Я бы на вашем месте вообще пока модуляцию не использовал. Тем более, что ошибка битовой частоты получается всего 0,2%=(1048576/109-9600)/9600*100% 4. Эмулятор при чтении регистров для отображения их в окне View может изменять их состояние, сбрасывая прерывания. Следует учитывать такой эффект. Это к вашему замечанию "интеррапт флаги usci автоматически сбрасываются". Кстати, неплохо бы еще и обработчик перывания посмотреть. 5. Был/есть какой-то глюк/нюанс при использовании DCO для тактирования USCI при синхронизации FLL от REFO или часового кварца. То ли в errata описанный, то ли еще где. Найду - напишу. Суть в том, что синхронизация и модуляция DCO приводит в результате к девиации битовой частоты, которая значительно влияет на работу UART. При использовании DCO для тактирования UART рекомендуется подключать источник синхронизации (REFO или LFXT) только на время (авто)подстройки частоты DCO. Затем источник синхронизации следует отключать, чтобы DCO работал на тех значениях, что получились в результате подстройки. Подробнее разберу вечером, когду будет время.
|
|
|
|
|
Dec 4 2013, 11:32
|
Местный
  
Группа: Участник
Сообщений: 314
Регистрация: 27-04-10
Пользователь №: 56 923

|
Цитата(rezident @ Dec 4 2013, 12:34)  2. Зачем вы инициализируете UART в 7-ми битном режиме? Протокол Modbus 8-ми битные символы использует. как раз в нашем случае ascii modbus - 7 битный, это RTU-8 битный. и софт с соответствующими настройками (на 7 бит). кадр то нормально принимается, и скорее всего uart тут не виноват(может сам процессор?), программа просто затыкается на полпути при формировании фрейма ответа... кстати, при 25 мгц программа затыкается немного раньше, и чаще всего попадает в обработчик прерывания TX.(там зацикливается). при DCO такого нет. Цитата(rezident @ Dec 4 2013, 12:34)  4. Эмулятор при чтении регистров для отображения их в окне View может изменять их состояние, сбрасывая прерывания. Следует учитывать такой эффект. Это к вашему замечанию "интеррапт флаги usci автоматически сбрасываются". в мануале написано: UCRXIFG and UCRXIE are reset by a system reset PUC signal or when UCSWRST = 1. UCRXIFG is automatically reset when UCAxRXBUF is read.а вот обработчик #pragma vector=USCI_A0_VECTOR __interrupt void USCI_A0_ISR(void) { switch(__even_in_range(UCA0IV,4)) { case 0:break; // Vector 0 - no interrupt case 2: b = UCA0RXBUF; if ( UCA0STAT & UCRXERR ) return; //__no_operation(); if ( BlockReceive ) return; if(ModBusMode == MODE_ASCII) { if ( ! FrameReady ) { //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! if(PDUlen >= 254){ PDUlen = 0; mbCRC16 = 0xFFFF; MB_Diag.BusCommErrorCount++; } //Message too long if (! mbFrameStarted) // waiting for new frame { if (b == ':') // SOF { mbFrameStarted = 1; mbAsciiChar = 0; mbLRC = 0; PDUlen = 0; } } else { if((PDUlen != 0) && (b == ':')) { PDUlen = 0; MB_Diag.BusCommErrorCount++; } // SOF occured before previous EOF if(b == 10) {// EOF if (mbLRC == 0) { FrameReady = 1;PDUlen--; mbFrameStarted = 0; Lock(); eventAdd();// UCA0IE |= UCTXIE ; BlockReceive = 1; return; } else { mbFrameStarted = 0; PDUlen = 0; MB_Diag.BusCommErrorCount++; } } if (mbAsciiChar) { mbLRC += (serialPDU [PDUlen] = Get_ASCII_Byte(mbAsciiChar,  ); PDUlen ++; mbAsciiChar = 0; } else mbAsciiChar = b; } } // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! } break; case 4: // if ( FrameReady ) if ( BlockReceive ) { if ( PDUlen >= ResponseLength )//ResponseLength { PDUlen = 0; ResponseLength = 0; FrameReady = 0; mbFrameStarted = 0; // while ((UCA0IFG & UCTXIFG) != UCTXIFG); P7OUT &= ~BIT0; // RS485 direction = RECIEVE UnLock(); BlockReceive = 0; UCA0IE &= ~UCTXIE ; } else __no_operation(); //UCA0TXBUF = serialPDU[1];} UCA0TXBUF = (ModBusMode == MODE_ASCII)? transmitBuf[PDUlen++] : serialPDU[PDUlen++];} //UCA0IE &= ~UCTXIE ; } break; default: break;} }
Сообщение отредактировал shide_3 - Dec 4 2013, 11:35
|
|
|
|
|
Dec 5 2013, 19:58
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(shide_3 @ Dec 4 2013, 16:32)  как раз в нашем случае ascii modbus - 7 битный, это RTU-8 битный. и софт с соответствующими настройками (на 7 бит). В режиме ASCII используется бит четности и всего один стоповый бит. У вас четность не используется и два стоповых бита. Цитата(shide_3 @ Dec 4 2013, 16:32)  кстати, при 25 мгц программа затыкается немного раньше, и чаще всего попадает в обработчик прерывания TX.(там зацикливается). при DCO такого нет. Я вам уже указал, что USCI отличается от USART в части обработки прерываний. Цитата(shide_3 @ Dec 4 2013, 16:32)  в мануале написано: UCRXIFG and UCRXIE are reset by a system reset PUC signal or when UCSWRST = 1. UCRXIFG is automatically reset when UCAxRXBUF is read. Правильно. В USART прерывание от приемника работает аналогично. Но, как я понял, проблема-то у вас с прерыванием от передатчика USCI! Вот сравните Для USART Цитата UTXIFGx is automatically reset if the interrupt request is serviced or if a character is written to UxTXBUF. Для USCI Цитата UCTXIFG is automatically reset if a character is written to UCAxTXBUF. Отличие состоит в том, что в USART прерывание от передатчика сбрасывается в т.ч. просто при переходе по вектору прерывания передатчика. Это возможно, т.к. вектора прерываний для передатчика и для приемника UART разные. В USCI вектор прерывания расшарен и адрес у него один, поэтому сброс запроса прерывания только по факту перехода на обработку передатчика не работает. Если вы попали в прерывание от передатчика, но передавать уже нечего, то флаг UCTXIFG нужно сбросить "вручную". Либо запретить прерывание от передатчика, чтобы после выхода из прерывания не попасть в него вновь. Цитата(shide_3 @ Dec 4 2013, 19:54)  эх. было бы наверное интересно и полезно опробовать заведомо рабочий прожект для подобного кристалла на своем. разумеется, не столь лажовый, как Flashing LED. У производителя на сайте есть примеры http://www.ti.com/lsds/ti/microcontroller/...tware.page#code
|
|
|
|
|
Dec 6 2013, 08:42
|
Местный
  
Группа: Участник
Сообщений: 314
Регистрация: 27-04-10
Пользователь №: 56 923

|
Цитата(rezident @ Dec 5 2013, 22:58)  Либо запретить прерывание от передатчика, чтобы после выхода из прерывания не попасть в него вновь. у меня на данный момент так и сделано
|
|
|
|
|
Dec 10 2013, 15:48
|
Местный
  
Группа: Участник
Сообщений: 314
Регистрация: 27-04-10
Пользователь №: 56 923

|
Цитата(rezident @ Dec 10 2013, 18:06)  В крайнем проекте на MSP430F5438A задействовано три UART и два SPI. Питание батарейное. Работа UART и одного из SPI по перываниям. Писал в виде драйвера для работы с буфером UART (функции: управление буфером - запись/чтение/очистка, (ре)инициализация UART с заданными параметрами, переключение режимов прием/передача/режим энергосбережения, плюс отдельно обработчик прерывания с записью/чтением буфера UART в прерывании). Разбор содержимого буфера был реализован на более высоком уровне. Никаких особых проблем не было. Проект коммерческий, поэтому код здесь привести не могу. может код инициализации (PMM, тактирование) вам показать реально?буду благодарен
|
|
|
|
|
Dec 14 2013, 20:24
|
Местный
  
Группа: Участник
Сообщений: 314
Регистрация: 27-04-10
Пользователь №: 56 923

|
Цитата(rezident @ Dec 14 2013, 19:35)  Вместо того, чтобы кромсать исходник (там для вашего примера лишнее) мне было бы проще написать пример инициализации с нуля. Но сейчас под рукой нет отладочной платы в которой этот пример можно проверить. Если только на следующей неделе уже. Неужели за такое продолжительное время при наличии примеров от производителя у вас до сих пор нет никакого положительного результата?  вы знаете, буквально два дня назад все заработало. причина оказалась неожиданной. в общем, у меня есть сектора во флеш-памяти (в code memory) которые используются для хранения уставок. так вот , судорожно пробуя все возможные варианты , я поменял адреса этих секторов в файле линкера, и глюки исчезли. а до этого было что-то непонятное, программа вылетала или зависала в определенном месте, причем незначительное изменение кода сказывалось совсем неоднозначно, иногда полной неработоспособностью... при попытке записи в регистр по модбасу микроконтроллер переставал реагировать вообще на любые запросы... ну да ладно. вот только как это популярно объяснить? нет ли у Вас точки зрения по этому поводу? пока напрашивается одна мысль - компилятор синтезировал код так, что происходили коллизии между адресами кода программ и памяти данных во флеш. но как такое вообще возможно? не знаю что еще подумать... я уже начинал бояться, что это какой-то железячный глюк...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|