0,0 → 1,237 |
/************************************************************************************************************************************** |
* File: I2Cmaster.c |
* |
* Purpose: controlling I2C |
* |
* Functions: int main(void) |
* |
* hardware: AVR-Ctrl experimental board without LCD display as I2C bus is used |
* |
* Created: Jan 2013 |
* |
* Version: 1.00 experimental version |
* |
* Copyright: (c)2013 dk9nw -at- darc.de |
* All rights reserved. This software is available only for non-commercial amateur radio or educational applications. |
* Other uses are prohibited. This software may be modified only if |
* the resulting code be made available publicly and the original author(s) given credit. |
* |
******************************************************************************************************************************************/ |
#include "I2Cmaster.h" |
|
unsigned char twi_state = 0; |
volatile unsigned char Motor[4]; // turn rate of the connected electrical motor 0 - 255 |
|
|
// ************************************************************************************************************************** |
// initialize the I2C Bus (TWI) |
// |
void i2c_init(void) |
{ |
static unsigned char sreg; |
sreg = SREG; // save backup status register , to be reseted later |
cli(); // switch off I-Bit Global Interrupt |
|
//-------------------------------------------------------------------------------------------------------------------- |
// TWSR = TWI Status Register containing: TWS7 TWS6 TWS5 TWS4 TWS3 TWPS1 TWPS0 |
// ------------------------- |
// TWPS: TWI Prescaler Bits |
// |
TWSR &= ~((1<<TWPS1)|(1<<TWPS0)); // TWI Status Register Bits 1..0 TWPS: TWI Prescaler Bits 00=1:1 01=1:4 10=1:16 11=1:64 |
|
//-------------------------------------------------------------------------------------------------------------------- |
// TWBR = TWI Bit Rate Register containing: TWBR7 TWBR6 TWBR5 TWBR4 TWBR3 TWBR2 TWBR1 TWBR0 |
// set TWI Bit Rate Register // SCL_frequency = ( CPU_Clock_frequency / ( 16 + 2 * TWBR ) * 4**TWPS ) |
// // |
TWBR = ((SYSCLK/SCL_CLOCK)-16)/2; // TWI Bit Rate (formula is only valid if TWSR=0) |
|
twi_state = 0; |
|
i2c_start(); |
|
SREG = sreg; // write back to old state, |
sei(); // Interrupt is activated again |
} |
// ************************************************************************************************************************** |
|
|
|
// ************************************************************************************************************************** |
// reset I2C Bus |
// |
void i2c_reset(void) |
{ |
i2c_stop(); // stop i2c Bus |
twi_state = 0; |
TWCR = (1<<TWINT); // reset to original state incl. interrupt flag reset |
TWAR = 0; |
TWDR = 0; |
TWSR = 0; |
TWBR = 0; |
i2c_init(); // initialize the I2C Bus (TWI) |
i2c_start(); |
i2c_write_byte(0); |
} |
// ************************************************************************************************************************** |
|
|
|
// ************************************************************************************************************************** |
// start of I2C Bus |
// |
void i2c_start(void) |
{ |
// TWCR = TWI Control Register -> TWINT TWEA TWSTA TWSTO TWWC TWEN TWIE |
// -------------------------------------------------------------------- |
// TWINT = TWI interrupt flag - to be set to one, to reset the TWINT Flag . |
// TWSTA = TWI start and should be set to one, that TWI is started as Master. |
// TWEN = TWI enable -> now TWI/I2C is working properly. |
// TWIE = TWI Interrupt enable is the TWIE Bit -> should be set |
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE); |
|
//while( !(TWCR & (1<<TWINT) ) ); // wait, that TWINT is zero again, that means that the start conditions have been transferred |
} |
// ************************************************************************************************************************** |
|
|
|
// ************************************************************************************************************************** |
// stop the I2C Bus |
// |
void i2c_stop(void) |
{ |
// TWCR = TWI Control Register -> TWINT TWEA TWSTA TWSTO TWWC TWEN TWIE |
// -------------------------------------------------------------------- |
// TWINT = TWI interrupt flag - to be set to one, to reset the TWINT Flag . |
// TWSTO TWI STOP Condition Bit (TWSTO = 1) -> now will be stoped |
// TWEN = TWI enable -> now TWI/I2C is working properly. |
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN); |
} |
// ************************************************************************************************************************** |
|
|
|
|
// ************************************************************************************************************************** |
// Write to I2C |
// |
void i2c_write_byte(unsigned char byte) |
{ |
//TWSR = 0x00; // TWI Status Register |
|
TWDR = byte; // move byte to send into TWI Data Register |
|
// TWCR = TWI Control Register -> TWINT TWEA TWSTA TWSTO TWWC TWEN TWIE |
// -------------------------------------------------------------------- |
// TWINT = TWI interrupt flag - to be set to one, to reset the TWINT Flag . |
// TWEN = TWI enable -> now TWI/I2C is working properly. |
// TWIE = TWI Interrupt enable is the TWIE Bit -> should be set |
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE); |
} |
// ************************************************************************************************************************** |
|
|
|
// ************************************************************************************************************************** |
// Receive byte and send ACK |
// |
void I2C_ReceiveByte(void) |
{ |
// TWCR = TWI Control Register -> TWINT TWEA TWSTA TWSTO TWWC TWEN TWIE |
// --------------------------------------------------------------------------- |
// TWINT = TWI interrupt flag - to be set to one, to reset the TWINT Flag . |
// TWEA = TWI Acknowledge Bit (TWEA = 1) |
// TWEN = TWI enable -> now TWI/I2C is working properly. |
// TWIE = TWI Interrupt enable is the TWIE Bit -> should be set |
// |
TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE) ; |
} |
// ************************************************************************************************************************** |
|
|
|
// ************************************************************************************************************************** |
// I2C receive last byte and send no ACK |
// |
void I2C_ReceiveLastByte(void) |
{ |
// TWCR = TWI Control Register -> TWINT TWEA TWSTA TWSTO TWWC TWEN TWIE |
// --------------------------------------------------------------------------- |
// TWINT = TWI interrupt flag - to be set to one, to reset the TWINT Flag . |
// TWEN = TWI enable -> now TWI/I2C is working properly. |
// TWIE = TWI Interrupt enable is the TWIE Bit -> should be set |
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE); |
} |
// ************************************************************************************************************************** |
|
|
|
// ************************************************************************************************************************** |
// Interrupt I2C |
//--------------------------------------------------------------------------------------------------------------------------- |
ISR(TWI_vect) |
{ |
switch(twi_state++) |
{ |
//------------------------------------------------------------------------------------------------------------------- |
// write Motor-Data to BL-Ctrl |
//------------------------------------------------------------------------------------------------------------------- |
case 0: |
i2c_write_byte(0x52); |
break; |
|
case 1: |
i2c_write_byte(Motor[0]); |
break; |
|
case 2: |
i2c_stop(); |
i2c_start(); |
break; |
|
case 3: |
i2c_write_byte(0x54); |
break; |
|
case 4: |
i2c_write_byte(Motor[1]); |
break; |
|
case 5: |
i2c_stop(); |
i2c_start(); |
break; |
|
case 6: |
i2c_write_byte(0x56); |
break; |
|
case 7: |
i2c_write_byte(Motor[2]); |
break; |
|
case 8: |
i2c_stop(); |
i2c_start(); |
break; |
|
case 9: |
i2c_write_byte(0x58); |
break; |
|
case 10: |
i2c_write_byte(Motor[3]); |
break; |
|
case 11: |
i2c_stop(); |
twi_state = 0; |
i2c_start(); |
break; |
|
default: |
twi_state = 0; |
break; |
} |
} |
// EOF ISR(TWI_vect) ***************************************************************************************************** |