Skip to content

Instantly share code, notes, and snippets.

@avr-programmierung
Created May 16, 2019 12:33
Show Gist options
  • Save avr-programmierung/247d8c33b9c0fe7ddeaefbbb3a2eec18 to your computer and use it in GitHub Desktop.
Save avr-programmierung/247d8c33b9c0fe7ddeaefbbb3a2eec18 to your computer and use it in GitHub Desktop.
ATmega88 @ 8MHz Temperaturmessung (5x pro Sekunde) und Ausgabe der Temperatur als Binärwert am PORTD
/*
* LM75_Tempsensor.c
* Temperaturmessung (5x pro Sekunde) und Ausgabe der Temperatur als Binärwert am PORTD
* Eine negative Temperatur wird zusätzlich durch eine LED an PB0 angezeigt
* CPU: ATmega88
* FCPU: 8MHz
* I²C CLK Frequency = 100kHz, CLK = 8000000/(16 + 2*(0x50)*1)
*/
#include <avr/io.h>
#include <util/delay.h>
/*** Statusregister codes and other defines ***/
#define START 0x08 // A START condition has been transmitted
#define R_START 0x10 // A REPEATED START condition has been transmitted
#define SLA_W 0x90 // Slave Address & Write 1001 0000
#define SLA_R 0x91 // Slave Address & Read 1001 0001
#define MT_SLA_ACK 0x18 // Master Transmit SLA+W has been transmitted & ACK has been received
#define MR_SLA_ACK 0x40 // Master Receive SLA + R has been transmitted & ACK has been received
#define MT_DATA_ACK 0x28 // Master Transmit Data byte has been transmitted & ACK has been received
#define MR_DATA_NACK 0x58 // Master Receive Data byte has been transmitted & NACK has been returned
#define BIT_RATE 0x50 // Set value for the bit rate register TWBR
#define POINTER_ADDRESS 0x00 // LM75 pointer address for temperature register
void ERROR(void); // Prototyping of function "ERROR"
/*** Function to send a START Condition ***/
void TWI_START(void)
{
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
// Wait for TWINT Flag set. This indicates that the START condition has been transmitted
while (!(TWCR & (1<<TWINT)));
// Check value of TWI statusregister. Mask prescaler bits. If status different from START go to ERROR if ((TWSR & 0xF8) != START)
ERROR();
}
/*** Function to send the Slave Address with ACK in Master Transmit Mode ***/
void TWI_MT_SLA_ACK(void)
{
// Load SLA_W into TWDR Register
TWDR = SLA_W;
// Clear TWINT bit in TWCR to start transmission of address
TWCR = (1<<TWINT) | (1<<TWEN);
// Wait for TWINT Flag set. This indicates that the SLA+W has been transmitted, and ACK/NACK has been received.
while (!(TWCR & (1<<TWINT)));
// Check value of TWI status register. Mask prescaler bits. If status different from MT_SLA_ACK go to ERROR
if ((TWSR & 0xF8) != MT_SLA_ACK)
ERROR();
}
/*** Function to send 8Bit of data with ACK in Master Transmit Mode **/
void TWI_MT_DATA_ACK(void)
{
// Load DATA into TWDR register
TWDR = POINTER_ADDRESS;
// Clear TWINT bit in TWCR to start transmission of data
TWCR = (1<<TWINT) | (1<<TWEN);
// Wait for TWINT flag set. This indicates that the DATA has been transmitted, and ACK/NACK has been received.
while (!(TWCR & (1<<TWINT)));
// Check value of TWI status register. Mask prescaler bits. If status different from MT_DATA_ACK go to ERROR
if ((TWSR & 0xF8) != MT_DATA_ACK)
ERROR();
}
/*** Function to send a REPEATED START condition **/
void TWI_R_START(void)
{
// Send a START condition
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
// Wait for TWINT Flag set. This indicates that the START condition has been transmitted
while (!(TWCR & (1<<TWINT)));
// Check value of TWI statusregister. Mask prescaler bits. If status different from R_START go to ER-ROR
if ((TWSR & 0xF8) != R_START)
ERROR();
}
/*** Function to send the Slave Address in Master Receive Mode with Acknowledge **/
void TWI_MR_SLA_ACK(void)
{
// Load SLA_R into TWDR Register
TWDR = SLA_R;
// Clear TWINT bit in TWCR to start transmission of address
TWCR = (1<<TWINT) | (1<<TWEN);
// Wait for TWINT Flag set. This indicates that the SLA+W has been transmitted, and ACK/NACK has been received.
while (!(TWCR & (1<<TWINT)));
// Check value of TWI status register. Mask prescaler bits. If status different from MR_SLA_ACK go to ERROR
if ((TWSR & 0xF8) != MR_SLA_ACK)
ERROR();
}
/*** Function to read one Databyte in Master Receive Mode with NACK ***/
uint8_t TWI_READ_DATABYTE_NACK(void)
{
// Read one data byte
TWCR = (1<<TWINT)| (1<<TWEN);
// Wait for TWINT flag set. This indicates that the DATA has been transmitted, and ACK/NACK has been received.
while (!(TWCR & (1<<TWINT)));
// Check value of TWI status register. Mask prescaler bits. If status different from MR_DATA_NACK go to ERROR
if ((TWSR & 0xF8) != MR_DATA_NACK)
ERROR();
return TWDR; // Return the value of data register
}
/*** function to send a STOP condition ***/
void TWI_STOP(void)
{
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // Transmit STOP condition
}
/*** function to show a bus error ***/
void ERROR(void)
{
PORTB |= (1<<PB1); // ERROR LED ON
}
uint8_t LSByte, MSByte;
uint16_t data_16bit, temperature, high_byte, low_byte;
int main(void)
{
DDRD = 0xFF; // PORTD = output
DDRC = 0x3F; // PC0 ... PC5 = output
DDRB = 0x03; // PB0 and PB1 = output
TWBR = BIT_RATE; // Set the TWI clock-frequency in bit rate register
while(1)
{
TWI_START(); // Send START condition
TWI_MT_SLA_ACK(); // Master Transmit Slave Address with ACK
TWI_MT_DATA_ACK(); // Master Transmit Data with ACK
TWI_R_START(); // Send REPEATED START condition
TWI_MR_SLA_ACK(); // Send the Slave Address in Master Receive Mode with ACK
MSByte = TWI_READ_DATABYTE_NACK(); // Read one Databyte without ACK
LSByte = TWI_READ_DATABYTE_NACK(); // Read one Databyte without ACK
TWI_STOP(); // Send STOP condition
low_byte = LSByte >> 5; // Shift LSByte 5 digits right
high_byte = MSByte << 8; // Shift MSByte 8 digits left
data_16bit = high_byte + low_byte; // Store 16bit-result of temp-register in data
temperature = data_16bit >> 8; // Shift data 8 digits right to get a 8bit value
if (MSByte & 0x80) // if bit7 = 1 --> negative Temperature
{
MSByte = ~MSByte + 1; // build 2´s complement
temperature = MSByte >> 3; // divide by 8
PORTD = temperature; // Show negative temperature on PORTD
PORTB |= (1<<PB0); // LED for negative Temperature ON
}
else // if bit7 = 0 --> positive Temperature
{
PORTB &= ~(1<<PB0); // LED for negative Temperature OFF
PORTD = temperature; // Show positive temperature on PORTD
}
_delay_ms(200); // wait 200ms for new readout
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment