英文:
ATtiny402 ADC value comming not properly
问题
在ATtiny402上,当输入电压达到+2.5V时,ADC值不会增加。它会卡在对应+2.5V时的最大ADC值上,即使我调整可变电阻以超过2.5V也没有变化。以下是代码部分:
#include <avr/io.h>
#include <util/delay.h>
uint16_t volatile adcVal;
void ADC0_init(void);
uint16_t ADC0_read(void);
void ADC0_init(void) {
/* 禁用数字输入缓冲区 */
PORTA.PIN6CTRL &= ~PORT_ISC_gm;
PORTA.PIN6CTRL |= PORT_ISC_INPUT_DISABLE_gc;
/* 禁用上拉电阻 */
PORTA.PIN6CTRL &= ~PORT_PULLUPEN_bm;
ADC0.CTRLB = VREF_ADC0REFEN_bm;
VREF.CTRLA = VREF_ADC0REFSEL_1_bm;
ADC0.CTRLC |= ADC_PRESC_DIV4_gc /* CLK_PER除以4 */
| ADC_REFSEL_INTREF_gc; /* 内部参考电压 */
ADC0.CTRLA |= ADC_ENABLE_bm /* 启用ADC */
| ADC_RESSEL_10BIT_gc; /* 10位模式 */
/* 选择ADC通道 */
ADC0.MUXPOS = ADC_MUXPOS_AIN6_gc;
}
uint16_t ADC0_read(void) {
/* 启动ADC转换 */
ADC0.COMMAND = ADC_STCONV_bm;
/* 等待直到ADC转换完成 */
while ( !(ADC0.INTFLAGS & ADC_RESRDY_bm) )
{
;
}
/* 通过写入1来清除中断标志: */
ADC0.INTFLAGS = ADC_RESRDY_bm;
return ADC0.RES;
}
请注意,这是提供的代码的翻译部分,不包括问题本身。如果您有任何其他需要翻译的内容,请继续提供。
英文:
In ATtiny402 There is no increment ADC value when its came on +2.5v. Its stuck on that max adc value of when it reaches the corresponding +2.5v....there is no change even i adjust the trimpot above 2.5v. And here is code.
#include <avr/io.h> #include <util/delay.h> uint16_t volatile adcVal;
void ADC0_init(void); uint16_t ADC0_read(void);
void ADC0_init(void) { /* Disable digital input buffer */ PORTA.PIN6CTRL &= ~PORT_ISC_gm; PORTA.PIN6CTRL |= PORT_ISC_INPUT_DISABLE_gc;
/* Disable pull-up resistor */
PORTA.PIN6CTRL &= ~PORT_PULLUPEN_bm;
ADC0.CTRLB = VREF_ADC0REFEN_bm ;
VREF.CTRLA = VREF_ADC0REFSEL_1_bm;
ADC0.CTRLC |= ADC_PRESC_DIV4_gc /* CLK_PER divided by 4 */
| ADC_REFSEL_INTREF_gc; /* Internal reference */
ADC0.CTRLA |= ADC_ENABLE_bm /* ADC Enable: enabled */
| ADC_RESSEL_10BIT_gc; /* 10-bit mode */
/* Select ADC channel */
ADC0.MUXPOS = ADC_MUXPOS_AIN6_gc;
}
uint16_t ADC0_read(void) { /* Start ADC conversion */ ADC0.COMMAND = ADC_STCONV_bm;
/* Wait until ADC conversion done */
while ( !(ADC0.INTFLAGS & ADC_RESRDY_bm) )
{
;
}
/* Clear the interrupt flag by writing 1: */
ADC0.INTFLAGS = ADC_RESRDY_bm;
return ADC0.RES;
}
答案1
得分: 1
这段代码的翻译如下:
这段代码将设置 ADC0REFSEL_1 位并启用 2.5V 参考电压。
VREF.CTRLA = VREF_ADC0REFSEL_1_bm;
ADC 无法测量高于参考电压的电压。
尝试不同的数值或在 `ADC0.CTRLC` 上启用 VDD 作为参考。
英文:
This writes a mask with bit ADC0REFSEL_1 set and enables 2.5V reference voltage.
VREF.CTRLA = VREF_ADC0REFSEL_1_bm;
ADC can't measure voltages above the reference.
Try different value or enable VDD as a reference on ADC0.CTRLC
答案2
得分: 0
关于评论中的第二个问题。
没有这个(ADC0.RES >> 2)我得到了一个十进制值4092...为什么只有在2位移位之后才有效
答案太长,无法放入评论中。您在此处犯了一个错误,使用了ADC0.CTRLB
而不是VREF.CTRLB
ADC0.CTRLB = VREF_ADC0REFEN_bm;
因此,VREF_ADC0REFEN_bm
等于2
被写入SAMPNUM
ADC控制字段,并启用了ACC4
模式。这意味着在每次ADC转换请求时,它会自行进行4次转换,并将结果求和放入ADC结果寄存器。因此,您应该将结果除以4才能得到您期望的值。
VREF仍然起作用,因为在缺失的行
VREF.CTRLB = VREF_ADC0REFEN_bm;
中,只是设置了ADC0REF输出的永久启用。没有这行代码,输出会在ADC请求时自动启用,但这需要更多的设置时间。
英文:
Regarding the second question in the comment.
> I got a decimal value 4092 without this (ADC0.RES >> 2) … and why is that working in only after 2 bit shifting
The answer is to long to put it into a comment.
You have a mistake here using ADC0.CTRLB
instead of VREF.CTRLB
ADC0.CTRLB = VREF_ADC0REFEN_bm;
So VREF_ADC0REFEN_bm
which equal 2
is written into SAMPNUM
ADC control field and ACC4
mode is enabled. This means at every ADC conversion request it makes four conversions by itself and places the sum into ADC result register. So you should divide the result by 4 to have what you expected.
VREF works anyway because (absent) line
VREF.CTRLB = VREF_ADC0REFEN_bm;
just sets permanent enabling of ADC0REF output. Without this code line the output is enabled automatically by ADC request which requires more setup time though.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论