I want to program the ADC module of arduino Mega2560 using Assembly language (for simulation and learning), I can initialise the ADC Module using Assembly and my program converts in the first iteration, but since the ATmega2560 has an exteded I/O registers, I did not find a way to reset the ADC Flag bit (ADIF) once the first conversion is done. If I use the SBI instruction, I got a error message that says: "operand out of range: 122"
#define __SFR_OFFSET 0x00
#include <avr/io.h>
.global init_ADC
.global init_PORT
.global read_ADC
;----PORT Initilasation--------
init_PORT:
LDI R23,0xFF;
OUT DDRB,R23 ;Configure PORTB as OUTPUT
OUT DDRC,R23 ;Configure PORTC as OUTPUT
RET
;----Initializing ADC Module----------
init_ADC:
LDI R19,0x00 ;
OUT DDRF,R19 ;Configure ADC0 as INPUT for analog conversion
LDI R16,0x40 ;Load R16 with 0x40
STS ADMUX,R16 ;Configure ADMUX with 5V vref and channel 0 for conversion
LDI R17,0x00
STS ADCSRB,R17 ;Set MUX5=0
LDI R18,0x85
STS ADCSRA,R18 ;Set Enable bit and prescaler to 1:32
RET
read_ADC:
LDI R20,0x40 ;
LDS R21,ADCSRA;
ADD R20,R21;
STS ADCSRA,R20 ;Set ADSC bit to start conversion
RCALL WAIT ;
LDS R21,ADCH;
OUT PORTC,R21
LDS R22,ADCL
OUT PORTB,R22
;==CLEAR FLAG BIT===+
SBI ADCSRA,ADIF ;Set ADC flag bit to clear it
RET
WAIT:
LDS R16,ADCSRA ;Load ADCSRA to R16 register
ANDI R16,0x10;
BREQ WAIT
RET
How could I clear or set any bit of a register that is out of range of these instructions (In my case is the ADCSRA) ?
lds r24,ADCSRA ori r24, (1 << ADIF) sts ADCSRA,r24
in CADCSRA |= (1 << ADIF);
And why do you want to clear this flag? This flag is cleared by hardware. Also, do not forget that ADIF is not equal to 0x10 but 0x04 instead. This is why I usedori r24,(1 << ADIF)
whit is equivalent toori r24,0x10
\$\endgroup\$ldi r16,ADIF
will load 4 to r16. \$\endgroup\$