This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
下午好...
我使用的是连接到 PC 的 MSP430FR2355开发板。 在 PC 端使用 RealTerm ...
我可以将波特率设置为19200和9600、并且都可以正常工作、但如果我将其设置为高于19200、我将得到错误的字符。 我已经验证了以下寄存器 是否按照用户指南设置为高于19.2的多个波特率
1. smclk 8MHz (在 P1.0上验证)、也验证了在 UART 控制寄存器设置中使用 SMCLK
2.还对照用户手册设置表22.5进行了验证: UCOS16、UCBR、UCBRF、UCBRS……
3. 已验证 RealTerm 是否设置为正确的波特。
ISR 开头的断点会验证 ISR 前端是否存在 RXBUFFER 错误、这使我认为设置中缺少什么??
有人对我可能遗漏的内容有什么想法、也有什么值得尝试的、因为我都不知道为什么我不能更快地走? (代码(在 main 中)除了 LPM3之外什么也不做(我在 LPM0中看不到任何改进)。 它等待 UART 字符进入、然后运行。
ISR 非常简单(如果字符停止、ISR 内部会布设超时)
case USCI_UART_UCRXIFG: buffer[mssgLength] = UCA1RXBUF; mssgLength++; if (monitor == 0) TimerCC_Delay(TIMER0, CC_ZERO, ONE_SECOND); monitor = 1; if (UCA1RXBUF == 0x0D) { mssgLength--; ISR.UARTmssgRcvdFlag = T; LPM3_EXIT; } break;
谢谢
您好、Steve、
根据 MSP 调试器 文档、ezFET 可支持的波特率存在限制。 请注意、只有支持频率。 摘录如下:
此致、
Evan
不是很相信……我从 SBWTDIO 和 SBWTCK 上取下跳线使调试器处于非活动状态……16MHz 时的 MCLK、针对 smclk 除以2……波特率设置为115200……寄存器看起来都很好……仍然是不可以的……然后尝试了38400,寄存器看起来很好…
我加载了代码并验证了寄存器设置、然后停止运行调试器、断开的跳线关闭目标电源并重新加电、但无法正常工作???
我在发布的代码中看不到 RXBUFFER。 我担心该 ISR。 接收到完整的线路后、您唤醒主程序、但 ISR 仍在运行、这可能会导致缓冲区出现问题。
我可以向您指出一个示例、即我经常以38400运行(我没有尝试过更高版本)、但它在汇编中。 我对数据使用 FIFO 队列。
RXBUFFER (抱歉我的错误)……这只是表示缓冲区……如果你看看 ISR,你会看到正确的分配,即 UCA1RXBUF……
我已经成功地使用了这个概念...这是唤醒后主代码的第一行
if (ISR.UARTmssgRcvdFlag) { applicationUART.pSysCommsA->UCAxIE &= ~UCRXIE;
我正在使用外部32kHz 晶体...
你能评论一下 REFOLP 位设置和 DISMOD 位设置。。。我尝试将这些设置翻转为 REFOLP=0 (即高功率),但没有结果。。。我看到我有一些代码(由于项目的性质有些不同)。 以更高的波特运行、但它的 DISMOD =1看起来对 me....in 来说是错误的。这个项目我的 DISMOD = 0?? (这些位于 CS 部分)
所以我把应用程序缩小到了裸块...我发现在38400时,接收到的第一个字节的信息是损坏的...所以我更改为 LPM0,它们都是在38400 ...然后我移至115200,我看到在 LPM0时,第一个字节再次是坏的...它 看起来处理器无法及时唤醒或唤醒某个东西???
我的时钟是8MHz,调试器是连接的,根据上面 Evan 的图片,应该可以正常工作……我真的想在 LPM3....ca上操作它,但我不想这样做……我的 SMCLKREQEN 是 set....seems,我应该唤醒它
我想听听 TI 的意见吗?? 从 LPM3接收唤醒时,似乎无法获得>19.2K 波特
我已经查看过数据表、数据表显示从 LPM3唤醒的典型时间是10us……115.2Kbaud 是8.7us,因此我必须相信无法在 UART RX 中断上唤醒并以 115200 波特率成功工作。 我无法使用 LPM3从 UART RX 中唤醒并捕获高于19.2kBaud 的所有传入字符...如果我转到 LPM0、我可以得到38400....
下面是38400处的一些基本代码(我删除了所有库并将 UART 和 clk inits 移动到文件中,以防分支导致麻烦),LPM3错误地引入了第一个字符....
#include "main.h" void init_ClockTo16MHz(void); static void Software_Trim(); void UART_Init(void); uint16_t itoa(uint16_t k); struct HardFlags ISR = {F}; static __vo uint8_t buffer[MSSG_LENGTH] = { [ 0 ... MSSG_LENGTH - 1] = 0 }, monitor = 0; __vo uint8_t mssgLength = 0; int main(void) { WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer PM5CTL0 &= ~LOCKLPM5; init_ClockTo16MHz(); UART_Init(); while(1) { __bis_SR_register( LPM3_bits + GIE); if (ISR.UARTmssgRcvdFlag) { UCA1IE &= ~UCRXIE; ISR.UARTmssgRcvdFlag = F; mssgLength = 0; UCA1IFG &= ~UCRXIFG; UCA1IE |= UCRXIE; } } } #pragma vector=USCI_A1_VECTOR __interrupt void COMM_ISR(void) { switch(__even_in_range(UCA1IV, USCI_UART_UCTXCPTIFG)) { case USCI_NONE: break; case USCI_UART_UCRXIFG: buffer[mssgLength] = UCA1RXBUF; if (buffer[mssgLength] == 0x0D) { ISR.UARTmssgRcvdFlag = T; LPM3_EXIT; } mssgLength++; break; case USCI_UART_UCTXIFG: break; case USCI_UART_UCSTTIFG: break; case USCI_UART_UCTXCPTIFG: break; } } #ifdef LOCAL void UART_Init(void) { P4SEL0 |= BIT3 | BIT2; UCA1CTLW0 |= UCSWRST; UCA1CTLW0 |= UCSSEL__SMCLK; //UCA1BR0 = 52; //19200 UCA1BR0 = 13; //115200 UCA1BR1 = 0x00; //UCA1MCTLW = 0x4900 | UCOS16 | UCBRF_1; //19200 UCA1MCTLW = 0x8400 | UCOS16 | UCBRF_0; //115200 UCA1CTLW0 &= ~UCSWRST; UCA1IFG &= ~UCRXIFG; UCA1IE |= UCRXIE; } void init_ClockTo16MHz(void) { FRCTL0 = FRCTLPW | NWAITS_1; P2SEL1 |= BIT6 | BIT7; do { CSCTL7 &= ~(XT1OFFG | DCOFFG); // Clear XT1 and DCO fault flag SFRIFG1 &= ~OFIFG; } while (SFRIFG1 & OFIFG); // Test oscillator fault flag __bis_SR_register(SCG0); // disable FLL CSCTL3 |= SELREF__XT1CLK; // Set XT1 as FLL reference source CSCTL1 |= DCOFTRIMEN_1 | DCOFTRIM0 | DCOFTRIM1 | DCORSEL_5;// DCOFTRIM=5, DCO Range = 16MHz CSCTL2 = FLLD_0 + 487; // DCOCLKDIV = 16MHz __delay_cycles(3); __bic_SR_register(SCG0); // enable FLL Software_Trim(); while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); CSCTL5 |= DIVS_1; CSCTL4 = SELMS__DCOCLKDIV | SELA__XT1CLK; // set XT1 (~32768Hz) as ACLK source, ACLK = 32768Hz } static void Software_Trim() { unsigned int oldDcoTap = 0xffff; unsigned int newDcoTap = 0xffff; unsigned int newDcoDelta = 0xffff; unsigned int bestDcoDelta = 0xffff; unsigned int csCtl0Copy = 0; unsigned int csCtl1Copy = 0; unsigned int csCtl0Read = 0; unsigned int csCtl1Read = 0; unsigned int dcoFreqTrim = 3; unsigned char endLoop = 0; do { CSCTL0 = 0x100; // DCO Tap = 256 do { CSCTL7 &= ~DCOFFG; // Clear DCO fault flag }while (CSCTL7 & DCOFFG); // Test DCO fault flag __delay_cycles((unsigned int)3000 * 16);// Wait FLL lock status (FLLUNLOCK) to be stable // Suggest to wait 24 cycles of divided FLL reference clock while((CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)) && ((CSCTL7 & DCOFFG) == 0)); csCtl0Read = CSCTL0; // Read CSCTL0 csCtl1Read = CSCTL1; // Read CSCTL1 oldDcoTap = newDcoTap; // Record DCOTAP value of last time newDcoTap = csCtl0Read & 0x01ff; // Get DCOTAP value of this time dcoFreqTrim = (csCtl1Read & 0x0070)>>4;// Get DCOFTRIM value if(newDcoTap < 256) // DCOTAP < 256 { newDcoDelta = 256 - newDcoTap; // Delta value between DCPTAP and 256 if((oldDcoTap != 0xffff) && (oldDcoTap >= 256)) // DCOTAP cross 256 endLoop = 1; // Stop while loop else { dcoFreqTrim--; CSCTL1 = (csCtl1Read & (~DCOFTRIM)) | (dcoFreqTrim<<4); } } else // DCOTAP >= 256 { newDcoDelta = newDcoTap - 256; // Delta value between DCPTAP and 256 if(oldDcoTap < 256) // DCOTAP cross 256 endLoop = 1; // Stop while loop else { dcoFreqTrim++; CSCTL1 = (csCtl1Read & (~DCOFTRIM)) | (dcoFreqTrim<<4); } } if(newDcoDelta < bestDcoDelta) // Record DCOTAP closest to 256 { csCtl0Copy = csCtl0Read; csCtl1Copy = csCtl1Read; bestDcoDelta = newDcoDelta; } }while(endLoop == 0); // Poll until endLoop == 1 CSCTL0 = csCtl0Copy; // Reload locked DCOTAP CSCTL1 = csCtl1Copy; // Reload locked DCOFTRIM while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // Poll until FLL is locked } #endif
数据表中有一个表(5-2)、该表告诉您唤醒所需的时间。 从 LPM3的唤醒时间为10us。
虽然 UART 能够唤醒、但它在起始位的下降沿执行此操作。 如果时钟未运行、则时序将成为一个问题、因为所有内容都以该下降沿为基准。 或时钟启动时、以最后的时间为准。
尊敬的 David:
是的,这就是我所处的位置...我不认为它可以完成...尽管它看起来不能达到57.6kBaud?
虽然很难理解用户指南似乎建议在中间进行采样...所以可能57.6也不在...但在 LPM3下似乎可以达到38.4? 您提到过您是在汇编语言中实现的、但使用 FIFO?? 我不知道汇编语言,但......我在上面的38.4号发布了代码,但它不起作用......有什么想法吗?
我的示例在大多数情况下都不使用低功耗模式。 我用一个运行它、不会忘记任何问题。 我提到了汇编器件、因为这会使许多 C 语言编程器感到害怕。 它中实际上没有任何东西无法在 C 语言中完成、但项目必须在汇编语言中完成。
在38、400 bps 时、10us 延迟会使您接近位的中心。 即使检测到起始位、所有后续位也将具有相同的偏移。 假设调制器正在使用中(它必须具有8MHz 参考时钟)、则还必须添加这些误差。 因此、38、400会有问题、因为采样时间会非常接近位的边缘。
如果必须使用 LPM3和更高的位速率、则必须找到一种在数据到达之前启动时钟的方法。 然后使其保持活动状态、直到接收到所有数据。