|
MSP430F149, прерывания USART., Странный порядок... |
|
|
|
Jul 17 2009, 06:05
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
RS485. Хочу управлять направлением передачи без таймера. План был такой: не отключать приёмник у драйвера 485, ловить эхо переданных символов, и по приёму последнего символа отключать передатчик. Пишу: Код // прерывание по приёму. void rx_interrupt(void) { if (is_tx_on()) // передатчик включен? { if (!tx_on_) // передача окончена? tx_off(); // отключаем передатчик. } else // обычный приём. { RxBuf.put(RXBUF0); } }
// прерывание по передаче void tx_interrupt(void) { if (TxBuf.is_empty()) { tx_on_ = false; } else TXBUF0 = TxBuf.get(); } }; Вроде бы всё логично. Сначала опустошается TXBUF0, возникает прерывание tx_interrupt, я сбрасываю флажок tx_on_. Затем этот последний символ принимается, возникает прерывание по приёму, я отключаю передатчик. Но. Почему-то сначала возникает прерывание по приёму, а лишь затем - по опустошению передатчика! Как такое может быть?
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jul 17 2009, 07:10
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(Dog Pawlowa @ Jul 17 2009, 10:35)  Вполне логично, поскольку для приема достаточно информационных бит, а для передатчика наверняка еще стоповый бит включен. Вряд ли, приёмник должен проконтролировать целостность фрейма, для этого стоповые тоже нужны. Хотел было предположить, что прерывания формируются одновременно, но у приёма более высокий приоритет, ан нет. #define USART1TX_VECTOR 4 /* 0xFFE4 USART 1 Transmit */ #define USART1RX_VECTOR 6 /* 0xFFE6 USART 1 Receive */ Трансмит выше. Да это и логично. Загадка, однако! Стоп... Я чё-то не понял... Прерывание по передаче формируется по окончании передачи?
Тогда зачем вся эта свистопляска с эхом/приёмом? Ещё вчера заметил забавную вещь. Подряд закидывал 2 байта в U0TXBUF (в тестовых целях), а на осциле видел только последний. Тоже удивился.
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Jul 17 2009, 07:20
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(MrYuran @ Jul 17 2009, 10:10)  Вряд ли, приёмник должен проконтролировать целостность фрейма, для этого стоповые тоже нужны. Это разные процессы. Сформировать готовность(и прерывание) - это одно. Продолжение накопления ошибок (например, переполнение будет сформировано если придет следующий старт - бит) - это другая функция аппаратуры.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Jul 17 2009, 08:37
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(AHTOXA @ Jul 17 2009, 11:49)  То есть, сам символ ещё передаётся. Но по факту это не так. Возможно, IFG формируется как на картинке, а вот на прерывание наложено ещё одно условие (сдаётся мне, что TXEPT) Провёл эксперимент на живой МСП-хе (правда, у меня сейчас 169, но не суть) Код interrupt(UART0TX_VECTOR) uart0_write_interrupt_handler(void) { P6OUT |= 1; IFG1 &= ~UTXIFG0; // clear flag TXD0 if(UART0.BytesToTransmit) // Есть что передавать {
// формируем CS в последнем байте пакета *(UART0.cTxBufPtr + UART0.BytesToTransmit) += ~(*(UART0.cTxBufPtr++) ); UART0.BytesToTransmit --; U0TXBUF = *UART0.cTxBufPtr; // Выдаём очередной байт P6OUT &= ~1; } else // передали весь пакет {
UART0.events->DataSent = 1; // выставили флаг UART0.events->SendingData = 0; for(;UART0.uart->utctl.txept == 0;); P6OUT &= ~1; #if LINE_MASTER_MODE == 1 GetRealTime(&Timers.SendTimer); Timers.SendTimer += DIR_SWITCH_DELAY_MS; #endif //UARTevents.SendingData = 0; } } В прерывании от последнего байта пакета дёргаю ногой вверх, а потом жду установки TXEPT и опускаю ногу. Результат: импульс длительностью ~10 мкс - никак не длительность передачи (бодрэйт стоит 1200)
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Jul 17 2009, 09:05
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(MrYuran @ Jul 17 2009, 14:37)  Возможно, IFG формируется как на картинке, а вот на прерывание наложено ещё одно условие (сдаётся мне, что TXEPT) Ну это вряд ли. Уж диаграммы в доках TI обычно всегда соответствуют. К тому же, при таком условии становится практически нереальной передача символов подряд. Цитата В прерывании от последнего байта пакета дёргаю ногой вверх, а потом жду установки TXEPT и опускаю ногу. Результат: импульс длительностью ~10 мкс - никак не длительность передачи (бодрэйт стоит 1200) Ну пусть даже 10 мкс. В любом случае прерывание по RX должно быть позже на эти самые 10 мкс! А я в свою очередь попробовал выключать передатчик в прерывании по TX. Тоже плохо. Сейчас найду второй щуп, и исследую получше, что там в каком порядке происходит
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jul 17 2009, 09:23
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Ещё один эксперимент. Код void test_UART() { U0TXBUF = 0x5a; P6OUT |= 1; for(; IFG1 & UTXIFG0 == 0;); P6OUT |= 4; for(;UART0.uart->utctl.txept == 0;); P6OUT &= ~5; } Итого: На обеих ногах импульс длительностью 8,5 мс То есть: TXIFG формируется сразу же, как только кинули байт в буфер. 10 мкс в прошлом разе - это время выполнения обработчика прерывания. То есть, по всей вероятности, в момент прерывания TXEPT уже торчит. Попутно ткнулся в выходной сигнал и обнаружил, что начало стартового бита запаздывает относительно момента записи в сдвиговый регистр на 400 мкс, то есть половину битового интервала. Щас гляну ещё конец. Что и требовалось доказать. TXEPT (по которому предположительно вызывается прерывание), тоже отодвинут на пол-интервала от конца стопового бита
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Jul 17 2009, 09:49
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(MrYuran @ Jul 17 2009, 15:23)  Итого: На обеих ногах импульс длительностью 8,5 мс На каких на обеих? А, понял  Цитата То есть: TXIFG формируется сразу же, как только кинули байт в буфер. Для первого символа - да. Ибо U0TXBUF сразу же перезаписывается в сдвиговый регистр и опустошается. Цитата 10 мкс в прошлом разе - это время выполнения обработчика прерывания. То есть, по всей вероятности, в момент прерывания TXEPT уже торчит. Да там вроде команд не так много  Цитата Попутно ткнулся в выходной сигнал и обнаружил, что начало стартового бита запаздывает относительно момента записи в сдвиговый регистр на 400 мкс, то есть половину битового интервала. Только всё же не в сдвиговый регистр, а в буфер передачи. Сдвиговый регистр - он унутре, и не доступен программисту  Цитата TXEPT (по которому предположительно вызывается прерывание), тоже отодвинут на пол-интервала от конца стопового бита Я всё же сильно сомневаюсь, что TXEPT влияет на возникновение прерывания. Попробуйте писать пару символов сразу, картина изменится. (я, к сожалению не нашёл второго луча  )
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jul 17 2009, 10:51
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(AHTOXA @ Jul 17 2009, 13:49)  Попробуйте писать пару символов сразу, картина изменится. (я, к сожалению не нашёл второго луча  ) Глянул. Забавная картина. Передаю 7 байтов подряд, в начале и конце обработчика TX_ISR машу ногой вверх/вниз. И что же? ровно в середине каждого стартового бита вижу тоненькую палку. Ничего не понимаю! (с)
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Jul 17 2009, 11:14
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(MrYuran @ Jul 17 2009, 16:51)  ровно в середине каждого стартового бита вижу тоненькую палку. Ничего не понимаю! (с) Дык, это как раз нормально  Стартовый бит пошёл - буфер передатчика освободился (отправлен в сдвиговый регистр) - прерывание. У меня возникли подозрения, что я банально пропускаю прерывание. Проц очень сильно нагружен, там scmRTOS, дисплей, то, сё... На сегодня плюнул, в понедельник буду ставить более чистый эксперимент
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jul 17 2009, 16:40
|
Участник

Группа: Участник
Сообщений: 54
Регистрация: 25-09-07
Пользователь №: 30 836

|
Цитата(AHTOXA @ Jul 17 2009, 10:05)  Но. Почему-то сначала возникает прерывание по приёму, а лишь затем - по опустошению передатчика! Как такое может быть? У UART MSP430 есть режим, когда прерывание возникает по приему стартового бита. Сделано это, чтобы можно было усыпить контроллер, и в то же время успеть включить DCO для приема символа. slau049f.pdf USART Peripheral Interface, UART Mode page 13-19 Receive-Start Edge Detect Operation The URXSE bit enables the receive start-edge detection feature. The recommended usage of the receive-start edge аeature is when BRCLK is sourced by the DCO and when the DCO is off because of low-power mode operation. The гltra-fast turn-on of the DCO allows character reception after the start edge detection. When URXSE, URXIEx and GIE are set and a start edge occurs on URXDx, the internal signal URXS will be set. When URXS is set, a receive interrupt request is generated but URXIFGx is not set. User software in the receive interrupt service routine can test URXIFGx to determine the source of the interrupt. When URXIFGx = 0 a start edge was detected and when URXIFGx = 1 a valid character (or break) was received......Проверьте состояние URXSE. Может быть, получается так, что у Вас в течение одного такта срабатывают и прерывания по передаче и по приему, а первым обслуживается прием (приоритет я навскидку не помню)?
|
|
|
|
|
Jul 17 2009, 16:49
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(=DS= @ Jul 17 2009, 22:40)  У UART MSP430 есть режим, когда прерывание возникает по приему стартового бита. Не, не оно. Я проверял уже Цитата Может быть, получается так, что у Вас в течение одного такта срабатывают и прерывания по передаче и по приему, а первым обслуживается прием (приоритет я навскидку не помню)? Да нет. Во-первых, приоритет передатчика выше. А во-вторых (и в главных), прерывание передатчика должно возникать по опустошению буфера передатчика, задолго до физического окончания передачи (передача ведётся из сдвигового регистра). Собственно из-за чего и приходится городить весь этот огород - нужно узнать момент окончания передачи, а не момент опустошения буфера передатчика.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jul 17 2009, 17:20
|
Участник

Группа: Участник
Сообщений: 54
Регистрация: 25-09-07
Пользователь №: 30 836

|
Цитата(AHTOXA @ Jul 17 2009, 20:49)  Да нет. Во-первых, приоритет передатчика выше. А во-вторых (и в главных), прерывание передатчика должно возникать по опустошению буфера передатчика, задолго до физического окончания передачи (передача ведётся из сдвигового регистра). Собственно из-за чего и приходится городить весь этот огород - нужно узнать момент окончания передачи, а не момент опустошения буфера передатчика. Не поленился, проверил  Приоритет приемника выше, да оно и логично. А по поводу цепочки событий: 1.запихивание байта в сдвиговый регистр 2.начало передачи и генерация TX переывания 3. Получение эха стартового бита и генерация RX прерывания 4 Передача остального символа Так что если события 2 и 3 попадут на один такт процессора, первым обслужится прием. Но если URXSE не установлен...  И еще вариант, правда маловероятный - если очень велика разница между частотой MCU и UART, те символ успевает передаться в течение такта.
Сообщение отредактировал =DS= - Jul 17 2009, 18:20
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|