WEEK1/2:
question: what is the difference between a single & and a double && ?
The difference between them is that if you add a && that mean do this
AND(&&) but & is a bit operator
Question: Why is the F_CPU needed? and what happens if we change it to
double or half the value?
The F_CPU is the frequency in which the processor of our micro controller
is running is needed for time delays and in general time department
operations .
Question: What is the difference between overflow and output compare
mode ?
Overflow Mode: Counts continuously and resets after reaching its
maximum value, often used for time delays
Output Compare Mode : Compares the count value to a preset target and
triggers actions when they match, making it suitable for precise timing
control.
Question: What is the EICRA register used for ?
Is to activate the pull-up registers
Question: What is an interrupt vector and where are they located ?
interrupt vector is a table of addresses pointing to functions that handle
various interrupt sources. They are stored in the program memory (Flash)
and are set up during the initialization phase. These vectors help the
microcontroller respond to external events .
1
BLINKING ONE LED WITH NO DELAYS AND ONLY WITH AN
INTERRUPT
2
WEEK2 Part Assignment :
This code uses a bit mask of
PIND if that pin mask is ==to
the one happening on our
micro controller that means
the button is pressed and we
need to freeze it or continue
our operation
3
WEEK3:
question: What happens if you switch AREF from 5v to 3.3v?
If we switch to 3.3v our
reference voltage will
be 3.3v and also this
reference voltage will
be used for an analog-
to-digital conversion.
This means that our
range is from 0-3.3v
and anything over that
will be indexed as 3.3v
even if its 5v.The range
from before with the 5v
was 0-1023 and now 0-
675.This reduces the
resolution
CODE:
Sampling rate should
be 2ice the highest
frequency of the
analog signal
Flash ADC
Advandage:
Fast
Disadvadage:
Needs too many parts
as a result to be costly
low resolution
4
large power consumption
Successive approximation ADC:
1.Set most significant bits
2.Convert most significant bits to analog using ADC
3.Compare guess with input
4.Set bit accordingly
5.Test next bit
Asynchronous/synchronous communication
Synchronous: In every bit pulse one bit of data comes in
Asynchronous: We only have receive and transmit lines and no clock. The
bits form the clock signal where we have a start and a stop.
With asynchronous we may miss a bit the trick is to sample more often
than the bit that we send between 8 to 16 times more. We do majority
voting and it acts like a low pass filter
question: How can you set the ADC at a sampling rate of 5 kHz?
We do the calculations :
16000000/(5000*256)=12.5
F_CPU DisireHz*Resolution
We go to our data sheet and choose 16
ADPS2=1 ADPS1=0 ADPS0=0
Download and complete the skeleton UART programme: calculate/look up
baudrate (see datasheet), fill in the correct frame format and check for
correct register fields.
5
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define ADCC 0
#define F_CPU 16000000UL
// Calculate and fill in the correct baud rate for 9600 on 16 MHz
#define baudrate 103 // (16000000 / (16 * BAUD)) - 1
volatile char latestChar = '*';
volatile unsigned char ADCr = 0;
volatile uint8_t ADC_ready = 0;
void init() {
// UART setup
UBRR0 = baudrate;//199
UCSR0C = (0 << UPM01) | (0 << UPM00) | (0 << USBS0) | (1 << UCSZ01) | (1 << UCSZ00);
// 8 data bits, 1 stop bit, no parity page181,183,186,198,197
UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
// ADC setup
ADMUX = (1 << REFS0);
ADCSRA |= (1 << ADEN) | (1 << ADIE) | (1 << ADATE) | (1 << ADSC) | (1 << ADPS2) | (
ADPS1) | (1 << ADPS0);
ADMUX |= (ADCC & 0x0F);
ADMUX |= (1 << ADLAR);
// Pins
DDRB |= 0b00001111; // Set only the first 4 bits as outputs
// Interrupt
sei();
}
void UARTsendchar(unsigned char data) {//page209
while (!(UCSR0A & (1 << UDRE0)))
;
UDR0 = data;
}
//while (!(UCSR0A & (1 << UDRE0))): This is a busy-wait loop that waits until the
//USART Data Register Empty (UDRE0) bit in the USART Control and Status Register A (UCSR0A) is
set.
//This bit indicates that the USART is ready to transmit new data.
//The loop ensures that the function doesn't proceed until it's safe to write new data.
6
question: Explain the added code in your logbook
Now connect four leds and try out this UART example programme with a
terminal programme (for instance Putty or the arduino IDE) on 9600 bauds.
question: Look up an ASCII table, what character do you need send to
"light" all four leds?
We need to send something that has 4 1111 at the last 4 signifigant bits
that means Works o works ? and a lot more
question: Explain how the UDR register "works" so that you can both read
from and write to it.
The UDR (USART Data Register) serves as a storage location for data in
UART communication. It can be read from to obtain received data and
written to for transmitting data. To read from UDR, you check for received
data and access it. For writing, you ensure the UDR is ready (by checking
the UDRE flag) before sending data. The UDR facilitates two-way serial
communication between a microcontroller and external devices.
STEP3:
UPM01 and UPM00 (USART Parity Mode Bits):
These two bits (UPM01 and UPM00) control the parity mode for USART communication.
In this case, both are set to 0, indicating that there is no parity checking (no parity bits are used).
Parity bits are used for error-checking purposes in serial communication.
USBS0 (USART Stop Bit Select):
This bit (USBS0) configures the number of stop bits to be used in the USART frame.
In this case, it is set to 0, indicating one stop bit.
The number of stop bits can be 1 or 2.
UCSZ01 and UCSZ00 (USART Character Size Bits):
These two bits (UCSZ01 and UCSZ00) determine the character size in the USART frame.
In this case, both are set to 1, indicating an 8-bit character size.
The character size can be 5, 6, 7, or 8 bits.
Putting it all together, the line of code is configuring the USART to use 8-bit data frames with no parity and one stop bit. This
configuration is common for many standard serial communication scenarios.
Here's a summary:
Parity: None (UPM01 and UPM00 both set to 0)
Stop Bits: 1 (USBS0 set to 0)
Character Size: 8 bits (UCSZ01 and UCSZ00 both set to 1)
RXEN0 (Receiver Enable 0): This bit, when set (1), enables the USART receiver. It
allows the microcontroller to receive data through the designated RX (Receive) pin.
TXEN0 (Transmitter Enable 0): This bit, when set (1), enables the USART
transmitter. It allows the microcontroller to transmit data through the designated TX
(Transmit) pin.
RXCIE0 (RX Complete Interrupt Enable 0): This bit, when set (1), enables the
USART Receive Complete interrupt. When a complete byte is received and ready to
be read from the receive buffer, this interrupt is triggered. Enabling this interrupt
allows the microcontroller to respond to incoming data asynchronously.
So, the entire line sets the control bits in the UCSR0B register to enable both the
receiver and transmitter of the USART and enable the RX Complete interrupt. This is
a common configuration for USART communication, allowing the microcontroller to
both send and receive data while also being able to respond to incoming data with
an interrupt.
7
REFS0 (Reference Selection Bit 0): This bit is part of the ADMUX (ADC Multiplexer
Selection Register) and, when set to 1 as in your code, selects the voltage reference
for the ADC (Analog-to-Digital Converter). Specifically, setting REFS0 to 1
configures the ADC to use the AVcc (voltage at the AVcc pin) as the reference
voltage.
ADEN (ADC Enable): Setting this bit to 1 enables the ADC.
ADIE (ADC Interrupt Enable): Setting this bit to 1 enables the ADC conversion
complete interrupt.
ADATE (ADC Auto Trigger Enable): Setting this bit to 1 enables auto-triggering of
the ADC by a free-running timer.
ADSC (ADC Start Conversion): Writing a 1 to this bit starts the ADC conversion
when auto-triggering is enabled.
ADPS2, ADPS1, ADPS0 (ADC Prescaler Select Bits): These bits set the ADC clock
prescaler. In your code, (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0) sets a
prescaler of 128. This means the ADC clock will be the system clock divided by 128.
ADCC (ADC Channel Configuration): The lower nibble (4 bits) of ADCC is masked
(& 0x0F) and then ORed with the contents of ADMUX. This sets the ADC channel to
the lower 4 bits of ADCC. The specific channel is determined by the value of ADCC
at runtime.
ADLAR (ADC Left Adjust Result): Setting this bit to 1 left-adjusts the ADC result. In
this configuration, the result is justified so that the 8-bit result is held in the high
register, effectively making it an 8-bit result.
In summary, these lines configure the ADC to use AVcc as the reference voltage,
enable the ADC with interrupt and auto-triggering, set a prescaler of 128, configure
the ADC channel, and left-adjust the result. These settings are typical for configuring
the ADC in AVR microcontrollers
8
CODE:
9
question: What is the difference between half-duplex and full-duplex? How does this
relate to SPI and I2C ?
Answer:
In half duplex data can go both ways but not at the same time.Only one of the tow can
trasmit or recive at the same time.(handheld transceiver).On the other hand full duplex
can transmit and recive at the same time this is done by having a different path of
trasmiting and a different for reciving example is the modern telephone.
HOW ARE THEY RELATED:
SPI is full duplex while I2C can do half duplexbut mostly..Also I2C uses the same bus and
clock lines as such divices take turns reciving and transmiting.While the SPI uses MOSI
and MISO lines to recive and transmit at the same time.
question: Why does I2C need resitors? And why doesn't SPI need resistors? Explain the
difference.
Answer:
Resistors are used in I2C (Inter-Integrated Circuit) communication to pull the bus lines
(SDA and SCL) to specific voltage levels when the bus is not actively being used by any
device. This is important so proper communication and avoiding bus contention. The
specific resistors used are called pull-up resistors.The bus lines that are pulled up are
SDA and SCL.The SPI does need the pull up resistors because uses 2 different line named
MISO and MOSI and also a dedicated clock. As a result the lines are driven by the
receiving and transmiting
1)In I2C, devices are assigned unique addresses for communication, with pull-up
resistors defining bus states; communication starts with a unique address.
2)SPI uses separate chip select (CS/SS) lines for device selection; the master activates
the corresponding line to communicate with a specific slave.
3)I2C relies on shared data and clock lines, while SPI has dedicated lines for data
(MOSI/MISO) and a clock line (SCK).
4)I2C employs start and stop conditions to mark the beginning and end of data transfers.
5)SPI does not use addressing; it leverages physical separation of chip select lines for
device selection.
6)The choice between I2C and SPI depends on application requirements and the number
of connected devices. Top of FormBottom of Form
question: How is decided who the "master" is and who the "slave" in both I2C and SPI?
Explain the difference.
Answer:
In both I2C and SPI communication protocols, the distinction between "master" and
"slave" devices is fundamental to their operation. In I2C, the master device initiates and
controls communication, addressing slave devices using unique identifiers. Slaves
respond to commands or requests from the master. Conversely, in SPI, the master device
also orchestrates communication, but instead of addressing, it selects slave devices
using dedicated chip select (CS) lines. Each slave responds to commands or data from
the master, activated via its CS line. While both protocols employ master-slave
architecture, their mechanisms for addressing and slave selection vary, defining their
unique communication approaches.
question: how is the byte data send in I2C and SPI: MSB or LSB first ? and can this be
changed ?
Answer:
In both I2C and SPI communication protocols, the transmission order of byte data,
whether it's MSB (Most Significant Bit) or LSB (Least Significant Bit) first, is typically
determined by the specific implementation or configuration of the devices involved. In
I2C, the transmission order can vary based on hardware or software design, without a
standardized rule. Conversely, in SPI, the default transmission order is often MSB first,
though LSB first transmission may be supported in some implementations. Generally, the
transmission order can be changed or configured to accommodate the requirements of
the communication system or the preferences of the designer, often through register
settings or software configurations.
10
question: what is the input and output range of the ADC chip ?
The input and output range of an ADC (Analog-to-Digital Converter) chip vary depending
on its specifications and configuration. The input range determines the range of analog
voltages the ADC can accurately convert to digital values, typically specified as 0 to 5
volts or -5 to +5 volts. On the other hand, the output range refers to the digital values
produced by the ADC based on the input voltage. This range is determined by the
number of bits the ADC uses for conversion; for example, an 8-bit ADC will have an
output range of 0 to 255, while a 10-bit ADC will range from 0 to 1023. It's essential to
refer to the datasheet of the specific ADC chip for accurate input and output range
information, as they can vary based on the model and manufacturer, and the input range
may be adjustable through settings or external components like voltage dividers or
amplifiers.
question: how can you read out the chip ?
To read out a chip, start by understanding its datasheet to grasp its pinout, features, and
supported communication protocols. Next, interface the chip with a microcontroller or
computer using appropriate interfaces like SPI, I2C, UART, or GPIO pins. Initialize the
chosen communication protocol, then send commands or data to the chip to request
specific registers, sensor readings, or operations. Receive data from the chip through the
established communication protocol and process it accordingly, such as converting
analog readings to digital values or interpreting sensor data. Implement error handling
mechanisms for communication errors or unexpected responses. Finally, thoroughly test
the chip's functionality and debug any issues encountered during the reading process.
11