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.

[参考译文] MSP430F5172:ADCCLK 的 MODOSC 频率

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1027130/msp430f5172-modosc-frequency-for-adcclk

器件型号:MSP430F5172

您好!  

我使用 ADC 通过 MSP430f5172微控制器感应电压和电流。 我正在使用 MODOSC 时钟、因此数据表显示它以5MHz 的频率运行。 然而、当我使用一个简单的 LED 打开和关闭代码来查看它的执行时间时、它的频率为10s 或更低。 这是测量 ADC 采样频率的正确方法吗? 我本来期望~300kHz、因为我正在使用采样并保存16个样本。  

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

    还有(10+1)个转换时钟、通过 CONSEQ=2将转换时钟限制在185ksps [参考用户指南(SLAU208Q)图27-8]。

    我的第一个猜测是您的 LED 监视器运行过度。 使用1MHz MCLK 时、每次转换只能获得大约5个 MCLK (CONSEQ=2)、这几乎不足以调用 ISR。 您能否描述您的测试用例(例如、张贴/附加您的代码)?

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

    Bruce、您好!  

    感谢你的答复。 以下是我的代码。 我正在使用 DMA 并同时读取通道序列。  

    #include
    #include
    #include

    //定义函数
    void SetVcoreUp (unsigned int level);
    void SetADC ();
    void SetDMA();

    #define T_BUCK 200 //降压级周期- 200MHz/500kHz (所需频率)=400
    #define T_BOOST 200 ////升压级周期
    unsigned int adc_result[9];// 10位 ADC 转换结果数组
    int iin_temp;// 10位 ADC 转换结果数组
    int Vin_temp;// 10位 ADC 转换结果数组
    int vbat_temp;// 10位 ADC 转换结果数组
    int ibat_temp;// 10位 ADC 转换结果数组
    int Vout_temp;// 10位 ADC 转换结果数组
    int Iout_temp;// 10位 ADC 转换结果数组
    int Vbuckout_temp;

    void main (void){


    WDTCTL = WDTPW + WDTHOLD;//停止看门狗计时器

    //配置 PWM 通道
    P1SEL |= BIT7;//将 P1.7设置为输出方向-高降压
    P1DIR |= BIT7;

    P3SEL |= BIT0;//将 P3.0设置为输出方向- BAT_GD_EN
    P3DIR |= BIT0;

    P2SEL |= BIT0;//将 P2.0设置为输出方向-低降压
    P2DIR |= BIT0;

    P2SEL |= BIT2;//将 P2.2设置为输出方向-高升压
    P2DIR |= BIT2;

    P2SEL |= BIT3;//将 P2.3设置为输出方向-低升压
    P2DIR |= BIT3;

    P2SEL |= BIT6;//将 P2.6设定为输出方向- Vgate BAT
    P2DIR |= BIT6;

    //配置 ADC 引脚
    PMAPPWD = 0x02D52;//启用写入访问以修改端口映射寄存器
    PMAPCTL = PMAPRECFG;//允许在运行时重新配置
    //P1MAP0|= PM_ANALOG;//修改所有 PxMAPy 寄存器- A0
    P1MAP1|= PM_ANALOG;//修改所有 PxMAPy 寄存器- A1
    P1MAP2|= PM_ANALOG;//修改所有 PxMAPy 寄存器- A2
    P1MAP3|= PM_ANALOG;//修改所有 PxMAPy 寄存器- A3
    P1OMAP4|= PM_ANALOG;//修改所有 PxMAPy 寄存器- A4
    P1MAP5|= PM_ANALOG;//修改所有 PxMAPy 寄存器- A5
    P3MAP5|= PM_ANALOG;//修改所有 PxMAPy 寄存器- A8
    P3MAP6|= PM_ANALOG;//修改所有 PxMAPy 寄存器- A7
    PMAPPWD = 0;//通过写入不正确的密钥来禁用写入访问以修改端口映射寄存器
    P1SEL |=BIT5+BIT4+BIT3+BIT2+BIT1+BIT0;//在应用模拟信号时将端口映射寄存器 PxMAPy 与 PxSEL.y=1一起设置为 PM_ANALOG
    P3SEL |=BIT6+BIT4;

    //将 Vcore 设置增加到3级以支持 fsystem=25MHz
    //注意:一次改变一个电平内核电压。

    SetVcoreUp (0x01);
    SetVcoreUp (0x02);
    SetVcoreUp (0x03);

    //将 DCO 初始化为25MHz
    _bis_SR_register (SCG0);//禁用 FLL 控制循环-设置 SCG0
    UCSCTL0 = 0x0000;//设置可能的最低 DCOx、MODx
    UCSCTL1 = DCORSEL_6;//选择 DCO 范围4.6MHz-88MHz 运行
    UCSCTL2 = FLLD_1_763;//将 DCO 乘法器设置为25MHz
    //(N + 1)* FLLRef = Fdco
    //(762 + 1)* 32768 = 25MHz
    //设置 FLL Div = fDCOCLK/2

    _BIC_SR_register (SCG0);//启用 FLL 控制循环-清除 SCG0

    // DCO 范围位已经存在时、DCO 的最坏情况稳定时间
    //已更改 n x 32 x 32 x f_MCLK / f_FLL_reference。 请参阅5xx 中的 UCS 一章
    // UG 进行优化。
    // 32 x 32 x 25 MHz/32、768Hz = 781250 = DCO 稳定的 MCLK 周期
    //__delay_cycles (781250);
    _DELAY_CYCLES (782000);

    SetADC();
    SetDMA();
    SetPWM (T_BUCK、T_BOOST);
    __DELAY_CYCLES (100);//序列转换之间的延迟

    P1DIR |= BIT0;//将 P1.0设置为输出方向

    for (;;){

    // ADC 采样频率  
    P1OUT ^= BIT0;//使用异或切换 P1.0

    while (ADC10CTL1 & BUSY);//如果 ADC10内核处于活动状态则等待
    ADC10CTL0 |= ADC10ENC + ADC10SC;//采样和转换准备就绪
    _bis_SR_register (CPUOFF + GIE);// LPM0、ADC10_ISR 将强制退出

    _bis_SR_register (LPM0_bits);//输入 LPM0


    // DMA ISR
    #if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
    #pragma vector=dma_vector
    _interrupt void DMA0_ISR (void)
    #Elif defined (_GNU_)
    void __attribute__((中断(DMA_vector)) DMA0_ISR (void)
    其他
    错误编译器不受支持!
    #endif

    switch (__evo_in_range (DMAIV、16))

    情况0:中断;//无中断
    案例2:
    //转换序列完成
    ADC10CTL0 &=~ADC10ENC;//禁用 ADC 转换
    _BIC_SR_REGISTER_ON_EXIT (CPUOFF);//退出 LPM
    中断;// DMA0IFG
    案例4:中断;// DMA1IFG
    案例6:中断;// DMA2IFG
    案例8:中断;//保留
    案例10:中断;//保留
    案例12:中断;//保留
    案例14:中断;//保留
    案例16:中断;//保留
    默认值:break;

    //函数

    void SetVcoreUp (无符号 int 级别)

    //子例程来更改内核电压
    //打开 PMM 寄存器进行写入
    PMMCTL0_H = PMMPW_H;
    //将 SVS/SVM 高电平设置为新的电平
    SVSMHCTL = SVSHE + SVSHRVL0 *电平+ SVMHE + SVSMHRRL0 *电平;
    //将 SVM 低电平设置为新的电平
    SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 *电平;
    //等待 SVM 稳定
    while ((PMMIFG & SVSMLDLYIFG)=0);
    //清除已设置的标志
    PMMIFG &=~(SVMLVLRIFG + SVMLIFG);
    //将 VCORE 设置为新的电平
    PMMCTL0_L = PMMCOREV0 *电平;
    //等待达到新级别
    IF (((PMMIFG 和 SVMLIFG))
    while ((PMMIFG & SVMLVLRIFG)=0);
    //将 SVS/SVM 低电平侧设定为新的电平
    SVSMLCTL = SVSLE + SVSLRVL0 *电平+ SVMLE + SVSMLRRL0 *电平;
    //锁定 PMM 寄存器以进行写访问
    PMMCTL0_H = 0x00;

    //配置 ADC 通道
    void SetADC (){
    ADC10CTL0 = ADC10SHT_2 + ADC10MSC + ADC10ON;// 16xADC 时钟周期、多采样转换、ADC10ON
    ADC10CTL1 = ADC10SSEL_0+ADC10SHP+ ADC10CONSEQ_1;// ADCCLK = MODOSC;采样信号来源于采样定时器、单次序列
    ADC10CTL2 = ADC10RES;// 10位转换结果
    ADC10MCTL0= ADC10INCH_8 + ADC10SREF_1;//选择 ADC 通道;使用 VR+= VREF 和 VR-= AVSS

    //默认情况下、REFMSTR=1 => REFCTL 被用来配置内部基准
    while (REFCTL0 & REFGENBUSY);//如果基准发生器忙,请等待
    REFCTL0 |= REFVSEL_2 + REFON;//选择内部基准= 2.5V
    _DELAY_CYCLS (75);//参考建立延迟(~75us)-ADC10采样和转换=(32+13)*2/SMCLK = 90/SMCLK = 75us

    void SetDMA(){
    //配置 DMA0 (ADC10IFG 触发器)
    DMACTL0 = DMA0TSEL_24;// ADC10IFG 触发器
    __data20_write_long ((uintptr_t)&DMA0SA、(uintptr_t)&ADC10MEM0);//源单地址
    __data20_write_long ((uintptr_t)&DMA0DA、(uintptr_t)&ADC_Result [0]);//更新目标数组地址
    DMA0SZ = 0x09;// 8次转换-字节或字传输的数量
    DMA0CTL = DMADT_4 + DMADSTINCR_3 + DMAEN +DMAIE;// Rpt、inc dest、启用转换序列后的 int

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

    看起来您正在转换9个通道(INCH=8、MSC=1、CONSEQ=1)。 因此、我预计大约(5M/(16+11)/9)= 20k "突发"/秒 您的测量结果是这样吗?

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

    是的,这接近于我得到的值。 不过、我有两个问题。 我们为什么要除以(16+11)。 我明白为什么有16个、但不确定是否有11个。 我的第二个问题 与在每个 通道中使用 DMA 与顺序代码进行感应有关。 我的硬件原型上有大约7个传感器、我认为使用 DMA 和自动扫描模式来获取所有通道将有助于我提高性能。 我是否应该使用某种方法来提高性能? 我在降压和升压转换器级中使用该器件、由于与开关频率(500kHz)相比、我的采样频率非常小、因此我的闭环无法稳定  

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

    1) 1) 11表示10个转换时钟和1个移动结果时钟。 [参考 UG 图27-7]。 查看 UG 表27-5、"10"指的是8位结果。 您的情况(10位)需要(12+1)才能实现正确的转换。

    2) 2)带有 DMA 的 CONSEQ=1非常接近您可以做的最好的事情。 您可以选择 CONSEQ=3、但不能选择采样率。 只有一个采样电容器(SET)、因此您无法并行进行转换。

    一个选项是减少采样/保持时间(SHT0)。 有一个较低的限制、它实际上是电气限制(源阻抗)、但如果您不处于该限制、则可以获取几个时钟[参考 UG 章节27.2.5.3]。 您还可以执行8位采样、这样可以减少2个转换时钟。 即使所有这些都不会使您获得超过40%的增益。

    数据表仅声明200ksps (渐近)、并将其分布在9个通道上、每个通道的工作速率约为22ksps。 即使是单个500kHz 信号、也不会成功进行奈奎斯特采样。 我对开关稳压器的工作方式不了解多少详细信息。 您是否有机会在数字域中执行某些操作?

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

    感谢您的详细回答。 我尝试在 PLECs 仿真中降低采样频率、它可以工作、但在硬件中不能工作。 我将研究其他选项。  

    此外、计算中可能缺少系数2、因为我刚刚检查了采样频率、它实际上是计算结果的~一半。 对于9个样本、采样频率为9kHz;对于1个样本、采样频率约为62.5KHz。 此外、当我使用子模块/主时钟时、采样频率高于 MODOSC。 我本来希望 MODCLCK 的值更高、但 DMA 也能与 MODCLK 配合使用、所以在使用这些替代时钟时、我没有获得正确的传感器读数。 我是否可以在设置中执行错误操作?

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

    如果您使用的是 SMCLK (25MHz)、请记住 ADC10_A 被限制为5.5MHz 时钟[参考数据表(SLAS619R)第5.39节]、因此您需要对 SMCLK 进行分频、此时您也可以使用 MODCLK。

    我怀疑您也受到源阻抗的限制;这通常表现为串扰。 这是一项物理定律(您将电子输入采样电容器的速度有多快?) 因此、这里没有太多技巧。 如果将 SHT0降低得太低、则会得到相同的效果。

    UG 章节 27.2.5.3中有一个公式、可为您提供最短采样时间(然后转换为时钟)。 我的经验是,这个公式有点乐观,我通常不得不四舍五入。