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.

[参考译文] MSP430F249:UART

Guru**** 2386620 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1204965/msp430f249-uart

器件型号:MSP430F249

我已经重新编写了 UART 数据管理状态机以支持 UART RX 中断。 但是、UART 永远不会生成并中断!

// UART 初始化。
UCA0CTL1 |= UCSWRST;//禁用 UART。

UCA0CTL0 |= 0x00;//无奇偶校验、LSB 优先、8位字符、1个停止位、UART 模式、异步模式
UCA0CTL1 |= 0x40;// ACLK
UCA0MCTL |= UCBRF_3 + UCBRS_5 + UCOS16;// 230、400波特
UCA0BR0 |= 0x04;//波特率预分频高字节
UCA0BR1 |= 0x00;//波特率预分频的低字节

UCA0CTL1 &=~UCSWRST;//启用 UART。
IE2 |= UCA0RXIE;//启用 UART 接收中断。

//将 RX 缓冲区中的字符复制到 Serial_Port_Data。
#pragma vector=USCIAB0RX_vector
__interrupt void USCI0RX_ISR (void){
_DINT();

Serial_Port_Data = UCA0RXBUF;
System_Flags |= UART_RX_DATA;

_EINT();
}

此致、Harvey

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    1) 1)如何确定未发生中断? ISR 中的断点通常令人信服。  

    2) 2)您是否在某处启用 GIE? [__enable_interrupt ()或_eINT ()或一些类似的]

    3) 3) System_Flags 是否被声明为"volatile"?

    4)[未经请求:]

    _EINT();

    CPU 中断机制为你执行_DINT 和_EINT。 在 ISR 中使用_EINT 会打开一个很可能在产品交付前一晚出现的小窗口。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我  从 ISR 中删除了_DINT ()和_EINT ()、突然间我得到了中断! 我不知道为什么会产生问题,但我会继续下去。  

    现在我还有其他问题,但已经取得了进展。

    谢谢 Bruce!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如果这是整个中断服务例程、那该怎么办呢? 您已将"Checking RXIFG"替换为"System_Flags"、将 RXBUF 替换为"Serial_Port_Data"。 不会获得任何时间或功能。

    它实际上更慢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    以下 ISR 的运行速度比预期慢约8到10倍。 对时钟周期进行计数 I 估计为2到2.4微秒。 不过、从 LED 亮起到 LED 熄灭我测得的值几乎为20微秒。 为什么有什么想法?

    #pragma vector=USCIAB0RX_vector
    __interrupt void USCI0RX_ISR (void){

    P3OUT &&~Ω LED1n;//打开 LED

    Upstown_Data[Upstone_pointer]= UCA0RXBUF;//将数据写入缓冲存储器。
    Upstone_pointer++;//指向 Upstone_Data 数组中的 Packet_Command 位置。

    if (上游指针>= Rx_Packet_Length ){
    System_Flags |= UART_RX_DATA;
    Upstone_pointer = 0;//初始化数组索引。
    }

    P3OUT |= LED1n;//关闭 LED
    }

    UART 似乎在230、400波特下正确运行、XIN 测量值为16.1MHz。 之后进行时钟初始化。

    //Set_Clock、用于将16MHz 时钟写入 XIN。
    // DCOCTL = 0;//选择最低的 DCOx 和 MODx 设置
    BCSCTL1 = CALBC1_16MHZ;// 0x10F9 //设置范围
    DCOCTL = CALDCO_16MHz;// 0x10F8 //设置 DCO 阶跃+调制
    BCSCTL2 = SMCLK_2M;// 0x06
    BCSCTL3 = LFXT1S_2;// 0x20 // ACLK 的 VLO (~12kHz)


    执行{
    IFG1 &=~OFIFG;//清除 OSCFault 标志
    对于(DDC03_INDEX = 0xFF;DDC03_INDEX > 0;DDC03_INDEX -);//设置标志的时间
    }

    while (IFG1和 OFIFG);// OSCFault 标志仍置1?

    //一旦芯片正在运行,设置为所需的操作,请参见寄存器定义了解详细信息
    DCOCTL = 0xE0;// DCO 设置为16MHz
    BCSCTL1 = 0xCF;// XT2振荡器关闭、LFXT1处于高频模式、ACLK 分频器设置为1、RSEL 最高范围。
    // BCSCTL2 = 0x00;// MCLK 和 SMCLK 源 DCOCLK、Div-0
    BCSCTL2 = 0xC0;// ACLK = MCLK = XIN、除以1。
    BCSCTL3 = 0xF0;//

    // while (IFG1 & OFIFG);// OSCFault 标志仍置1?

    //一旦芯片正在运行,设置为所需的操作,请参见寄存器定义了解详细信息
    DCOCTL = 0xE0;// DCO 设置为16MHz
    BCSCTL1 = 0xC7;//
    BCSCTL2 = 0xC0;// MCLK 和 SMCLK 源 DCOCLK、Div-0
    BCSCTL3 = 0xF0;//

    谢谢、Harvey

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我不明白。 首先、您使用信息存储器中的已校准值来设定 DCO、然后您将它们更改为未校准。

    您检查振荡器故障标志、但似乎没有配置 LFXT 或 XT2。

    虽然您的注释显示您已将 MCLK 设置为 DCO、但是这些位表示 SELM 为11、即 LFXT1。 幸运的是、失效防护系统退回到 DCO。 在器件头文件中为这些字段定义了一些有用的符号。 (SELM_0和 DIVM_0等)

    时钟系统寄存器经常摆弄、所以我不知道你认为你在干什么。 当然、最后一个 fidling 的值不会将 DCO 设置为16MHz。

    哦、在使用校准值(CALDCO 等)之前、您应该验证 TLV 数据的校验和、以确保它不会被打乱。 如何处理故障取决于您。 停下来着火、或使用一些最佳猜测值。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我继承了此代码、发现时钟部分编程在任何情况下都很混乱。

     在"while"之后,我把所有的东西都删掉了,并对时钟编程做了一些调整,一切似乎都在按应有的方式工作。

    我剩下:

    DCOCTL = CALDCO_16MHz;
    BCSCTL1=XT2OFF + XTS + RSEL3 + RSEL2 + RSEL1 + RSEL0;
    BCSCTL2 = 0xC0;// MCLK 和 SMCLK 源 DCOCLK、Div-0
    BCSCTL3 = 0;

    执行{
    IFG1 &=~OFIFG;//清除 OSCFault 标志
    对于(DDC03_INDEX = 0xFF;DDC03_INDEX > 0;DDC03_INDEX -);//设置标志的时间
    }

    while (IFG1和 OFIFG);// OSCFault 标志仍置1?

    有什么评论或批评?

    谢谢

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Harvey:

    BCSCTL1 = XT2OFF + XTS + RSEL3 + RSEL2 + RSEL1 + RSEL0;
    [/报价]

    我想把它更改为像 BCSCTL1 = XT2OFF | XTS | (0xF0 & CALBC1_16MHz ) 这样的值、这样你就可以使用16MHz 上 RSELx 的校准值。  

    我们通常还包括如下行、用于检查 校准值是否尚未擦除:

      if (CALBC1_16MHZ==0xFF)					// If calibration constant erased
      {											
        while(1);                               // do not load, trap CPU!!	
      }

    在我们的示例中、我们只是进行陷阱管理 、但正如 David 所说的有关检查 TLV 校验和的内容、您将如何处理该错误情况由您来决定。  

    此致、
    Brandon Fisher

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢 Brandon!