Created
May 16, 2019 12:33
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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