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

 
 
> пример работы UART, рабочий
Dubov
сообщение Mar 6 2014, 10:00
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 408
Регистрация: 28-05-12
Пользователь №: 72 052



Прошу поделится примером рабочего кода инициализирующего UART, и принимающего/передающего символы через UART.

Code Examples от TI - полное барахло.


Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Dubov
сообщение Mar 15 2014, 14:47
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
mcheb
сообщение Mar 16 2014, 01:06
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 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]
// };
}
И прочитайте всё-таки даташит
Go to the top of the page
 
+Quote Post
Dubov
сообщение Mar 16 2014, 05:48
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 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 ?
в вашем коде не видно когда обнуляетсяэтот флаг
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 29th July 2025 - 15:07
Рейтинг@Mail.ru


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