In any embedded system, data communication between different modules or external peripherals plays a key role. The ATmega16 microcontroller supports various serial communication protocols like SPI (Serial Peripheral Interface) and I2C (Inter-Integrated Circuit), which help exchange data efficiently between devices. These protocols are widely used in embedded projects involving real-time data exchange such as connecting sensors, memory chips, display modules, or even other microcontrollers. In this article, we will study the practical implementation of SPI and I2C in ATmega16 using C language. We will see how to initialize these modules, transmit and receive data, and understand the internal registers involved. Each section includes example programs that demonstrate how data transfer takes place between master and slave devices using these protocols.
SPI Communication with ATmega16
SPI is a fast, full-duplex, synchronous communication protocol that uses four main signals: MOSI, MISO, SCK, and SS. One device acts as the master that controls the clock, and other devices act as slaves. It is ideal for short-distance, high-speed communication between microcontrollers and devices such as ADCs, DACs, and EEPROMs.
Registers Used in SPI
| Register | Description |
|---|---|
| SPCR | SPI Control Register – enables SPI, sets master/slave mode, clock polarity, and phase. |
| SPSR | SPI Status Register – contains status flags like SPIF (SPI Interrupt Flag). |
| SPDR | SPI Data Register – holds data for transmission and reception. |
SPI Master Program (ATmega16)
#include <avr/io.h>
#define F_CPU 8000000UL
#include <util/delay.h>
void SPI_MasterInit(void) {
DDRB = (1<<PB5)|(1<<PB7)|(1<<PB4); // MOSI, SCK, SS as output
DDRB &= ~(1<<PB6); // MISO as input
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0); // Enable SPI, Master mode, Fosc/16
}
void SPI_MasterTransmit(char data) {
SPDR = data; // Load data into buffer
while(!(SPSR & (1<<SPIF))); // Wait for transmission complete
}
int main(void) {
SPI_MasterInit();
while(1) {
SPI_MasterTransmit('A'); // Transmit data
_delay_ms(500);
}
}
SPI Slave Program (ATmega16)
#include <avr/io.h>
void SPI_SlaveInit(void) {
DDRB = (1<<PB6); // MISO as output
SPCR = (1<<SPE); // Enable SPI in slave mode
}
char SPI_SlaveReceive(void) {
while(!(SPSR & (1<<SPIF))); // Wait until data received
return SPDR; // Return received data
}
int main(void) {
char data;
SPI_SlaveInit();
while(1) {
data = SPI_SlaveReceive(); // Receive from master
// Further processing or display
}
}
I2C Communication with ATmega16
I2C is a two-wire serial communication protocol that allows multiple devices to share the same bus using SDA (Serial Data) and SCL (Serial Clock) lines. It is a half-duplex, multi-master protocol where every slave is identified by a unique address. This makes it ideal for applications where several sensors or ICs need to communicate using just two wires.
Registers Used in I2C (TWI)
| Register | Description |
|---|---|
| TWBR | Bit Rate Register – sets the I2C clock frequency. |
| TWCR | Control Register – manages start, stop, ACK, and enable bits. |
| TWSR | Status Register – holds status flags for various I2C operations. |
| TWDR | Data Register – stores the data to transmit or receive. |
| TWAR | Address Register – holds slave address in slave mode. |
I2C Master Program for Data Transmission
#include <avr/io.h>
#define F_CPU 8000000UL
#include <util/delay.h>
void I2C_Init(void) {
TWSR = 0x00;
TWBR = 0x47; // Set bit rate for 100kHz SCL
}
void I2C_Start(void) {
TWCR = (1<<TWSTA)|(1<<TWEN)|(1<<TWINT);
while (!(TWCR & (1<<TWINT)));
}
void I2C_Stop(void) {
TWCR = (1<<TWSTO)|(1<<TWEN)|(1<<TWINT);
}
void I2C_Write(unsigned char data) {
TWDR = data;
TWCR = (1<<TWEN)|(1<<TWINT);
while (!(TWCR & (1<<TWINT)));
}
int main(void) {
I2C_Init();
while(1) {
I2C_Start();
I2C_Write(0xA0); // Slave address + write bit
I2C_Write(0x55); // Data byte
I2C_Stop();
_delay_ms(1000);
}
}
Conclusion
This article covered the implementation of SPI and I2C data transmission and reception using ATmega16 in C. These protocols are the backbone of most embedded communication systems. Understanding how to initialize, configure, and use these communication modules gives students the ability to build projects that connect multiple devices seamlessly. Mastery of SPI and I2C programming helps in designing reliable, efficient embedded systems for real-world applications.
Comments
Post a Comment
Subscribe to Post Comments [Atom]