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.

[参考译文] MSP430F5438A:ADC12定时器触发

Guru**** 2589280 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/746039/msp430f5438a-adc12-timer-trigger

器件型号:MSP430F5438A

您好!

我正在尝试从以下光学灰尘传感器收集数据:

根据数据表的第5页、我 使用计时 器 A 为传感器的输入引脚3生成了正确的 PWM 信号、并在 示波器中观察到该信号。 现在、在图2的同一页上、他们讨论了输出脉冲采样时序。 有人可以帮助我了解如何为此设置 ADC12? 有关这方面的问题很少:

我的采样保持时间应该是0.28ms 吗?

如果是、那么我应该等待下一 个0.04ms + 9.68ms 来收集我的下一个 ADC 值、因为输入脉冲需要很长时间到达?

3.如果1和2正确、如何为此设置 ADC?  

谢谢、

 

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

    我不会评论您所查看的传感器的具体细节、但该应用似乎类似于常规烟雾探测器应用。 请参阅以下资源、这些资源可能会帮助您完成应用。 器件不同、但通用原理相同。

    此博客底部链接了大量设计资源:
    e2e.ti.com/.../designing-a-smoke-detector-with-the-smart-analogue-combo-in-the-msp430fr2355

    烟雾探测器应用手册:
    http://www.ti.com/lit/slaa335

    您很可能还需要实现计时器触发的 ADC 采样。 请参阅以下链接、了解器件的示例代码。 请查看示例 DMA04。 它显示了如何为计时器触发器配置 ADC、但增加了 DMA 用法移动所述 ADC 样本的复杂度。
    dev.ti.com/.../
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    当我读取此数据时、您的 MCU 会生成传感器激活(LED)脉冲、建议占空比为0.32ms (10ms)。 然后、建议您在脉冲变为低电平之前(以及从脉冲开始至少0.28ms)尽可能晚地对电压电平进行采样、以便在脉冲变为低电平之前完成采样。 这将使您<= 40 μ s (0.040毫秒)进行转换。

    [如果这不是它的工作方式、请忽略其余部分。]

    转换当然可以在<= 40usec 的条件下完成,只需选择合适的(SHT+13)*ADCCLK 即可。

    我看不到您将如何使用单个 CCR 进行协调。 我建议在 CCR 脉冲之前使用第二个 CCR 设置进行比较匹配(SHT+13)* ADCCLK,并使用它来触发 ADC。 您需要调查数据表中的可用 ADC 触发器(SHS 设置)、并选择一个也具有引脚输出的计时器。 ADC 触发 OUTMOD 应该被置位/复位并且脉冲应该被复位/置位。

    [我可能已经使它听起来很复杂、但它比代码更具算术功能。]
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!
    感谢您的回答。 我编写了以下代码。 现在问题是、我始终得到零。 不确定是计时器和 ADC 设置问题还是概念问题。 我要做的是设置一个计时器、为传感器输入生成 PWM。 另一个计时器、用于在传感器获得激活脉冲的同时精确触发 ADC12。 在我的 ADC12中、我将采样保持时间设置为大约0.26ms (不能将其设置为0.28ms、这是建议的)。 然后、我将通过 UART 发送 ADC 数据、以便检查我的 ADC 值(使用 tera 项查看规则)。 I.m 在 MSP 编码中效率低下、这就是为什么不使用 ISR 而不处理其他复杂问题的原因。

    我的代码:
     

    #include 
    
    volatile unsigned char volt [5];
    volatile unsigned int in_value;
    
    void clock_setup (void);
    void clock_setup (void)
    {
    P11DIR |= BIT0;
    P11SEL |= BIT0;// ACLK
    P11DIR |= BIT1;
    P11SEL |= BIT1;// MCLK
    P11DIR |= BIT7
    ;= BIT7|= BIT7
    ;= BIT7;= BIT7;= BIT7;= BIT7;= BITCL2;= BIT7
    // ADC12 CLK
    }
    
    void init_serial (void);
    void init_serial (void)
    {
    P5SEL |= 0xC0;// 5.6和5.7 for TX/RX- UCA1
    UCA1CTL1 |= UCSWRST;
    UCA1CTL1 |= UCSSEL_1;//32768Hz
    UCA1BR0调制=
    
    
    0x00;UCA1CTR1 = 0x00;UCA1CTL = 0x00;// UCA0= 0x00;UCA1CT08 = 0x00;UCA0= UCA0= 0x00
    UCA1CTL1 &=~UCSWRST;//在操作模式
    
    下}
    
    void ADC_Value (int);
    void ADC_Value (int ADC_Data)
    {
    volatile char x=3;
    [3]= volt [2]= volt [1]= volt [0]= 0x30;
    while (ADC_Data > 0)
    {
    [x]= volatile [x]= volt [2];= volt ADC_Data|= 0x30;/voltage/ADC_Data = 10)
    //数字的其余部分与最后一位
    数的 x -;
    }
    伏特[4]='\0';
    }
    
    void Send_Serial (void);
    void Send_Serial (void)
    {
    volatile char I=0;
    while (volt[i]!='\0')
    {
    UCA1TXBUF = VOL[i];
    
    while (UCA1STAT & UCB1UCA+
    
    
    
    
    );UCA1TXBUF+= 0xUCA1+;UCA1UCA1UCA1UCA0+;UCA1UCA1UCA1UCA+= 0xUCB0UCA+;UCA1UCA1UCA1UCA1UCA+;
    while (UCA1STAT 和 UCBUSY);
    
    }
    
    
    int main (void)
    {
    clock_setup ();
    init_serial ();
    
    WDTCTL = WDTPW + WDTHOLD;//停止 WDT
    P8DIR |= BIT6;// P8.6输出
    P8SEL |= BIT6;// P1DIR 选项选择
    P1DIR |= BIT1
    
    
    ;P1TP1 = BIT1;/ PIT1;PSRT1 = BTRT1;= PIT1;PWM= BTR1;PWM= BIT1;PWM= BIT1;PWM= BTR1;
    // PWM 周期
    TA1CCTL1 = OUTMOD_7;// CCR1复位/设置
    TA1CCR1 = 10286;// CCR1 PWM 占空比-->从10ms 中获得0.32ms 低电平脉冲,在9.68ms TA1CTL
    = tassel_SMCLK + MC_UP + TACLR; // SMCLK、向上计数模式、清除 TAR
    
    //配置 Timer0_A3以定期触发 ADC12
    TA0CCR0 = 10617-1;// PWM 周期
    TA0CCTL1 = OUTMOD_3;// TACCR1设置/复位
    TA0CCR1 = 10286;// TACCR1 PWM 占空比- >在9.68ms 触发 ADC12、同时传感器获得低输入
    TA0CTL = tassel_SMCLK + MC_UP + TACLR;// SMCLK、UP 模式、清除
    
    P6SEL |= BIT7;
    // ADC12CTL0中的 ADC = ADC12SHT0_8 + ADC12TAR; //采样时间(((256+13)/(ADC_CLK)=0.26ms、不能得到传感器数据表建议的0.28ms)、
    ADC12CTL1上的 ADC12 = ADC12SHP + ADC12SH_1;//使用采样计时器+ MCLK
    ADC12MCTL0 = ADC12INCH_7;
    
    
    而
    
    ~
    
    ADC12C12C12S0 = ADC12C12C12F 和 ADC12C12C12C12C12C12C12C0;ADC12C12C12C12C0 = ADC12C12C12C12C12C12C12C12C12C12C12C12C12C12C12C0 (ADC12C0 + ADC12C12C12C12MC
    
    P1OUT ^= BIT1;
    ADC_VALUE (IN_VALUE);
    发送串行();
    }
    
    



    我也在为该传感器附加 Arduino 版本(可在 Web 中找到)代码。 我正在尝试在 MSP430中实现相同的东西。 我测试了代码、它非常适合传感器。 如果我在振铃柱中解释了传感器的任何错误、我会附加此信息。
    Arduino 代码版本:

    int sensePin = A0;
    int ledPin = 9;
    
    int Tsampling = 280;
    int Tdelta = 40;
    int Tsleep = 9680;
    
    float outVo = 0;
    float sigVolt
    = 0;float
    
    setup ()= 0;void setup (){
    Serial.begin(9600);
    pinitalMode (ledPin、output);
    }
    
    void loop (leWrite
    (ledPin、low
    
    
    )
    
    ;digaydelta
    (ted);s (tdelegydelayed);s (tdelegydelayed);s (tdelegydelegydelegsent loop (lid);s (ted
    delayMicroseconds (Tsleep);
    
    sigVolt = outVo *(3.3 / 1024);
    
    灰尘浓度 Level = 0.17 * sigVolt - 0.1;
    
    Serial.print ("测量信号值(0-1023):");
    Serial.print (outVo);
    
    Serial.print ("电压:");
    Serial.print (sigvolt
    
    
    );Serial.print (
    
    1000);Dust Print (sigeln);Dust Level (1000)(集尘密度)
    



    希望你们中的任何人都能帮助我了解我的错误!

    谢谢、

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

    在论坛上发布代码时、请使用标记的代码格式工具 按钮。 可以通过单击回复菜单右下角的"插入代码、附件文件等"链接来找到此工具。 代码格式化工具可让您轻松阅读代码、并帮助您更快地在论坛上获得支持。 我修改了您之前的帖子、以反映该工具的使用情况。

    我强烈建议大家花时间切换到这里的中断驱动方法、因为这将使您的工作时序更轻松。 您可能还需要提高 MCLK 速度、以便在您的时间范围内完成所需的所有操作。 您似乎以默认的1MHz 速度运行。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    将两个 CCR1值设置为相同(10286)将在脉冲开始时触发 ADC、这有两个问题:

    1) 1)您不希望采样电容器在该较长的上升时间(标称值230us)内集成、也不希望对其进行快照、而是希望在其电平处于高值后才对其进行快照。
    2)您使用的是 ADC12SSEL_0=ADC12OSC、它的运行频率大约为4.8MHz、因此转换时间大约为(大约)(256+13)/4.8=54usec。 这意味着您的转换在信号(如图2所示)大幅上升之前完成。

    我建议您将采样时间缩短为64个时钟(SHT0_4)、在 ADC12OSC 容差范围内、这些时钟仍然小于19usec。 然后从脉冲关闭时间中减去40usec、即设置 TA0CCR1 = 10617-1.06*40 (我假设1.06是您测得的 SMCLK 校正)。

    因此、脉冲开始10286个周期、然后 ADC 以10575个周期触发、然后 ADC 运行直到大约10595个周期、然后脉冲以10617个周期结束。 您最终可能会对这些进行微调、但我认为这是正确的。
    ------
    我同意 Jace 的说法、您可能最终会得到一个中断驱动的结构。 您面临的问题是、轮询 ADC 的常用方法会等待 ADCBUSY 变为低电平、但您不知道何时变为高电平。 (我怀疑这是您看到0的原因。)

    此时、您可能会放弃两相轮询:等待 ADCBUSY 变为高电平、然后变为低电平:
    > while (((ADC12CTL1 & ADCBUSY)=0)/*empty*/;//等待它启动
    > while ((ADC12CTL1 & ADCBUSY)!= 0)/* empty*/; //等待它结束

    设置 SC 没有任何价值。 在环路前设置 ENC=1、然后让定时器触发周期。
    ------
    使用两个计时器并不理想、但我同意 F5438A 中的 SHS 选项不会使其变得简单。 使用两个计时器将导致轻微的异步(固定偏移)、但目前上述数字具有大量的斜率。 长期而言、您可能会尝试移动到 TB0、它具有外部引脚和 ADC 触发器(SHS=3)。