|
пример работы UART, рабочий |
|
|
|
 |
Ответов
(1 - 14)
|
Mar 7 2014, 08:07
|
Местный
  
Группа: Участник
Сообщений: 408
Регистрация: 28-05-12
Пользователь №: 72 052

|
Цитата(rezident @ Mar 6 2014, 19:34)  Вначале следует утончить: режим UART для модуля USART или для модуля USCI? Примеры использования периферийных модулей (и USART и USCI) есть на сайте производителя - см. MSP430 Code Examples. а вы этот Code Example сами пробовали? код нерабочий там. Нужен пример для USCI
|
|
|
|
|
Mar 7 2014, 09:53
|
Местный
  
Группа: Участник
Сообщений: 408
Регистрация: 28-05-12
Пользователь №: 72 052

|
Цитата(rezident @ Mar 7 2014, 13:39)  Который именно? Вы же не указали конкретный тип МК. К тому же прием/передачу данных через UART можно организовать двумя способами: 1) по прерываниям от USCI и 2) без использования прерываний, по опросу флагов готовности USCI. Вам какой способ больше подходит? Вы бы конкретизировали свою задачу, а то "инициализация и прием/передача символов через UART" это слишком общо. Да и честно говоря, при самостоятельном изучении документации (User's Manual) эта задача занимает максимум один рабочий день вместе с обедом, послеобеденным сном и семью перекурами  Там регистров-то USCI кот наплакал. Загвоздка может возникнуть лишь с использованием модулятора - дык, можно просто оценив ошибку baudrate, пока и не использовать его.  пример любой. Они все одинаковово корявые. Я подумал что кто-то может выложить сюда кусок кода работы USCI по прерываниям.
|
|
|
|
|
Mar 7 2014, 10:03
|
Участник

Группа: Свой
Сообщений: 69
Регистрация: 15-02-14
Из: Кострома
Пользователь №: 80 525

|
Цитата(Dubov @ Mar 7 2014, 13:53)  пример любой. Они все одинаковово корявые. Я подумал что кто-то может выложить сюда кусок кода работы USCI по прерываниям. Что значит "корявые" конкретизируйте пожалуйста в чем проявляется "кривизна", а то возникают нехорошие подозрения, что Вам нужен просто оригинальный код, отличный от примеров, потому что лень писать самому. Если нужен оригинальный код, так и скажите. Я при использовании примеров от TI не встречал значительных косяков...
|
|
|
|
|
Mar 7 2014, 10:46
|
Местный
  
Группа: Участник
Сообщений: 408
Регистрация: 28-05-12
Пользователь №: 72 052

|
Цитата(vzelenuk @ Mar 7 2014, 14:03)  Что значит "корявые" конкретизируйте пожалуйста в чем проявляется "кривизна", а то возникают нехорошие подозрения, что Вам нужен просто оригинальный код, отличный от примеров, потому что лень писать самому. Если нужен оригинальный код, так и скажите. Я при использовании примеров от TI не встречал значительных косяков... всем спасибо. нашёл интереснутему с примерами http://electronix.ru/forum/index.php?showt...=UART&st=15 там, кстати, тоже не жалуют примеры от TI
|
|
|
|
|
Mar 15 2014, 14:47
|
Местный
  
Группа: Участник
Сообщений: 408
Регистрация: 28-05-12
Пользователь №: 72 052

|
переделал код. Теперь работает по прерываниям. CODE #include <msp430x471x7.h> #include <stdint.h>
#define FREQMCLK 9830400UL //MCLK #define FREQSMCLK 9830400UL //SMCLK //#define FREQSMCLK 16000000UL //SMCLK #define FREQACLK 32768UL //ACLK #define BAUDRATE 9600UL //baudrate #define TICK_MS_ADDVAL 100U //инкремент таймера тиков [мс] #define BLINK_TIME_MS 500U //полупериод мерцания LED [мс]
int __low_level_init(void) { WDTCTL = WDTPW | WDTHOLD; //останов WDTimer return 1; }
void main(void) { uint32_t lTmp; //Инициализация системы тактирования // FLL_CTL1 = XT2OFF; //D=2, MCLK=fDCOCLK/D, SMCLK=fDCOCLK/D, ACLK=LFXT/1, XT2=off FLL_CTL1 = 0; //D=2, MCLK=fDCOCLK/D, SMCLK=fDCOCLK/D, ACLK=LFXT/1 FLL_CTL2 = XT2S1; //для работы XT2=16МГц FLL_CTL0 = XCAP0PF; //XT1=LF, DCO/D, XCAP=11пФ while ((FLL_CTL0 & LFOF) != 0); //ждем готовности генератора 32768Гц // while ((FLL_CTL0 & XT2OF) != 0); //ждем готовности генератора 16МГц SCFI0 = FLLD_4 | FN_2; //D=4, fDCOCLK = 1.4-12MHz SCFQCTL = SCFQ_M + (75U-1U); //fDCOCLK=32768*(75)*4=9830400Гц, DCO=fDCOCLK/4 while ((FLL_CTL0 & DCOF) != 0); //ждем готовности FLL // FLL_CTL0 |= DCOPLUS; //MCLK=DCO/1, SMCLK=DCO/1 FLL_CTL1 |= SELS; //MCLK=DCO, SMCLK=XT2, ACLK=LFXT/1 do { IFG1 &= OFIFG ^ 0xFF; } while ((IFG1&OFIFG) != 0); //ждем готовности всей системы тактирования P5OUT ^= BIT7; //Инициализация UART UCA1CTL1 |= UCSWRST; //Reset USCI UCA1CTL0 = 0; //Parity=disable, 8bit, 1stop-bit UCA1CTL1 = UCSSEL_2 | UCSWRST; //BRCLK=SMCLK lTmp=FREQSMCLK/BAUDRATE; UCA1BR1 = (uint8_t)(lTmp>>8UL); // UCA1BR0 = (uint8_t)(lTmp); //BITCLK=BRCLK/(UCAxBR1*256+UCAxBR0) UCA1MCTL = 0; //регистр модуляции UCA1STAT = 0; //сброс всех битов ощибок UCA1IRTCTL = 0; //IRDA disable UCA1CTL1 &= ~UCSWRST; P1SEL |= BIT6 | BIT7; //P1.6 = USCI TXD, P1.7 = USCI RXD UC1IE |= UCA1RXIE; //разрешить прерывания от приёмника USCI_A1 UC1IFG |= UCA1RXIFG; //сбросим флаг готовности буфера приемника // UC1IFG |= UCA1TXIFG; //установим флаг готовность буфера передатчика //Инициализация LED P5DIR |= BIT7; P5SEL &= ~BIT7; P5OUT &= ~BIT7; __enable_interrupt(); //разрешим прерывания }
// Echo back RXed character, confirm TX buffer is ready first #pragma vector=USCIAB1RX_VECTOR __interrupt void USCIA1RX_ISR (void) { if ((UC1IFG&UCA1TXIFG)!=0); UCA1TXBUF = UCA1RXBUF; // TX -> RXed character P5OUT ^= BIT7; }
Но наблюдается очень странное поведение. Некоторые символы отлично проходят в "эхо", другие возвращаются с ошибками(непонятные символы приходят). Например символ "a" не возвращается как положено, а символ "z" всегда возвращается как надо. При каждом прерывании светодиод должен менять своё состояние, но, для случая с "a" состояние меняется, а для случая отправки "z" состояние не меняется. То есть со светодиодом ситуация наоборот... КАК ТАК?
Сообщение отредактировал Dubov - Mar 15 2014, 15:15
|
|
|
|
|
Mar 16 2014, 01:06
|
Местный
  
Группа: Участник
Сообщений: 326
Регистрация: 30-05-06
Пользователь №: 17 602

|
Цитата(Dubov @ Mar 15 2014, 17:47)  переделал код. Теперь работает по прерываниям.
КАК ТАК? Правильный код такой // MOdemRX interrupt #pragma vector = USCI_A0_VECTOR __interrupt void USCI_A0_ISR(void) { uint8_t u; if(UCA0IV & (UCRXIFG<<1)) { u = UCA0RXBUF; // RXed character rxBuf[0] if(!ModemFlags.Uart) { if(u=='\n' || u=='\r') ModemFlags.Uart=1; uartRxBuf[uartRxCnt++] = u; }; }; // if(UCA0IV & (UCTXIFG<<1)) // { // uartCommand = UCA0RXBUF; // TXed character txBuf[0] // }; } И прочитайте всё-таки даташит
|
|
|
|
|
Mar 16 2014, 05:48
|
Местный
  
Группа: Участник
Сообщений: 408
Регистрация: 28-05-12
Пользователь №: 72 052

|
Цитата(mcheb @ Mar 16 2014, 05:06)  Правильный код такой // MOdemRX interrupt #pragma vector = USCI_A0_VECTOR __interrupt void USCI_A0_ISR(void) { uint8_t u; if(UCA0IV & (UCRXIFG<<1)) { u = UCA0RXBUF; // RXed character rxBuf[0] if(!ModemFlags.Uart) { if(u=='\n' || u=='\r') ModemFlags.Uart=1; uartRxBuf[uartRxCnt++] = u; }; }; // if(UCA0IV & (UCTXIFG<<1)) // { // uartCommand = UCA0RXBUF; // TXed character txBuf[0] // }; } И прочитайте всё-таки даташит извините, не могли бы вы рассказать про смысл ModemFlags.Uart ? в вашем коде не видно когда обнуляетсяэтот флаг
|
|
|
|
|
Mar 16 2014, 07:15
|
Местный
  
Группа: Участник
Сообщений: 326
Регистрация: 30-05-06
Пользователь №: 17 602

|
Цитата(Dubov @ Mar 16 2014, 08:48)  извините, не могли бы вы рассказать про смысл ModemFlags.Uart ? в вашем коде не видно когда обнуляетсяэтот флаг Это флаг прихода Новой команды по Уарту. После обработки команды он сбрасывается.
|
|
|
|
|
Mar 16 2014, 11:41
|
Местный
  
Группа: Участник
Сообщений: 408
Регистрация: 28-05-12
Пользователь №: 72 052

|
Цитата(mcheb @ Mar 16 2014, 11:15)  Это флаг прихода Новой команды по Уарту. После обработки команды он сбрасывается. позвольте узнать, что в вашем примере примечательного? мне не нужно принимать последовательность байтов, я реализую простейшее эхо. Так вот некоторые символы передается а некоторые нет. Зависит от символа, не могу понять почему.
|
|
|
|
|
Mar 17 2014, 02:07
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Dubov @ Mar 15 2014, 19:47)  Но наблюдается очень странное поведение. Некоторые символы отлично проходят в "эхо", другие возвращаются с ошибками(непонятные символы приходят). Например символ "a" не возвращается как положено, а символ "z" всегда возвращается как надо. У вас скорее всего не передача глючит, а прием символов по причине неверной настройки baudrate. Кварц подключенный к XT2 у вас точно 9830,4кГц? К тому же, думаю, стоит зациклить вашу программу, чтобы "эхо" передавалось каждый раз при приеме нового символа. Для этого в конце main следует добавить строку for(;;); Ну и неплохо бы уже указать конкретный тип кристалла. А то мы можем лишь догадываться по заголовочному файлу, что у вас что-то из серии MSP430F471x7.
|
|
|
|
|
Mar 17 2014, 02:41
|
Местный
  
Группа: Участник
Сообщений: 408
Регистрация: 28-05-12
Пользователь №: 72 052

|
Цитата(rezident @ Mar 17 2014, 06:07)  У вас скорее всего не передача глючит, а прием символов по причине неверной настройки baudrate. Кварц подключенный к XT2 у вас точно 9830,4кГц? К тому же, думаю, стоит зациклить вашу программу, чтобы "эхо" передавалось каждый раз при приеме нового символа. Для этого в конце main следует добавить строку for(;;); Ну и неплохо бы уже указать конкретный тип кристалла. А то мы можем лишь догадываться по заголовочному файлу, что у вас что-то из серии MSP430F471x7. кристалл MSP430F47197. Два кварца: 32768Гц и 16Мгц Код взял здесь http://electronix.ru/forum/index.php?showt...l=UART&st=0 и переписал, чтобы задействовать прерывания. У автора топика по ссылке тоже такая же конфигурация кварцев
Сообщение отредактировал Dubov - Mar 17 2014, 02:45
|
|
|
|
|
Mar 17 2014, 13:27
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Dubov @ Mar 17 2014, 07:41)  кристалл MSP430F47197. Два кварца: 32768Гц и 16Мгц Код взял здесь http://electronix.ru/forum/index.php?showt...l=UART&st=0 и переписал, чтобы задействовать прерывания. У автора топика по ссылке тоже такая же конфигурация кварцев Гм. А как вы думаете, какой результат вы получаете в результате выполнения вот этой операции? Код lTmp=FREQSMCLK/BAUDRATE; Таки реальная частота SMCLK у вас вовсе не 9830400Гц, а в 4 раза меньше. Даже могу подсказать отчего она меньше Код #define FREQSMCLK 9830400UL //SMCLK //#define FREQSMCLK 16000000UL //SMCLK Код // FLL_CTL0 |= DCOPLUS; //MCLK=DCO/1, SMCLK=DCO/1 FLL_CTL1 |= SELS; //MCLK=DCO, SMCLK=XT2, ACLK=LFXT/1 Вы уж разберитесь от какого генератора хотите тактировать SMCLK и правильно раскомментарьте/закомментарьте указанные строки
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|