主题中讨论的其他器件:MSP430F5438A
12位完成中断并不总是发生。 通常、ADC 转换开始后、ADC 完成转换并发出中断。 在该器件上、中断在某些时间内未能发生并变为"停止"状态。 清除触发器(ADC12SC)前几个数量级的延迟似乎是使 ADC "解除卡滞"的唯一方法。 感谢您在解决此问题方面提供的任何帮助。
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.
12位完成中断并不总是发生。 通常、ADC 转换开始后、ADC 完成转换并发出中断。 在该器件上、中断在某些时间内未能发生并变为"停止"状态。 清除触发器(ADC12SC)前几个数量级的延迟似乎是使 ADC "解除卡滞"的唯一方法。 感谢您在解决此问题方面提供的任何帮助。
你(们)好 感谢您的回答。 我们的应用运行的 ADC 计时器不在 ACLK @ 32kHz 范围内。 我们的采样保持时间为32个周期或大约1毫秒。 我认为每个转换周期需要12个时钟。 这将是366us。 每个通道所需的总时间不应超过2毫秒。 被转换的通道总数为2 - 4msec。 首次转换在启动时触发。 然后、我们在触发另一个转换之前等待100ms。 之后、我们将每4秒触发一次转换。 在三个电路板上、我们看到第二次转换不会触发。 我们已发货的所有其他板(150+)未显示此问题。
在触发另一个转换之前、我们将检查忙标志。 完成转换后、我们不会设置 ADC12ENC = 0。 我不明白为什么在 ADC12中断触发后再添加50ms 延迟、然后设置 ADC12ON = 0和 ADC12SC = 0似乎可以避免这个问题。 当 ADC12SC 和 ADC12SC 必须在新的转换发生前清零时、ADC12中断发生后是否有计时窗口? 感谢你的帮助。
下面是我们的配置:
1.初始化 ADC12代码:
initAdc()
// REFON 必须打开才能配置器件。 然后可以将其关闭。
REFCTL0 =(REFMSTR // REF 由其自身的位而不是传统的 ADC 位控制
| REFVSEL_3 //将 REF 设置为2.5V
| REFON //必须在配置期间置位
);
P6SEL = ADC_IN_3;// P6.3 ADC 模式
ADC12CTL0 =(ADC12SHT1_15 //通道8-15的 S&H 时间为32个时钟(1msec)
| ADC12SHT0_15 //通道0 - 7的 S&H 时间为32个时钟(1毫秒)
| ADC12MSC
| ADC12ON);//打开 ADC。
ADC12CTL1 =(ADC12CSTARTADD_0 //从转换存储器0开始
| ADC12SH_0 //由 ADC12CTL0中的 ADC12SC 位发起的 S&H
| ADC12SHP // S&H 由计时器结束
| ADC12DIV_0 // ADC12时钟除以1
| ADC12SSEL_1 // ADC12时钟源为 ACLK
| ADC12CONSEQ_1);// ADC12转换一个通道序列
ADC12CTL2 =(ADC12TCOFF //内部温度传感器关闭。 将在需要时打开
| ADC12RES_2 // 12位分辨率
| ADC12SR);//采样率< 50ksps
ADC12MCTL0 =(ADC12SREF_1 //使用 VREF+和 AVSS 作为参考
| ADC12INCH_3);//输入通道3 (电池电压/11)
ADC12MCTL1 =(ADC12EOS //序列结束-这是序列中的最后一个寄存器
| ADC12SREF_1 //使用 VREF+和 AVSS 作为参考
| ADC12INCH_10);//输入通道10 (温度传感器)
ADC12IE = ADC12IE0;//在完成第一个(和唯一的)转换(VCC)后获得一个中断
ADC12CTL0 |= ADC12ENC;// ADC12的配置要求 ADC12ENC =0
adcInProgress = 0;
REFCTL0 &=~REFON;
REFCTL0 |= REFTCOFF;
}
2. adcStart()-此例程通常每4秒调度一次,以开始新的转换。
a.检查 ADC 是否繁忙
b. REFCTL0 |=温度传感器的 REFON //导通基准
REFCTL0 &=~REFTCOFF //打开温度传感器
ADC12CTL0 |= ADC12ON | ADC12SC //打开 ADC 并开始转换
3.当转换中断发生时:
a.获取 ADC12MEM0读数
b.获取 ADC12MEM1读数
c. ADC12CTL0 &=~(ADC12ON | ADC12SC)//关闭 ADC 并清除触发
d. REFCTL0 &=~REFON
e. REFCTL0 |= REFTCOFF
> | ADC12SHT0_15 //通道0 - 7的 S&H 时间为32个时钟(1msec)
SHT0=15是1024个时钟、所以每次转换大约为33ms。 [参考 UG (SLAU208Q)表28-4]
----------------------------------------------------
>ADC12MCTL1 =(ADC12EOS //序列结束-这是序列中的最后一个寄存器
>ADC12IE = ADC12IE0;//在完成第一个(和唯一的)转换(VCC)后获得一个中断
您使用的是 CONSEQ=1和 MSC=1、因此每个 SC 将执行2次转换、总计66ms。 完成中断将在第一次转换后、即在 ADC 真正完成其工作之前的33ms 发生。 第二个完成后、您将听不到任何内容。
----------------------------------------------------
> a.检查 ADC 是否繁忙
您是如何做到这一点的?
----------------------------------------------------
> ADC12CTL0 &&~μ A (ADC12ON | ADC12SC)//关闭 ADC 并清除触发器
当 ADC 仍在运行时、几乎肯定会执行此操作。 由于未设置 ADC12ENC=0、ADC 将继续运行。 (此外、我很确定当 ADC12ENC=1时、你不能设置 ADC12ON=0。)
----------------------------------------------------
我怀疑是由于过早中断、您在 ADC 完成之前发出另一个 SC。 您的50ms 延迟允许(第二次)转换完成。 我建议:
1) 1)使用 ADC12IE1而不是 ADC12IE0、这样您就可以得到整个序列。
2) 2)从您的描述中、您需要 SHT0=3、而不是=15
你好 Bruce。 感谢您指出 S&H 的时间以及您的建议。 我尝试了您的建议、触发了最终转换(ADC12IE1)、但这对我不起作用。 在代码中、转换内存0和1不会与上面我的大纲中显示的内容同时被读取。
为了确保读数之间的时间差足够、我在读取第二个转换寄存器(ADC12MCTL1)之前添加了一个与第一个转换完成中断(ADC12IE0)和第二个转换(ADC12MCTL1)之间的 S&H 时间(33msec)相对应的延迟。 我发现我仍然无法获得另一个转换序列发生。 但是、如果我将此时间加倍(66msec)、我可以触发另一个转换、我会遇到转换错误。 这让我相信、由于 ADC 硬件本身的时序问题、我仍然错过了每一次其他转换。
我还尝试按照您的建议将采样保持时间缩短至1ms、并仍然观察到相同的行为。 按照勘误表中的建议通过(ADC12ENC = 0和 ADC12ON = 0)禁用 ADC 似乎没有帮助。
要回答您关于 ADCBUSY 的问题、我在开始另一个转换之前先检查以下行以使其完成:
IF (ADCCTL1和 ADCBUSY){
//设置诊断标记
返回;
}
您是否知道在第一个转换中断发生后、读取第一个转换结果寄存器需要多少个时钟周期? 我意识到,在任何情况下,由于时钟等原因,添加延迟都可能有容差,但应该有一些余量,这是我希望得到答案的部分:)
谢谢。
> 触发最终转换(ADC12IE1)、但这对我不起作用。
它以什么方式不起作用?
> 在代码中、不会同时读取转换内存0和1
当它们被读取时、并不像它们总是被一起转换那样重要。
>您是否知道在第一次转换中断发生后、从第一个转换结果寄存器读取时需要多少个时钟周期?
我不确定我是否理解这个问题。 UG (SLAU208Q)图28-8表示需要1个 ADC 时钟来存储 MEM 寄存器并设置 IFG。 MEM 寄存器的内容随后可供 CPU 使用(无延迟)。
我想我仍然担心上面的代码会在 ADC 运行时例行关闭 ADCSC。 我从未(有意)明确地关闭 ADCSC、因此我不知道它会持续多长时间、但这样做实际上是不必要的。 如果您不这么做、会发生什么情况?
你好、Anthony
我已经创建了一个项目、可以在 GPIO 和片上温度传感器上获取模拟信号。 我已经在 msp430f5438a 上对其进行了测试。 您可以使用硬件进行更改、只要模拟输入 GPIO 就足够了。 能否帮助我查看此代码是否有任何问题?e2e.ti.com/.../msp430x54xA_5F00_adc12_5F00_09.c
你好、Anthony
我想我们已经找到了这个问题的根本原因:
在 用户指南 的740页 中,当 ADC 用于 通道序列模式时 ,“ADC12SC 必须在每个序列后由软件清除以触发另一个序列。” 通常情况下 、ADC12SC 会自动复位、但对于某些器件、它无法复位。 因此、我们建议通过软件清除该位。 您可以在坏器件的 ADC 转换 ISR 中设置一个试验点、以查看 ADC12SC 是否自动复位以验证它。
此致
Gary
您好、Gary、
我们的示例代码似乎不包含您的建议。 您能否验证这个修改后的示例代码以便 Anthony 能够在他的电路板上进行测试? 我添加了第155行。 第156行用于测试。
e2e.ti.com/.../msp430x54xA_5F00_adc12_5F00_09_5F00_modified.c