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.

[参考译文] ADC 和 UART

Guru**** 2560390 points
Other Parts Discussed in Thread: MSP430FR2355

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/887707/adc-and-uart

器件型号:MSP430FR2355

工具/软件:TI C/C++编译器

我使用 MSP-EXT430FR2355 来实现 ADC 并转换 来自 UART 的数据。

调试时,始终收到 警告,通知我程序 无法执行。

警告:CPU 关闭(低功耗模式)并且中断被禁用! 无法执行 Step/Go。

我的计划是:

#include "msp430fr2355.h"

unsigned int ADvalue;
unsigned char a[2];
void ADC12Init (void);
空 UART0Init (空);

void main (void)

 WDTCTL = WDTPW+WDTHOLD;

 CSCTL3 |= SELREF_XT1CLK;//将 XT1设置为 FLL 基准源
 CSCTL0 = 0;//清除 DCO 和 MOD 寄存器
 CSCTL1 = DCORSEL_5;//设置 DCO = 16MHz
 CSCTL2 = FLLD_0 + 487;// DCOCLKDIV = 16MHz、16000000 / 32768-1=487
 CSCTL4 = SELMS_DCOCLKDIV | SELA_XT1CLK;//将 XT1 (~32768Hz)设置为 ACLK 源、ACLK = 32768Hz

ADC12Init();
UART0Init();
_EINT();

while (1)

  ADCCTL0 |= ADCENC | ADCSC;//采样和转换启动

  UCA0TXBUF = A[1];
  UCA0TXBUF = A[0];





空 ADC12初始化(空)


ADCCTL0 &=~ADCENC;
ADCCTL0 = ADCON;
ADCCTL1 = ADCCONSEQ_0+ADCSHP+ADCSSEL_0;
ADCCTL2 = ADCRES_2;

ADCMCTL0=ADCINCH_0+ADCSREF_0;
ADCIE =ADCIE0;
ADCCTL0 |= ADCENC;

空 UART0Init (空)

//配置 UART 引脚
P1SEL0 |= BIT6 | BIT7;//将2个 UART 引脚设置为第二功能(1.7TXD、1.6RXD)

//配置 UART
UCA0CTLW0 |= UCSWRST;
UCA0CTLW0 |= UCSSEL_SMCLK;
UCA0CTLW0 =UCSPB_0+UC7BIT_0;//8位传输、1位停止

UCA0BR0 = 0x8a;// 16000000/115200
UCA0BR1=0x0E;
UCA0MCTLW = UCBRS0;
UCA0IE |= UCTXIE0;
UCA0CTLW0 &=~UCSWRST;//初始化 eUSCI

#pragma vector=ADC_vector
_interrupt void ADC (void)

开关(ADCIV)

案例 ADCIV_0:break;
案例 ADCIV_2:break;
案例 ADCIV_4:break;
案例 ADCIV_6:中断;
案例 ADCIV_8:中断;
case ADCIV_10:break;

ADCIV_12案例:
ADvalue =ADCMEM0;
A[0]= ADValue&0xFF;
A[1]=(ADvalue>8)&0xFF;

ADCCTL0 |=ADCSC;
默认:中断;

请帮助我、谢谢!

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

    > UCA0IE |= UCTXIE0;

    删除此行。 您没有 UCA0的 ISR、因此您的程序将立即(在_EINT()之后)向量关闭到 ISR_TRAP。

    更一般而言、ADC 和 UART 都需要联锁:

    1) 1)您在 main 和 ADC ISR 中设置 ADCSC;您应该执行其中一个或另一个。 此外、您需要等待 ADC 完成、然后才能通过 UART 发送结果。

    2) 2)写入 UCA0TXBUF 而无需等待它变为可用(UCTXIFG)、因此会丢失字节。

    浏览中的示例可能很有用:

    http://dev.ti.com/tirex/explore/node?node=ACqyBhoKY-mma1YuW1PofA__IOGqZri__LATEST

    [编辑:将时钟设置为16MHz、而不设置 FRAM 等待状态。 请参阅示例 msp430fr235x_CS_03.c:

    http://dev.ti.com/tirex/explore/node?node=AKck5cmxoHuBiRVX8QJuhg__IOGqZri__LATEST

    ]

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

    感谢 你的答复。  我读取示例并重试,但我 从 PC 的串行端口接收到 ADvalue,数据已满“0”。

    我的计划是:

    #include "msp430fr2355.h"
    #include
    unsigned int ADvalue;
    unsigned char a[2];
    void Software_Trim ();//软件调整可获得最佳 DCOFTRIM 值
    #define MCLK_FREQ_MHz 16 // MCLK = 16MHz


    /
    函数功能:发送一个字节数据 μ A
    (二 /
    void UART_Send_Byte (unsigned char MyData)//发送一个字节

    UCA0TXBUF=MyData;//将数据写到数据发射缓冲器TXBUF1中,等待发射,发送完一个字节的数据为8位
    while (!(UCA0IFG&UCTXIFG));// UCTXIFG为发送器空标志,若为0表示TXBUF中有数据,为“1”表示TXBUF为空
    在此等待一个字节的数据发送完 μ s

    void main (void)

    WDTCTL = WDTPW+WDTHOLD;

    FRCTL0 = FRCTLPW | NWAITS_1;
    _bis_SR_register (SCG0);//禁用 FLL
    CSCTL3 |= SELREF_REFOCLK;//将 REFO 设置为 FLL 基准源
    CSCTL1 = DCOFTRIMEN_1 | DCOFTRIM0 | DCOFTRIM1 | DCORSEL_5;// DCOFTRIM = 5、DCO 范围= 16MHz
    CSCTL2 = FLLD_0 + 487;// DCOCLKDIV = 16MHz
    _DELAY_CYCLES (3);
    _BIC_SR_register (SCG0);//启用 FLL
    Software_Trim ();//软件调整可获得最佳 DCOFTRIM 值

    CSCTL4 = SELMS_DCOCLKDIV | SELA_REFOCLK;//将默认 REFO (~32768Hz)设置为 ACLK 源、ACLK = 32768Hz
    //默认 DCOCLKDIV 为 MCLK 和 SMCLK 源


    //配置 ADC A0引脚
    P1SEL0 |=BIT0;//使能AD输入,选择的通道为P1.0
    P1SEL1 |=BIT0;
    //配置 UART 引脚
    P1SEL0 |= BIT6 | BIT7;//将2个 UART 引脚设置为第二功能(1.7TXD、1.6RXD)
    //禁用 GPIO 上电默认高阻抗模式以激活
    //先前配置的端口设置
    PM5CTL0 &=~LOCKLPM5;//禁用 GPIO 上电默认高阻抗模式
    //配置 ADC12
    ADCCTL0 |= ADCSHT_2 | ADCON;// ADCON、S&H=16 ADC CLKS
    ADCCTL1 |= ADCSHP;// ADCCLK = MODOSC;采样计时器
    ADCCTL2 &=~ADCRES;//清除 ADCCTL 中的 ADCRES
    ADCCTL2 |= ADCRES_2;// 12位转换结果
    ADCMCTL0 |= ADCINCH_0;// A0 ADC 输入选择;Vref=AVCC

    //配置 UART
    UCA0CTLW0 |= UCSWRST;
    UCA0CTLW0 |= UCSSEL_SMCLK;
    //波特率计算
    // 16000000 /(115200)= 134.88888,134=0x8a
    //分数部分= 0.8888
    //用户指南表22-4:UCBRSx = 0xf7
    // UCBRFx = int ((134.8888-134)*16)= 14
    UCA0BR0 = 0x8a;// 16000000/115200
    UCA0BR1 = 0x00;
    UCA0MCTLW = 0xf700 | UCOS16 | UCBRF_1;
    UCA0CTLW0 &=~UCSWRST;//初始化 eUSCI

    ADCIE |= ADCIE0_1;//启用 ADC 转换完成中断//激活先前配置的端口设置


    while (1)

    ADCCTL0 |= ADCENC | ADCSC;//采样和转换启动
    _bis_SR_register (LPM0_bits | GIE);// LPM0、ADC_ISR 将强制退出
    __no_operation();//仅用于调试
    A[0]= ADValue&0xFF;
    A[1]=(ADvalue>8)&0xFF;
    UART_Send_Byte (A[0]);
    UART_Send_Byte (A[1]);

    // ADC 中断服务例程
    #if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
    #pragma vector=ADC_vector
    _interrupt void ADC_ISR (void)
    #Elif defined (_GNU_)
    void __attribute__((interrupt (ADC_vector))) ADC_ISR (void)
    其他
    错误编译器不受支持!
    #endif

    switch (__evo_in_range (ADCIV、ADCIV_ADCIFG))

    案例 ADCIV_NONE:
    中断;
    ADCIV_ADCOVIFG 案例:
    中断;
    案例 ADCIV_ADCTOVIFG:
    中断;
    ADCIV_ADCHIIFG 案例:
    中断;
    ADCIV_ADCLOIFG 案例:
    中断;
    ADCIV_ADCINIFG 案例:
    中断;
    ADCIV_ADCIFG 案例:
    ADvalue = ADCMEM0;
    _BIC_SR_REGISTER_ON_EXIT (LPM0_BITS);//从 LPM0清除 CPUOFF 位
    中断;
    默认值:
    中断;

    空 Software_Trim ()

    unsigned int oldDcotTap = 0xFFFF;
    unsigned int newDcoTap = 0xFFFF;
    unsigned int newDcoDelta = 0xFFFF;
    unsigned int bestDcoDelta = 0xFFFF;
    unsigned int csCtl0Copy = 0;
    unsigned int csCtl1Copy = 0;
    无符号 int csCtl0Read = 0;
    无符号 int csCtl1Read = 0;
    unsigned int dcoFreqTrim = 3;
    unsigned char endLoop = 0;

    操作

    CSCTL0 = 0x100;// DCO 抽头= 256
    操作

    CSCTL7 &=~DCOFFG;//清除 DCO 故障标志
    } while (CSCTL7 & DCOFFG);//测试 DCO 故障标志

    __DELAY_CYCLLES ((unsigned int) 3000 * MCLK_FREQ_MHz);//等待 FLL 锁定状态(FLLUNLOCK)保持稳定
    //建议等待24个经过分频的 FLL 参考时钟周期
    while (((CSCTL7 &(FLLUNLOCK0 | FLLUNLOCK1))和&((CSCTL7 & DCOFFG)= 0));

    CSCCtl0Read = CSCTL0;//读取 CSCTL0
    CSCCtl1Read = CSCTL1;//读取 CSCTL1

    oldDcoTap = newDcoTap;//记录上次的 DCOTAP 值
    newDcoTap = csCtl0Read & 0x01ff;//这次获得 DCOTAP 值
    dcoFreqTrim =(csCtl1Read & 0x0070)>>4;//获取 DCOFTRIM 值

    if (newDcoTap < 256)// DCOTAP < 256

    newDcoDelta = 256 - newDcoTap;// DCPTAP 和256之间的增量值
    if ((oldDcotap!= 0xFFFF)&&(oldDcotap >= 256)// DCOTAP 交叉256
    endLoop = 1;//停止 while 循环
    其他

    dcoFreqTrim --;
    CSCTL1 =(csCtl1Read &(~DCOFTRIM))|(dcoFreqTrim <4);


    else // DCOTAP >= 256

    newDcoDelta = newDcoTap - 256;// DCPTAP 和256之间的增量值
    if (oldDcoTap < 256)// DCOTAP 交叉256
    endLoop = 1;//停止 while 循环
    其他

    dcoFreqTrim++;
    CSCTL1 =(csCtl1Read &(~DCOFTRIM))|(dcoFreqTrim <4);

    if (newDcoDelta < bestDcoDelta)//记录最接近256的 DCOTAP

    csCtl0Copy = csCtl0Read;
    csCtl1Copy = csCtl1Read;
    bestDcoDelta = newDcoDelta;

    }while (endLoop =0);//轮询直至 endLoop =1

    CSCTL0 = csCtl0Copy;//重新加载锁定的 DCOTAP
    CSCTL1 = csCtl1Copy;//重新加载锁定的 DCOFTRIM
    while (CSCTL7 &(FLLUNLOCK0 | FLLUNLOCK1));//轮询直到 FLL 被锁定

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

    >UCA0BR0 = 0x8a;// 16000000/115200
    >UCA0MCTLW =0xf700 | UCOS16 | UCBRF_1;

    使用 UCOS16将 SMCLK 除以16、这使得 BRW=0x8A 太大(~7kbps)。 您可以调整一个或另一个。 我建议删除 UCOS16、因为这样可以提供更高的分辨率。

    [考古学家注意:运行此代码需要将 P1.6/7 (J1)修补到 RXD/TXD (J101、USB 端)、因为反向通道 UART 是 UCA1。]