https:
eclass.yorku.ca/pluginfile.php/4326585/mod_resource/content/1/LabG_AVR_AssemblerIO_Student_EECS2021_F2022
EECS 2021 – Lab G: Analogue Values in C & Assembler Student Version F2022
You do not have permission to share or distribute this document outside of York University.
EECS 2021 – Lab G: Analogue Values in C & Assembler
Dr. James Andrew Smith, P.Eng.
Background
We are continuing our work on exploring the ATMEGA hardware using both C and Assembler.
References:
• Chapter 13 of the Mazidi, Naimi and Naimi textbook
o You should review the textbook discussion on the ADC and look at suggestions for
changes in Part 1 of this lab document.
o https:
nicerland.com/av
• Chapter 23 of the ATmega328P Datasheet
o https:
ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf
In this lab you are to initialize and run the analogue to digital converter (ADC) on the
ATMEGA328 of your Grove board. The ADC is a slightly complicated component, more than
the general purpose I/O that you’ve used for the LED, for instance.
Marking Guide
You can either demonstrate the individual parts to the TA over Zoom or you can do it as a
ecording submitted in video form to eClass by the Sunday after your lab.
• Part 1a (pot, C): 0.2 points for initializing and running the ADC in C. All or nothing.
• Part 1b (light sensor, C): 0.2 points for initializing and running the ADC in C.. All or
nothing.
• Part 2a (pot, Assembler function). 0.3 points for initializing and running the ADC in
Assembler, called from a C main function XXXXXXXXXXif the ADC is initialized in Assembler, but
other parts of ADC operation are done in C. 0 otherwise.
• Part 2b (light sensor, Assembler function): 0.4 pts. 0.3 points for initializing and running
the ADC in Assembler, called from a C main function XXXXXXXXXXif the ADC is initialized in
Assembler, but other parts of ADC operation are done in C. 0 otherwise.
EECS 2021 – Lab G: Analogue Values in C & Assembler Student Version F2022
You do not have permission to share or distribute this document outside of York University.
Part 1: Read the ADC channel for the Potentiometer & Light Sensor in C
In Chapter 13 of the textbook you can view source code for polling analogue to digital
inputs on the ATMEGA328. Also, refer to the datasheet (https:
it.ly/3U8mKgQ).
Your Grove board has a potentiometer connected to ADC channel A0. As per Table
23-4 in the datasheet, for us to use ADC0 we need the MUX3..0 bits in ADMUX to be
0b0000. We also need for bits 7 and 6 to be 0b01 so that we use the AVCC voltage
eference on the AREF pin of the chip. We’ll keep the result to the “right adjusted”
output, so keep bit 5 (ADLAR) to 0.
Initialize the ADC:
1. Make DDRC equal to 0x00. This allows it to be an input, either digital or
analogue.
2. Make ADMUX 0x40. This sets bit 6 (REFS0) to 1. All other bits in the register
are 0.
a. In the Mazidi, Naimi and Naimi text the authors use a different
(smaller) voltage reference and set the analogue multiplexer to
0xC0. Don’t do that.
3. Make ADCSRA 0x87. This means that bits 7, 4, 2, 1 and 0 are all set to 1.
(You’re setting the ADPS2..1 bits to 1 for prescaling to 128. You’re setting
the enable bit, ADEN, to one to enable the ADC. And you’re permitting
single conversion mode (ADSC set to 1).
a. You can also set ADCSRA to 0x97, which sets the prescaling, the ADEN and the ADSC all at once.
Run the ADC :
1. Start the ADC conversion by setting ADSC bit to 1.
a. ADCSRA |= (1
ADSC);
this only makes the ADSC bit 1. Leaves other alone.
2. Loop until the conversion is finished by checking the ADIF bit in ADCSRA
a. While((ADCSRA & (1
ADIF))==0);
Loop until ADIF bit is 1.
3. Break on a asm(“nop”);
4. Manually read the value in the ADC register using the MPLAB X memory view.
Demo 1a. Demonstrate to the TA that if you turn the potentiometer in a particular
way you get specific values out:
• Completely counter-clockwise: ADC is 1023 (or within 50 quanta) in
ase 10.
• Competely clockwise: ADC is 0 (or within 50 quanta) in base 10.
Next, modify the MUX3..0 bits in ADMUX to be equal to 6 (in binary). This
now connects you to the A6 channel on the ATMEGA328. On the Grove board
this connects to the light sensor.
Demo 1b. Demonstration to the TA that the ADC value will change with the
amount of light that you shine on it:
• Cover the sensor with your hand: ADC is between 0 and 100 in base
10.
• Shine a
ight light at the board: ADC is over 500 in base 10.
#include
int main(void) {
Step 1. Make Port C an input for ADC (all bits)
/* something goes here */
eakpoint here.
Step 2. Select Vref=AVcc & ADC channel
/* something goes here */
Step 3. set prescaler to 128 and enable ADC
/* something goes here */
Step 4. Begin ADC conversion (change ADSC bit to 1)
/* something goes here */
Step 5. Wait until ADC conversion is complete
(it’s a while loop checking ADIF bit)
/* something goes
asm("nop");
asm("nop");
eakpoint here. (report the ADC register value)
return (0);
}
Template for reading the ATMEGA ADC in C.
Figure 1 View the ADC register after changing the
potentiometer or the light sensor.
EECS 2021 – Lab G: Analogue Values in C & Assembler Student Version F2022
You do not have permission to share or distribute this document outside of York University.
Part 2: Read the ADC channel for the Potentiometer & Light Sensor in Assembler
Now, repeat the ADC tasks from Part 1 but, this time, put all the initialization for the ADC, as
well as the sampling of the ADC channel in a stand-alone Assembler function called runADC().
This is to be done in a file called runADC.S and you are to call this Assembler function from a
C main function as you’ve done in previous labs.
Put a
eakpoint inside of the Assembler routine, at a position in the code after the ADC value
has been updated in order to view the value in the ADC register.
Demo 2a. Demonstrate to the TA that if you turn the potentiometer in a particular way, you get
specific values out:
• Completely counter-clockwise: ADC is 1023 (or within 50 quanta) in base 10.
• Competely clockwise: ADC is 0 (or within 50 quanta) in base 10.
Next, modify the MUX3..0 bits in ADMUX to be equal to 6 (in binary). This now connects you
to the A6 channel on the ATMEGA328. On the Grove board this connects to the light sensor.
Demo 2b. Demonstration to the TA that the ADC value will
change with the amount of light that you shine on it:
• Cover the sensor with your hand: ADC is between 0 and
100 in base 10.
• Shine a
ight light at the board: ADC is over 500 in base
10.
Note about partial marks:
In both cases, if you do all of the ADC initialization and collecting of data from the ADC0 or
ADC6 channels within the Assembler code, then you get full marks. If you can only initialize the
ADC but have write the remaining conduct for the looping that checks the ADIF register (for
when the ADC sampling is finished) or any other part of the ADC task in C, then you get half
marks.
Figure 2 Use the memory view to
determine what the value of the ADC is.