Skip to content

Instantly share code, notes, and snippets.

@avr-programmierung
Created May 16, 2019 12:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save avr-programmierung/8f39f2e4209b8a62addff5604bc373cc to your computer and use it in GitHub Desktop.
Save avr-programmierung/8f39f2e4209b8a62addff5604bc373cc to your computer and use it in GitHub Desktop.
ATmega88 @ 8MHz Lichtmessung (alle 200ms) und Ausgabe der Lichtstärke in Lux in der Variablen "lux_value"
/* Light_Sensor_ISL29020.c
* Lichtmessung (alle 200ms) und Ausgabe der Lichtstärke in Lux in der Variablen "lux_value"
* Ein möglicher Übertragungsfehler (ERROR) wird durch eine LED an PB1 angezeigt
* CPU: ATmega88, FCPU = 8MHz
* I²C CLK Frequency = 62,5kHz, --> CLK Frequency = FCPU/(16 + 2*(TWBR)*Prescaler Value)
*/
#include <avr/io.h>
#include <util/delay.h>
#define START 0x08 // A START condition has been transmitted
#define R_START 0x10 // A REPEATED START condition has been transmitted
#define SLA_W 0x88 // Slave Address & Write 1000 1000
#define SLA_R 0x89 // Slave Address & Read 1000 1001
#define MT_SLA_ACK 0x18 // Master Transmit SLA + W 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_SLA_ACK 0x40 // Master Receive SLA + R has been transmitted & ACK has been received
#define MR_SLA_NACK 0x48 // Master Receive SLA + R has been transmitted & ACK has been received
#define MR_DATA_ACK 0x50 // Master Receive Data byte has been transmitted & ACK has been returned
#define MR_DATA_NACK 0x58 // Master Receive Data byte has been transmitted & NACK has been returned
#define BIT_RATE 56 // Set value for the bit rate register TWBR
void ERROR(void); // Prototyping of function "ERROR"
/*** Function to send a START Condition ***/
void TWI_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 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 Slave Address + Write into TWDR Register
TWDR = SLA_W;
// Clear TWINT bit in TWCR to start transmission
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(uint8_t data)
{
// Load DATA into TWDR register
TWDR = data;
// Clear TWINT bit in TWCR to start transmission
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 Slave Address + Read into TWDR Register
TWDR = SLA_R;
// Clear TWINT bit in TWCR to start transmission
TWCR = (1<<TWINT) | (1<<TWEA) | (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 send the Slave Address in Master Receive Mode without Acknowledge **/
void TWI_MR_SLA_NACK(void)
{
// Load Slave Address + Read into TWDR Register
TWDR = SLA_R;
// Clear TWINT bit in TWCR to start transmission
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_NACK go to ERROR
if ((TWSR & 0xF8) != MR_SLA_NACK)
ERROR();
}
/*** Function to read one Databyte in Master Receive Mode and send NACK ***/
uint8_t TWI_READ_DATABYTE_NACK(void)
{
// Clear TWINT bit in TWCR to start transmission with NACK
TWCR = (1<<TWINT) | (1<<TWEN);
// Wait for TWINT flag set. This indicates that the DATA has been received
while (!(TWCR & (1<<TWINT)));
// Check value of TWI status register. Mask prescaler bits. If status different from MR_SLA_NACK go to ERROR
if ((TWSR & 0xF8) != MR_DATA_NACK)
ERROR();
return TWDR; // Return the value of data register
}
/*** Function to read one Databyte in Master Receive Mode and send ACK ***/
uint8_t TWI_READ_DATABYTE_ACK(void)
{
// Clear TWINT bit in TWCR to start transmission with ACK
TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
// Wait for TWINT flag set. This indicates that the DATA 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_DATA_ACK)
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, lux_value, 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
TWI_START(); // Send START condition
TWI_MT_SLA_ACK(); // Master Transmit Slave Address with Acknowledge
TWI_MT_DATA_ACK(0x00); // Transmit 0x00 for Register Command with Acknowledge
TWI_MT_DATA_ACK(0xC3); // Transmit 0xC3 (1100 0011) EN, Mode=1, Range4
TWI_STOP(); // Send STOP condition
_delay_ms(10); // Delaytime between STOP and next START contition
while(1)
{
TWI_START(); // Send START condition
TWI_MT_SLA_ACK(); // Master Transmit Slave Address with ACK
TWI_MT_DATA_ACK(0x01); // Transmit 0x01 to start with Register 0x01 with ACK
TWI_R_START(); // Send REPEATED START condition
TWI_MR_SLA_ACK(); // Send the Slave Address in Master Receive Mode with ACK
/* Read 2 Databytes in Burst Read Sequence */
// Read one Databyte with ACK (tells the receiver more data will be received)
LSByte = TWI_READ_DATABYTE_ACK();
// Read one Databyte with NACK (tells the receiver no further data will be received)
MSByte = TWI_READ_DATABYTE_NACK();
TWI_STOP(); // Send STOP condition
low_byte = LSByte; // Store LSByte in low_byte
high_byte = MSByte << 8; // Shift MSByte 8 digits to left and store in high_byte
lux_value = low_byte + high_byte; // Store 16bit-result in lux_value
_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