67.6k views
2 votes
In an ATmega4809 application, an internal VREF Voltage of 4.3V has been set as the Analogto-Digital Converter (ADC) reference voltage, so this is the full-scale voltage, Vfs. Answer the following questions, assuming a 10-bit ADC: (i) What is the resolution of the ADC in this configuration? (This is the input voltage that will change the ADC Result by 1-bit). (ii) If the input voltage applied to the ADC is 3.01V, what result would you expect to read from the ADC0.RES register, which holds the conversion result? (iii) If the ADC result register has the data 0x1c8 (456), what voltage was applied at the ADC input pin?

code is in c
code below>
/*
* Lab3.c
*
* Created: 20/07/2022 16:51:28
* Author : Ciaran.MacNamee
*/
#include
#include
#include
#define F_CPU 20.0E6
#include
/* Use a struct to make the association between PORTs and bits connected to the LED array more explicit */
struct LED_BITS
{
PORT_t *LED_PORT;
uint8_t bit_mapping;
};
struct LED_BITS LED_Array[10] = {
{&PORTC, PIN5_bm}, {&PORTC, PIN4_bm}, {&PORTA, PIN0_bm}, {&PORTF, PIN5_bm}, {&PORTC, PIN6_bm}, {&PORTB, PIN2_bm}, {&PORTF, PIN4_bm}, {&PORTA, PIN1_bm}, {&PORTA, PIN2_bm}, {&PORTA, PIN3_bm}
};
void CLOCK_init (void);
void InitialiseLED_PORT_bits(void);
void InitialiseButton_PORT_bits(void);
void Set_Clear_Ports(uint8_t set);
void Toggle_Ports(void);
void RTC_init(void);
void CLOCK_init (void)
{
/* Disable CLK_PER Prescaler */
ccp_write_io( (void *) &CLKCTRL.MCLKCTRLB , (0 << CLKCTRL_PEN_bp));
/* If set from the fuses during device programming, the CPU will now run at 20MHz (default is /6) */
}
void RTC_init()
{
uint8_t temp1;
/* Initialize 32.768kHz Oscillator: */
/* Enable 32k ULP oscillator: */
temp1 = CLKCTRL.OSC32KCTRLA;
temp1 |= CLKCTRL_RUNSTDBY_bm;
/* Writing to protected register */
ccp_write_io((void*)&CLKCTRL.OSC32KCTRLA, temp1);
while(CLKCTRL.MCLKSTATUS & CLKCTRL_OSC32KS_bm)
{
; /* Wait until OSC32KS becomes 0 */
}
/* Initialize RTC: */
while (RTC.STATUS > 0)
{
; /* Wait for all register to be synchronized */
}
/* 32.768kHz Internal Oscillator (XOSC32K) */
RTC.CLKSEL = RTC_CLKSEL_INT32K_gc;
/* Run in debug: enabled */
RTC.DBGCTRL = RTC_DBGRUN_bm;
RTC.PITINTCTRL = RTC_PI_bm; /* Periodic Interrupt: enabled */
RTC.PITCTRLA = RTC_PERIOD_CYC8192_gc | RTC_PITEN_bm; /* RTC Clock Cycles 8192, Enable: enabled */
}
void InitialiseLED_PORT_bits()
(1<<5)
void InitialiseButton_PORT_bits(void)
{
PORTE.DIRCLR = PIN1_bm; /* PORTE bit 1 is an input */
PORTE.PIN1CTRL = PORT_PULLUPEN_bm; /* Enable Pull up resistors on PORTE pins 1 & 2 */
}
/* Function to set or clear all LED port bits, 1 - set, 0 - clear */
void Set_Clear_Ports(uint8_t set) {
uint8_t i;
for (i = 0; i <= 9; i += 1)
{
if (set)
LED_Array[i].LED_PORT->OUTSET = LED_Array[i].bit_mapping;
else
LED_Array[i].LED_PORT->OUTCLR = LED_Array[i].bit_mapping;
}
}
void Toggle_Ports(void)
{
uint8_t i;

for (i = 0; i <= 9; i += 1)
{
LED_Array[i].LED_PORT->OUTTGL = LED_Array[i].bit_mapping;
}
}
int main(void)
{
CLOCK_init();
/* set UNO D0-D7 to all outputs, also LED8 and LED9 */
InitialiseLED_PORT_bits();
/* Initialise Push Button bits and pull up resistors */
InitialiseButton_PORT_bits();
Set_Clear_Ports(0);
RTC_init();
sei();
while (1)
{
}
}
ISR(RTC_PIT_vect)
{
static uint8_t PIT_count;
/* Clear flag by writing '1': */
RTC.PITINTFLAGS = RTC_PI_bm;
if (++PIT_count > 0)
{
PIT_count = 0;
Toggle_Ports();
}

}

1 Answer

4 votes

Final answer:

In an ATmega4809 application with a 10-bit ADC and a 4.3V reference voltage, the resolution is 4.2 mV, and for a 3.01V input, the ADC0.RES register should read approximately 717 (0x2CD). A reading of 0x1c8 (456) corresponds to an input voltage of around 1.915V.

Step-by-step explanation:

Regarding the ATmega4809 application with a 10-bit ADC where the full-scale voltage (Vfs) is 4.3V, the questions can be addressed as follows:

  1. The resolution of the ADC is calculated by dividing the full-scale voltage by the maximum ADC value (2^10 for a 10-bit ADC, which is 1024 steps), resulting in 4.3V / 1024 or approximately 4.2 mV per step. This is the smallest change in input voltage that the ADC can detect.
  2. For an input voltage of 3.01V, the expected ADC result can be determined by dividing the input voltage by the resolution. This results in 3.01V / 4.2mV which equals approximately 717. Therefore, the ADC0.RES register should hold a value close to 717 (0x2CD).
  3. If the ADC result register shows 0x1c8 (456), to find the voltage that was applied at the ADC input, multiply the resolution by the ADC result. Doing so gives 456 * 4.2mV, which is approximately 1.915V.

This analysis shows how the ADC converts the analog input voltage to a digital value that can be read from a register and understanding this concept is essential for designing and troubleshooting microcontroller-based applications.

User Arimbun
by
8.7k points