I am using an ATtiny402 for an experiment in ADC. In my current configuration, I am using the PA6 pin as the output pin and the PA2 pin as the analog input pin. In PA2 a potentiometer is connected. In the current experiment if the analog input value is greater than or equal to a threshold value the LED will blink, and if the value is less than the threshold value the LED will be off.
In the current program the ADC0.RES is always returning 0xFFC0 if I monitor the register by the debugger. I have checked the PA2 pin by an oscilloscope, and the input signal is not always HIGH(+5V) if I rotate the potentiometer. But the LED is always blinking even if I set the analog input voltage to 0V, and it is kind of strange.
Am I missing something or what is the bug in my code?
#define F_CPU 20000000UL // CLK frequency is configured to 20 MHz by protected write
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
FUSES = {
.WDTCFG = 0x00, // WDTCFG {PERIOD=OFF, WINDOW=OFF}
.BODCFG = 0x00, // BODCFG {SLEEP=DIS, ACTIVE=DIS, SAMPFREQ=1KHz, LVL=BODLEVEL0}
.OSCCFG = 0x02, // OSCCFG {FREQSEL=20MHZ, OSCLOCK=CLEAR}
.TCD0CFG = 0x00, // TCD0CFG {CMPA=CLEAR, CMPB=CLEAR, CMPC=CLEAR, CMPD=CLEAR, CMPAEN=CLEAR, CMPBEN=CLEAR, CMPCEN=CLEAR, CMPDEN=CLEAR}
.SYSCFG0 = 0xC4, // SYSCFG0 {EESAVE=CLEAR, RSTPINCFG=UPDI, CRCSRC=NOCRC}
.SYSCFG1 = 0x07, // SYSCFG1 {SUT=64MS}
.APPEND = 0x00, // APPEND {APPEND=User range: 0x0 - 0xFF}
.BOOTEND = 0x00, // BOOTEND {BOOTEND=User range: 0x0 - 0xFF}
};
LOCKBITS = 0xC5; // {LB=NOLOCK}
#define LED_ON PORTA.OUT |= (1<<PIN6) ; //PA6 output 1
#define LED_OFF PORTA.OUT &= ~(1<<PIN6) ; //PA6 ouptut 0
#define LED_TOGGLE PORTA.OUTTGL |= (1<<PIN6) ; //toggle PA6 pin
uint16_t adcVal = 0 ;
uint16_t thresholdVal = 0xFFC0 ;
void clock_conf(){
_PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, !CLKCTRL_PEN_bm); // prescaler disabled
_PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSC20M_gc); //20MHz clock
}
void io_config(){
PORTA.DIR = 0b01000000 ; //PA6 output pin
PORTA.PIN2CTRL = 0b0000100 ; //PA2 digital input buffer and pull-up is disabled
}
void adc_init(){
ADC0.CTRLA = ADC_FREERUN_bm; //Set ADC to free running Mode
ADC0.CTRLA |= ADC_ENABLE_bm ; //enable ADC
ADC0.CTRLB = ADC_SAMPNUM_ACC64_gc; //SET the ADC to sum 64 samples
ADC0.CTRLC = ADC_SAMPCAP_bm | ADC_REFSEL1_bm; //Select VDD as the reference
ADC0.CTRLD = ADC_INITDLY_DLY256_gc; //Set the init delay before first sample
ADC0.MUXPOS = ADC_MUXPOS_AIN2_gc; //SET PA2 as the input for the ADC
ADC0.INTCTRL = ADC_RESRDY_bm; //enable the result ready interrupt
ADC0.COMMAND = ADC_STCONV_bm; // Start the conversion
}
ISR(ADC0_RESRDY_vect){
adcVal = ADC0.RES ;
}
int main(void) {
io_config() ;
clock_conf() ;
adc_init() ;
sei() ;
while (1) {
if(adcVal >= thresholdVal){
LED_ON ;
_delay_ms(500 ) ;
LED_OFF ;
_delay_ms(500) ;
}
if(adcVal < thresholdVal) {
LED_OFF ;
}
}
}