From 6b9f51b34195b4eb63a386860f9c46128bded8c7 Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Sat, 23 Mar 2024 21:18:52 +0100 Subject: [PATCH] Splitting code --- i2c.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ i2c.h | 7 +++++++ makefile | 2 +- uart.c | 32 ++++++++++++++++++++++++++++++++ uart.h | 7 +++++++ 5 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 i2c.c create mode 100644 i2c.h create mode 100644 uart.c create mode 100644 uart.h diff --git a/i2c.c b/i2c.c new file mode 100644 index 0000000..c4efba6 --- /dev/null +++ b/i2c.c @@ -0,0 +1,44 @@ +#include +#include +#include "i2c.h" + +void initI2C() { + // Set the prescaler to 1 + TWSR &= ~(1 << TWPS0); + TWSR &= ~(1 << TWPS1); + // Set the bit rate to 100kHz + TWBR = ((F_CPU / 100000) - 16) / 2; +} + +void I2C_start() { + // Send the start condition + TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); + // Wait for the start condition to be sent + while (!(TWCR & (1 << TWINT))) + ; +} + +void I2C_stop() { + // Send the stop condition + TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); + // Wait for the stop condition to be sent + while (TWCR & (1 << TWSTO)); +} + +void I2C_write(uint8_t data) { + // Load the data into the data register + TWDR = data; + // Start transmission of data + TWCR = (1 << TWINT) | (1 << TWEN); + // Wait for the data to be sent + while (!(TWCR & (1 << TWINT))); +} + +uint8_t I2C_read(uint8_t ack) { + // Enable TWI, generate ACK (if ack = 1) and clear TWI interrupt flag + TWCR = (1 << TWINT) | (1 << TWEN) | (ack << TWEA); + // Wait until TWI finish its current job (read operation) + while (!(TWCR & (1 << TWINT))); + // Return received data + return TWDR; +} \ No newline at end of file diff --git a/i2c.h b/i2c.h new file mode 100644 index 0000000..47fa6fe --- /dev/null +++ b/i2c.h @@ -0,0 +1,7 @@ +#pragma once + +void initI2C(); +void I2C_start(); +void I2C_stop(); +void I2C_write(uint8_t data); +uint8_t I2C_read(uint8_t ack); \ No newline at end of file diff --git a/makefile b/makefile index ed9f3ae..536f931 100644 --- a/makefile +++ b/makefile @@ -12,7 +12,7 @@ QEMU_MACHINE_NAME = uno CFLAGS = -std=c2x -Wall -Wno-array-bounds -mmcu=$(MCU) -DF_CPU=16000000UL -O3 # Source files -SRCS = main.c +SRCS = $(wildcard *.c) # Object files OBJS = $(SRCS:.c=.o) diff --git a/uart.c b/uart.c new file mode 100644 index 0000000..7f5f144 --- /dev/null +++ b/uart.c @@ -0,0 +1,32 @@ +#include "uart.h" +#include +#include + +// 9600 seems to be the highest the ATmega328P can handle in this config +#define BAUD 9600 +#include + +void initUART() { + // Set baud rate + UBRR0H = (uint8_t)(F_CPU / (BAUD * 16UL) - 1) >> 8; + UBRR0L = (uint8_t)(F_CPU / (BAUD * 16UL) - 1); + // Enable receiver and transmitter + UCSR0B |= (1 << RXEN0) | (1 << TXEN0); + // Set frame format: 8 data, 1 stop bit + UCSR0C |= (1 << UCSZ01) | (1 << UCSZ00); +} + +void UART_transmit(uint8_t data) { + // Wait for empty transmit buffer + while (!(UCSR0A & (1 << UDRE0))); + // Put data into buffer, sends the data + UDR0 = data; +} + +void UART_println(const char *str) { + // Transmit each character until NULL character is encountered + while (*str) UART_transmit(*str++); + // Transmit carriage return and line feed characters + UART_transmit('\r'); + UART_transmit('\n'); +} diff --git a/uart.h b/uart.h new file mode 100644 index 0000000..0383f49 --- /dev/null +++ b/uart.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +void initUART(); +void UART_transmit(uint8_t data); +void UART_println(const char *str); \ No newline at end of file