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.

[参考译文] MSP430G2553:ADC10转换问题

Guru**** 2524550 points
Other Parts Discussed in Thread: MSP430G2553

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/771703/msp430g2553-adc10-convert-problem

器件型号:MSP430G2553
主题中讨论的其他器件: MSP-EXP430G2

大家好、我有 ADC 问题、

代码

----

int ADC_value;

void main (void)

WDTCTL = WDTPW + WDTHOLD;
ADC10CTL0 = SREF_0 | ADC10SHT_2 | ADC10ON;
ADC10CTL1 = INCH_0 | SHS_0 | ADC10DIV_0 | ADC10SSEL_2 | CONSEQ_0;
while (1)

ADC10CTL0 = ADC10CTL0 | ENC | ADC10SC;
while (ADC10CTL1 & BUSY)

AD_Value=ADC10MEM;
ADC10CTL0 &= ENC;


我已经看到 MSP430G2553的数据表并将 CONSEQ 设置为00模式

并查看流程图;

我确定 SHS=0、ENC=1、ADCSC=1;但是在调试中、我总是看到 SHS=0、ENC=1、ADC10SC=0 BUSY=0;  

它应该转至 convert process and Busy 应该更改为1;但是 ADC10SC & Busy 总是=0;为什么??

它会改变转换... 在 adc10MEM 处获取值;它在转换时应为1表示忙;并完成忙线解决自动变为零、但它不会

请观看视频;

e2e.ti.com/.../workspace_5F00_v8-_2D00_-MSP430G2553_5F00_tiny_5F00_printf_5F00_main.c-_2D00_-Code-Composer-Studio-2019_5F00_2_5F00_13-_0A4E4853_-10_5F00_35_5F00_19.mp4

如何解释; 我希望我的代码进入   "while (ADC10CTL1 & BUSY)"循环

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    > while (ADC10CTL1 & BUSY)
    >{
    >AD_Value=ADC10MEM;
    >ADC10CTL0 &= ENC;
    >}

    尝试:

    > while (ADC10CTL1 & ADC10BUSY)/* empty*/;//等待非忙
    >AD_VALUE = ADC10MEM;//获取结果
    >ADC10CTL0 &=~ENC; //禁用,直到下次
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    不,它不会去 while……一直都很忙,0也不会改变为1
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    视频中不清楚这是 ADC 问题、或者调试/项目中可能有问题。 您可能需要清理、然后重新构建项目、并再次尝试运行它。

    这里有很多 ADC10示例代码项目: dev.ti.com/.../

    您能否在 LaunchPad 上使用这些示例之一进行测试? 您可以 通过 View->Resource Explorer 将其直接导入 CCS。

    谢谢、
    JD

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    调试器中(CONSEQ=0)的 ADC10BUSY=1是不可能的、因为转换将在调试器执行其断点簿记时在后台完成。

    您的循环可能会(17个 MCLK)检测 ADC10BUSY=1 (一次)、但我不确定您会如何辨别。

    如果您的目标是执行 ADC 转换并检索结果、我建议使用我上面建议的代码。 如果您的目标不同、您可能需要更详细地解释。

    未经请求:如果您添加以下内容、您将获得更好的转换结果:
    >ADC10AE0 |= BIT0;//在 A0上禁用数字电路
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您的建议是无用的、并且您通过 ADC10提供代码示例、那么对于 conseq=00模式、它不是足够的
    好的、我问 u 我是否要使用 conseq=00模式、应该如何设置 ADC10寄存器??
    我不想更改重复我只想更改内核上的 ADC 通道。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    e2e.ti.com/.../4540.MSP430G2553_5F00_tiny_5F00_printf.7z

    首先、我在 msp430g2553中不知道如何使用 ADC10。数据表不清楚细节。
    我参考"MSP430微控制器基础知识"一书、了解 ADC 是否正在转换、繁忙状态应为1。
    但在视频中、我的寄存器忙始终为零、它可以为 ADC_vaule 更改完成????
    图22-5的过程假设寄存器设置 SHS=0且 ENC + ADC10sc 设置1和1 ins、则它应开始转换、
    不是? 那么、它将被覆盖、那么 BUSY 位的寄存器应该为1。此外、我如何在 CONSEQ_0模式中检查 COVERT 是否完成。
    数据表官员可能不是写初始信息? 哦、忙位可能不支持 conseq_0模式???????

    我逐步打开我的 ez430FET、我不会看到它总是在 while (ADC10CTL0&ADC10BUSY)处停止;

    哦、我确信它不会因位忙而发生变化。 但有时我会获得秘密价值???

    哦、可能我发布了我的项目。 奇怪的是、如果不处于调试模式、它会跳出 while 例程

    奇怪的是我将 AD 通道更改的代码放置在2个通道上,通过 A0PIN 获取 A1值, 通过 A1PIN 获取 a0值。

    这是一个大问题,如果在项目中使用它是可怕的,请解释。 请参阅项目注释 ADC 部分。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    也许您可以运行此代码,我确信 ADC 有很大的问题,那么我的机器就不能工作了。
    #include

    define Vref 3.3
    浮点开关_OUT;
    浮动 DC_CURRENT;
    int Current_temp;
    int PWM_temp;
    int PWM_OUT;
    int adc_flag;
    int Bkin;
    Int NOT;
    INT 测试;
    void printf (char *、...);
    void float_TO_int (float v、int 标志);
    void read_Bkin ();
    void open();
    void main (void)

    //禁用看门狗
    WDTCTL = WDTPW + WDTHOLD;
    //使用1MHz DCO 工厂校准
    DCOCTL = 0;
    BCSCTL1 = CALBC1_1MHz;
    DCOCTL = CALDCO_1MHz;
    BCSCTL2 = DIVS_3;// 1MHz/8 = 125KHz
    //为警报 LED 设置 GPIO
    P2DIR|=BIT0;
    P1DIR|=BIT5;
    //为 BKIN 输入设置 GPIO
    P2DIR&=~BIT7;
    ///PWM
    P2DIR|=BIT6;
    P2SEL|=BIT6;
    P2SEL &=~BIT7; //禁用 XTAL 引脚选择 TA0.1 PWM
    P2SEL2 &=~(BIT6 | BIT7);//禁用 XTAL 引脚选择 TA0.1 PWM
    //用于中断的计时器 A1
    TA1CCTL1=CCIE;
    TA1CCR0=1523;//持续0.1秒
    TA1CTL=tassel_2+ID_3+TAIE+TACLR+MC_1;//125KHz 8/8=15.625KHZ 1/15.625=0.064ms
    定时器 A0的//PWM 定时器
    TA0CTL=tassel_2+MC_1_ID_3;//125KHz / 8=15.625KHZ
    TA0CCTL1=OUTMOD_7;
    TA0CCR0=1023-1; //1/15.625KHZ=0.064ms,0.064*1023=65.472ms,1/65.472ms=15.27Hz,PWM 波形=15.27Hz
    //ADC_CHANNEL
    P1REN|=BIT0;
    P1REN|=BIT1;
    P2OUT&=~BIT0;
    _bis_SR_register (GIE);
    while (1)

    //flag=0、ADC 通道=A1;获取 switch_out 值
    if (ADC_FLAG = 0)

    ADC10CTL0 = SREF_0 | ADC10SHT_2 | ADC10ON;
    ADC10CTL1 = INCH_1 | SHS_0 | ADC10DIV_0 | ADC10SSEL_2 | CONSEQ_0;//CONSEQ_0 = 00模式、ADC 通道转换器1次。
    ADC10CTL0 = ADC10CTL0 | ENC | ADC10SC;//打开 ADC;
    while (ADC10CTL1&ADC10BUSY)


    PWM_TEMP=ADC10MEM;
    switch_out=vref/1023*pwm_temp;
    float_TO_int (Switch_out、ADC_flag);
    ADC10CTL0&=~ENC;
    ADC_FLAG = 1;
    // printf ("pwm_temp =%i\n"、pwm_temp);


    //flag=1,ADC 通道=A0;DC_CURRENT
    if (adc_flag==1)

    ADC10CTL0 = SREF_0 | ADC10SHT_2 | ADC10ON;
    ADC10CTL1 = INCH_0 | SHS_0 | ADC10DIV_0 | ADC10SSEL_2 | CONSEQ_0;//CONSEQ_0 = 00模式、ADC 通道变换器1次。
    ADC10CTL0 = ADC10CTL0 | ENC | ADC10SC;//打开 ADC;
    while (ADC10CTL1&ADC10BUSY)

    CURRENT_TEMP=ADC10MEM;
    DC_CURRENT_Vref/1023* CURRENT_temp;
    float_TO_int (DC_CURRENT、ADC_FLAG);
    ADC10CTL0&=~ENC;
    ADC_FLAG = 0;
    // printf ("current_temp =%i\n"、current_temp);


    open();
    Read_Bkin ();
    if (Bkin = 0)

    TA0CCR1=PWM_temp;

    其他

    TA0CCR1=0;

    //printf ("BKIN =%i\n"、Bkin);

    //if (a>10){P2OUT&=~BIT0;}
    //if (a>=100) a=0;
    //printf ("a =%i\n"a);

    if (not >5) P2OUT&=~BIT0;
    if (not <5) P2OUT|=BIT0;



    空 open ()

    if (DC_CURRENT_>2.67)

    P1OUT|=BIT5;
    // TA1CTL=MC_1;

    其他

    // TA1CTL=MC_0;
    P1OUT&=~BIT4;


    void read_Bkin ()

    if ((P2IN & BIT7)==0)

    Bkin = 0;

    其他

    Bkin = 1;


    void float_TO_int (float v、int 标志)

    int temp[1];
    整数满;
    full=(int) v;
    temp[1]=v;
    temp[0]=(v-full)*10;
    if (flag=0){printf ("Switch_out =%i"、temp[1]);printf ("。");printf ("%i\n"、temp[0]);}
    if (flag==1){printf ("DC_CURRENT =%I"、temp[1]);printf (".");printf ("%i\n"、temp[0]);}

    #pragma vector = Timer1_A1_vector
    _interrupt void Timer1_A1_ISR (void)

    switch (TA1IV)//读取 TA1的中断向量

    案例2:// TA1CCR1

    不是++;
    如果(不>=10)

    不= 0;


    中断;


    案例14://溢出- TA1IFG


    中断;


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

    您好!

    MSP430g2x33_ADC10_01是 P1.1上的单次转换。 它与您尝试的非常相似、但由中断驱动。 我刚刚下载并在 MSP-EXP430G2 launchpad 上运行、运行良好。 我建议与以下确切示例进行比较: dev.ti.com/.../

    将您的代码与上述示例进行比较、我看不到您设置了寄存器 ADC10AE0。 该寄存器使能 GPIO 作为模拟输入、是进行 ADC 测量所必需的。

    我建议运行和调试上述示例、然后调整示例以适合您的具体应用。

    谢谢、
    JD

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

    您好…您没有回答我的任何问题。 我已经看到了单次转换重复的示例,然后 conseq 为01,我只想说我需要 conseq=0模式示例,r u listen?

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

    也许这是缺失的部分:当你设定 ADC10SC 时、ADC10BUSY 立即变为1 (忙)、并且一旦转换完成、它自动返回0 (不再忙)。 在整个序列之后、转换完成。 (我认为这是用户指南(SLAU144J)中明确提到的、但我似乎找不到它。)

    此过程(0->1->0)非常快。 调试器太慢、您无法看到 ADC10BUSY=1。 您的程序可能会也可能不会在1 (取决于编译器生成的代码)看到它。 但您只对它返回到0后的点感兴趣、这意味着转换已完成。

    当 ADC10BUSY=1时、您不应该接触任何寄存器。

    这就是我上面建议的代码只要 ADC10BUSY=1、并且只在之后读取 ADC10MEM 的原因。 您还可以在示例 msp430g2x33_ADC10_05.c 中看到这一点、如下所示:
    dev.ti.com/.../

    该程序正在使用内部通道(INCH_11)、因此它不会设置 ADC10AE0。 但您的程序应该(见上文)。

    [编辑:略作修改。]

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

    e2e.ti.com/.../MSP430G2553_5F00_tiny_5F00_printf.rarok,thx对于 u,但还有其他问题,请查看我的项目文件

    我想问为什么我看到 P1.0 (A0)为 A1值获取 ADC_cahnnel、P1.1 (A1)为 A0值获取 ADC_cahnnel

    打开我的项目并刻录代码、请参阅打印;并通过硬件操作、您会发现这很奇怪;

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

    这似乎与您之前发布的代码相同。 它始终从 A1读取、因为您正在错误地检查 ADC 完成情况、因此 ADC_FLAG 始终为=0。 它总是过早读取结果并获得先前的结果。

    如果您进行了我建议的更改(到目前为止已进行3次)、我希望它将在 A0和 A1之间来回切换。 您将正确匹配结果。

    此外、我不建议为 P1.0/1 (A0/1)设置 P1REN 位。 根据数据表(SLAS735j)中表16之前的原理图、设置 ADC10AE0似乎不会禁用电阻器。

    此外、"不"应声明为"易失性"。

    [编辑:由于代码格式化、我第一次读取错误。]

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

    好的、我修改了代码

    ****
    if (ADC_FLAG = 0)

    ADC10CTL0 = SREF_0 | ADC10SHT_2 | ADC10ON;
    ADC10CTL1 = INCH_1 | SHS_0 | ADC10DIV_0 | ADC10SSEL_2 | CONSEQ_0;//CONSEQ_0 = 00模式、ADC 通道转换器1次。
    ADC10CTL0|= ENC + ADC10SC;//打开 ADC;
    while (ADC10CTL1&ADC10BUSY);
    a1=ADC10MEM;
    a1_Voltage=Vref/1023*a1;
    float_TO_int (a1_Voltage、adc_flag);
    ADC10CTL0&=~ENC;
    ADC_FLAG = 1;

    if (adc_flag==1)

    ADC10CTL0 = SREF_0 | ADC10SHT_2 | ADC10ON;
    ADC10CTL1 = INCH_0 | SHS_0 | ADC10DIV_0 | ADC10SSEL_2 | CONSEQ_0;//CONSEQ_0 = 00模式、ADC 通道变换器1次。
    ADC10CTL0|= ENC + ADC10SC;//打开 ADC;
    while (ADC10CTL1&ADC10BUSY);
    A0=ADC10MEM;
    A0_Voltage=Vref/1023*A0;
    float_TO_int (A0_Voltage、ADC_FLAG);
    ADC10CTL0&=~ENC;
    ADC_FLAG = 0;

    ***

    它可以正常工作、并使用 a0和 a1值进行校正。

    非常多

    这是您的意思吗?
    我没有在 while ()中 foud;我总是想 while (){;}、哈哈、我犯了这么大的错误

    另一个问题是 、此转换时间~转换完成的代码循环中的采样速度有多快

    对于 tsample peroid 为1MHz*8=8MHZ。 tconvert 时间是13*ADC10CLK =13MHZ?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    SHT=2、ssel=2 (MCLK=1MHz)时的 ADC 转换时间为(16+12+1)*1usec=29usec。 [参考用户指南(SLAU144J)图22-5]

    这里的采样不是由 ADC 进行的,而是由 MCU 正在进行的另一项工作进行的--我看到了一些浮点算术运算和针对每次转换的几个 printf()调用,这些调用的相加时间将远远超过 ADC 时间。 我认为我无法对所有这些花费的时间作出合理的估计。

    如果您有示波器、最简单的测量方法是采用未使用的 GPIO 引脚并在每次转换之前进行切换、然后使用示波器测量边沿之间的时间。

    如果您没有示波器、则可以在每次转换之前捕获 TA1R、并减去之前的值(模数 TA1CCR0)。 我希望该值将小于 TA1时间范围(98.24毫秒)、因此它应该合适。

    请记住、每次您更改代码中的任何内容(或优化级别)时、这些计时以及采样率都会发生变化。