/* * This code utilizes the AVR libraries for I2C and UART communication. * Make sure to connect the SDA and SCL pins of the ATmega328P to the * corresponding pins of your I2C temperature sensor. Additionally, you might * need pull-up resistors for the I2C lines. */ #include #include #include #define LED_PIN PB5 // Define the pin connected to the LED #define TEMP_SENSOR_ADDR 0x48 #define TEMP_REG_ADDR 0x00 #define BAUD 9600 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; } 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'); } float readTemperature() { uint16_t temperature; // Send start condition I2C_start(); // Send device address with write operation I2C_write((TEMP_SENSOR_ADDR << 1) | 0); // Send temperature register address I2C_write(0x00); // Repeat start I2C_start(); // Send device address with read operation I2C_write((TEMP_SENSOR_ADDR << 1) | 1); // Read temperature data MSB temperature = (uint16_t)(I2C_read(1)) << 8; // Read temperature data LSB temperature |= I2C_read(0); // Send stop condition I2C_stop(); // Convert raw data to temperature in Celsius return (float)temperature * 0.0625; } int main(void) { initI2C(); initUART(); float temperature; while (1) { temperature = readTemperature(); // Print temperature over UART UART_println("Temperature: "); UART_transmit((uint8_t)(temperature / 10.0) + '0'); UART_transmit((uint8_t)fmod(temperature, 10.0) + '0'); UART_println(" °C"); _delay_ms(1000); // Delay for 1 second } return 0; } void blink() { // Set the LED pin as output DDRB |= (1 << LED_PIN); while (1) { // Turn on the LED by setting the pin high PORTB |= (1 << LED_PIN); // Delay for 500 milliseconds _delay_ms(500); // Turn off the LED by setting the pin low PORTB &= ~(1 << LED_PIN); // Delay for 500 milliseconds _delay_ms(500); } }