1
0
Fork 0

Additions from 03/12/2021: Refactoring to multiple files.

This commit is contained in:
Yohan Boujon 2022-04-05 20:26:58 +02:00
parent f2c5b40d7d
commit 900988633e
11 changed files with 686 additions and 142 deletions

220
i2c_test_attiny85/USI_TWI_Slave.c Executable file
View file

@ -0,0 +1,220 @@
// This file has been prepared for Doxygen automatic documentation generation.
/*! \file ********************************************************************
*
* Atmel Corporation
*
* File : USI_TWI_Slave.c
* Compiler : IAR EWAAVR 4.11A
* Revision : $Revision: 1.14 $
* Date : $Date: Friday, December 09, 2005 17:25:38 UTC $
* Updated by : $Author: jtyssoe $
*
* Support mail : avr@atmel.com
*
* Supported devices : All device with USI module can be used.
*
* AppNote : AVR312 - Using the USI module as a I2C slave
*
* Description : Functions for USI_TWI_receiver and USI_TWI_transmitter.
*
*
****************************************************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
#include "USI_TWI_Slave.h"
/*! Static Variables
*/
static unsigned char TWI_slaveAddress;
static volatile unsigned char USI_TWI_Overflow_State;
/*! Local variables
*/
static uint8_t TWI_RxBuf[TWI_RX_BUFFER_SIZE];
static volatile uint8_t TWI_RxHead;
static volatile uint8_t TWI_RxTail;
static uint8_t TWI_TxBuf[TWI_TX_BUFFER_SIZE];
static volatile uint8_t TWI_TxHead;
static volatile uint8_t TWI_TxTail;
/*! \brief Flushes the TWI buffers
*/
void Flush_TWI_Buffers(void)
{
TWI_RxTail = 0;
TWI_RxHead = 0;
TWI_TxTail = 0;
TWI_TxHead = 0;
}
//********** USI_TWI functions **********//
/*! \brief
* Initialise USI for TWI Slave mode.
*/
void USI_TWI_Slave_Initialise( unsigned char TWI_ownAddress )
{
Flush_TWI_Buffers();
TWI_slaveAddress = TWI_ownAddress;
PORT_USI |= (1<<PORT_USI_SCL); // Set SCL high
PORT_USI |= (1<<PORT_USI_SDA); // Set SDA high
DDR_USI &= ~(1<<PORT_USI_SCL); //modified // Set SCL as input
DDR_USI &= ~(1<<PORT_USI_SDA); // Set SDA as input
USICR = (1<<USISIE)|(0<<USIOIE)| // Enable Start Condition Interrupt. Disable Overflow Interrupt.
(1<<USIWM1)|(0<<USIWM0)| // Set USI in Two-wire mode. No USI Counter overflow prior
// to first Start Condition (potentail failure)
(1<<USICS1)|(0<<USICS0)|(0<<USICLK)| // Shift Register Clock Source = External, positive edge
(0<<USITC);
USISR = 0xF0; // Clear all flags and reset overflow counter
}
/*! \brief Puts data in the transmission buffer, Waits if buffer is full.
*/
void USI_TWI_Transmit_Byte( unsigned char data )
{
unsigned char tmphead;
tmphead = ( TWI_TxHead + 1 ) & TWI_TX_BUFFER_MASK; // Calculate buffer index.
while ( tmphead == TWI_TxTail ); // Wait for free space in buffer.
TWI_TxBuf[tmphead] = data; // Store data in buffer.
TWI_TxHead = tmphead; // Store new index.
}
/*! \brief Returns a byte from the receive buffer. Waits if buffer is empty.
*/
unsigned char USI_TWI_Receive_Byte( void )
{
unsigned char tmptail;
unsigned char tmpRxTail; // Temporary variable to store volatile
tmpRxTail = TWI_RxTail; // Not necessary, but prevents warnings
while ( TWI_RxHead == tmpRxTail );
tmptail = ( TWI_RxTail + 1 ) & TWI_RX_BUFFER_MASK; // Calculate buffer index
TWI_RxTail = tmptail; // Store new index
return TWI_RxBuf[tmptail]; // Return data from the buffer.
}
/*! \brief Check if there is data in the receive buffer.
*/
unsigned char USI_TWI_Data_In_Receive_Buffer( void )
{
unsigned char tmpRxTail; // Temporary variable to store volatile
tmpRxTail = TWI_RxTail; // Not necessary, but prevents warnings
return ( TWI_RxHead != tmpRxTail ); // Return 0 (FALSE) if the receive buffer is empty.
}
/*! \brief Usi start condition ISR
* Detects the USI_TWI Start Condition and intialises the USI
* for reception of the "TWI Address" packet.
*/
ISR(USI_START_VECTOR)
{
unsigned char tmpUSISR; // Temporary variable to store volatile
tmpUSISR = USISR; // Not necessary, but prevents warnings
// Set default starting conditions for new TWI package
USI_TWI_Overflow_State = USI_SLAVE_CHECK_ADDRESS;
DDR_USI &= ~(1<<PORT_USI_SDA); // Set SDA as input
while ( (PIN_USI & (1<<PORT_USI_SCL)) & !(tmpUSISR & (1<<USIPF)) ); // Wait for SCL to go low to ensure the "Start Condition" has completed.
// If a Stop condition arises then leave the interrupt to prevent waiting forever.
USICR = (1<<USISIE)|(1<<USIOIE)| // Enable Overflow and Start Condition Interrupt. (Keep StartCondInt to detect RESTART)
(1<<USIWM1)|(1<<USIWM0)| // Set USI in Two-wire mode.
(1<<USICS1)|(0<<USICS0)|(0<<USICLK)| // Shift Register Clock Source = External, positive edge
(0<<USITC);
USISR = (1<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| // Clear flags
(0x0<<USICNT0); // Set USI to sample 8 bits i.e. count 16 external pin toggles.
// RGB_DDR |= RED_LED_MASK;
}
/*! \brief USI counter overflow ISR
* Handels all the comunication. Is disabled only when waiting
* for new Start Condition.
*/
ISR(USI_OVERFLOW_VECTOR)
{
unsigned char tmpTxTail; // Temporary variables to store volatiles
unsigned char tmpUSIDR;
switch (USI_TWI_Overflow_State)
{
// ---------- Address mode ----------
// Check address and send ACK (and next USI_SLAVE_SEND_DATA) if OK, else reset USI.
case USI_SLAVE_CHECK_ADDRESS:
if ((USIDR == 0) || (( USIDR>>1 ) == TWI_slaveAddress))
{
if ( USIDR & 0x01 )
USI_TWI_Overflow_State = USI_SLAVE_SEND_DATA;
else
USI_TWI_Overflow_State = USI_SLAVE_REQUEST_DATA;
SET_USI_TO_SEND_ACK();
}
else
{
SET_USI_TO_TWI_START_CONDITION_MODE();
}
break;
// ----- Master write data mode ------
// Check reply and goto USI_SLAVE_SEND_DATA if OK, else reset USI.
case USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA:
if ( USIDR ) // If NACK, the master does not want more data.
{
SET_USI_TO_TWI_START_CONDITION_MODE();
return;
}
// From here we just drop straight into USI_SLAVE_SEND_DATA if the master sent an ACK
// Copy data from buffer to USIDR and set USI to shift byte. Next USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA
case USI_SLAVE_SEND_DATA:
// Get data from Buffer
tmpTxTail = TWI_TxTail; // Not necessary, but prevents warnings
if ( TWI_TxHead != tmpTxTail )
{
TWI_TxTail = ( TWI_TxTail + 1 ) & TWI_TX_BUFFER_MASK;
USIDR = TWI_TxBuf[TWI_TxTail];
}
else // If the buffer is empty then:
{
SET_USI_TO_TWI_START_CONDITION_MODE();
return;
}
USI_TWI_Overflow_State = USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA;
SET_USI_TO_SEND_DATA();
break;
// Set USI to sample reply from master. Next USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA
case USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA:
USI_TWI_Overflow_State = USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA;
SET_USI_TO_READ_ACK();
break;
// ----- Master read data mode ------
// Set USI to sample data from master. Next USI_SLAVE_GET_DATA_AND_SEND_ACK.
case USI_SLAVE_REQUEST_DATA:
USI_TWI_Overflow_State = USI_SLAVE_GET_DATA_AND_SEND_ACK;
SET_USI_TO_READ_DATA();
break;
// Copy data from USIDR and send ACK. Next USI_SLAVE_REQUEST_DATA
case USI_SLAVE_GET_DATA_AND_SEND_ACK:
// Put data into Buffer
tmpUSIDR = USIDR; // Not necessary, but prevents warnings
TWI_RxHead = ( TWI_RxHead + 1 ) & TWI_RX_BUFFER_MASK;
TWI_RxBuf[TWI_RxHead] = tmpUSIDR;
USI_TWI_Overflow_State = USI_SLAVE_REQUEST_DATA;
SET_USI_TO_SEND_ACK();
break;
}
}

176
i2c_test_attiny85/USI_TWI_Slave.h Executable file
View file

@ -0,0 +1,176 @@
// This file has been prepared for Doxygen automatic documentation generation.
/*! \file ********************************************************************
*
* Atmel Corporation
*
* File : USI_TWI_Slave.h
* Compiler : IAR EWAAVR 4.11A
* Revision : $Revision: 1.14 $
* Date : $Date: Friday, December 09, 2005 17:25:38 UTC $
* Updated by : $Author: jtyssoe $
*
* Support mail : avr@atmel.com
*
* Supported devices : All device with USI module can be used.
* The example is written for the ATmega169, ATtiny26 & ATtiny2313
*
* AppNote : AVR312 - Using the USI module as a TWI slave
*
* Description : Header file for USI_TWI driver
*
*
*
****************************************************************************/
//! Prototypes
void USI_TWI_Slave_Initialise( unsigned char );
void USI_TWI_Transmit_Byte( unsigned char );
unsigned char USI_TWI_Receive_Byte( void );
unsigned char USI_TWI_Data_In_Receive_Buffer( void );
void Timer_Init(void);
#define TRUE 1
#define FALSE 0
typedef unsigned char uint8_t;
//////////////////////////////////////////////////////////////////
///////////////// Driver Buffer Definitions //////////////////////
//////////////////////////////////////////////////////////////////
// 1,2,4,8,16,32,64,128 or 256 bytes are allowed buffer sizes
#define TWI_RX_BUFFER_SIZE (8)
#define TWI_RX_BUFFER_MASK ( TWI_RX_BUFFER_SIZE - 1 )
#if ( TWI_RX_BUFFER_SIZE & TWI_RX_BUFFER_MASK )
#error TWI RX buffer size is not a power of 2
#endif
// 1,2,4,8,16,32,64,128 or 256 bytes are allowed buffer sizes
#define TWI_TX_BUFFER_SIZE (8)
#define TWI_TX_BUFFER_MASK ( TWI_TX_BUFFER_SIZE - 1 )
#if ( TWI_TX_BUFFER_SIZE & TWI_TX_BUFFER_MASK )
#error TWI TX buffer size is not a power of 2
#endif
#define USI_SLAVE_CHECK_ADDRESS (0x00)
#define USI_SLAVE_SEND_DATA (0x01)
#define USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA (0x02)
#define USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA (0x03)
#define USI_SLAVE_REQUEST_DATA (0x04)
#define USI_SLAVE_GET_DATA_AND_SEND_ACK (0x05)
//! Device dependent defines
/*#if defined(__AT90tiny26__) | defined(__ATtiny26__)
#define DDR_USI DDRB
#define PORT_USI PORTB
#define PIN_USI PINB
#define PORT_USI_SDA PORTB0
#define PORT_USI_SCL PORTB2
#define PIN_USI_SDA PINB0
#define PIN_USI_SCL PINB2
#define USI_START_COND_INT USISIF
#define USI_START_VECTOR USI_STRT_vect
#define USI_OVERFLOW_VECTOR USI_OVF_vect
#endif*/
/*#if defined(__AT90Tiny2313__) | defined(__ATtiny2313__)
#define DDR_USI DDRB
#define PORT_USI PORTB
#define PIN_USI PINB
#define PORT_USI_SDA PORTB5
#define PORT_USI_SCL PORTB7
#define PIN_USI_SDA PINB5
#define PIN_USI_SCL PINB7
#define USI_START_COND_INT USISIF
#define USI_START_VECTOR USI_START_vect
#define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect
#endif*/
/*#if defined(__ATtiny25__) | defined(__ATtiny45__) | defined(__ATtiny85__)*/
#define DDR_USI DDRB
#define PORT_USI PORTB
#define PIN_USI PINB
#define PORT_USI_SDA PB0
#define PORT_USI_SCL PB2
#define PIN_USI_SDA PINB0
#define PIN_USI_SCL PINB2
#define USI_START_COND_INT USISIF //soit USISIF ou USISIE
#define USI_START_VECTOR USI_START_vect
#define USI_OVERFLOW_VECTOR USI_OVF_vect
/*#endif*/
/*#if defined(__AT90Mega165__) | defined(__ATmega165__) | \
defined(__ATmega325__) | defined(__ATmega3250__) | \
defined(__ATmega645__) | defined(__ATmega6450__) | \
defined(__ATmega329__) | defined(__ATmega3290__) | \
defined(__ATmega649__) | defined(__ATmega6490__)
#define DDR_USI DDRE
#define PORT_USI PORTE
#define PIN_USI PINE
#define PORT_USI_SDA PORTE5
#define PORT_USI_SCL PORTE4
#define PIN_USI_SDA PINE5
#define PIN_USI_SCL PINE4
#define USI_START_COND_INT USISIF
#define USI_START_VECTOR USI_START_vect
#define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect
#endif*/
/*#if defined(__AT90Mega169__) | defined(__ATmega169__)
#define DDR_USI DDRE
#define PORT_USI PORTE
#define PIN_USI PINE
#define PORT_USI_SDA PORTE5
#define PORT_USI_SCL PORTE4
#define PIN_USI_SDA PINE5
#define PIN_USI_SCL PINE4
#define USI_START_COND_INT USISIF
#define USI_START_VECTOR USI_STRT_vect
#define USI_OVERFLOW_VECTOR USI_OVF_vect
#endif*/
//! Functions implemented as macros
#define SET_USI_TO_SEND_ACK() \
{ \
USIDR = 0; /* Prepare ACK */ \
DDR_USI |= (1<<PORT_USI_SDA); /* Set SDA as output */ \
USISR = (0<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| /* Clear all flags, except Start Cond */ \
(0x0E<<USICNT0); /* set USI counter to shift 1 bit. */ \
}
#define SET_USI_TO_READ_ACK() \
{ \
DDR_USI &= ~(1<<PORT_USI_SDA); /* Set SDA as intput */ \
USIDR = 0; /* Prepare ACK */ \
USISR = (0<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| /* Clear all flags, except Start Cond */ \
(0x0E<<USICNT0); /* set USI counter to shift 1 bit. */ \
}
#define SET_USI_TO_TWI_START_CONDITION_MODE() \
{ \
USICR = (1<<USISIE)|(0<<USIOIE)| /* Enable Start Condition Interrupt. Disable Overflow Interrupt.*/ \
(1<<USIWM1)|(0<<USIWM0)| /* Set USI in Two-wire mode. No USI Counter overflow hold. */ \
(1<<USICS1)|(0<<USICS0)|(0<<USICLK)| /* Shift Register Clock Source = External, positive edge */ \
(0<<USITC); \
USISR = (0<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| /* Clear all flags, except Start Cond */ \
(0x0<<USICNT0); \
}
#define SET_USI_TO_SEND_DATA() \
{ \
DDR_USI |= (1<<PORT_USI_SDA); /* Set SDA as output */ \
USISR = (0<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| /* Clear all flags, except Start Cond */ \
(0x0<<USICNT0); /* set USI to shift out 8 bits */ \
}
#define SET_USI_TO_READ_DATA() \
{ \
DDR_USI &= ~(1<<PORT_USI_SDA); /* Set SDA as input */ \
USISR = (0<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| /* Clear all flags, except Start Cond */ \
(0x0<<USICNT0); /* set USI to shift out 8 bits */ \
}

View file

@ -135,9 +135,33 @@
</ToolchainSettings> </ToolchainSettings>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="led_gen.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="led_gen.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="led_receptor.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="led_receptor.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="led_test.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="led_test.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="main.c"> <Compile Include="main.c">
<SubType>compile</SubType> <SubType>compile</SubType>
</Compile> </Compile>
<Compile Include="USI_TWI_Slave.c">
<SubType>compile</SubType>
</Compile>
<Compile Include="USI_TWI_Slave.h">
<SubType>compile</SubType>
</Compile>
</ItemGroup> </ItemGroup>
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" /> <Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
</Project> </Project>

34
i2c_test_attiny85/led_gen.c Executable file
View file

@ -0,0 +1,34 @@
/*
* led_gen.c
*
* Created: 03/12/2021 14:25:05
* Author: 40008304
*/
#include "led_gen.h"
void led1_init(void)
{
DDRB |= (1<<PB1);
TCCR1|=(1<<CTC1)|(1<<COM1A0); //on active le mode CTC en comparant OCR1C, COM1A1 ? 1 pour desactiver /OC1A
OCR1C=16; //d'apres retroingenieurie OCR1C=16
TCCR1|=(1<<CS10); //on active la clock avec CS10 = 1, pas de prediv (plus precis pour haute freq)
}
void led2_init(void)
{
DDRB |= (1<<PB4);
GTCCR|=(1<<COM1B0); //COM1B0 a 1 pour desactiver /OC1A
OCR1B=16; //d'apres retroingenieurie OCR1B=16
TCCR1|=(1<<CS10); //on active la clock avec CS10 = 1, pas de prediv (plus precis pour haute freq)
}
void led1_stop(void)
{
TCCR1 &= ~(1<<COM1A0);
}
void led2_stop(void)
{
GTCCR &= ~(1<<COM1B0);
}

19
i2c_test_attiny85/led_gen.h Executable file
View file

@ -0,0 +1,19 @@
/*
* led_gen.h
*
* Created: 03/12/2021 14:25:45
* Author: 40008304
*/
#ifndef LED_GEN_H_
#define LED_GEN_H_
#include <avr/io.h>
void led1_init(void);
void led2_init(void);
void led1_stop(void);
void led2_stop(void);
#endif /* LED_GEN_H_ */

View file

@ -0,0 +1,81 @@
/*
* led_receptor.c
*
* Created: 03/12/2021 14:29:43
* Author: 40008304
*/
#include "led_receptor.h"
void ADC_init(void)
{
DDRB &=~(1<<PB3); //Pin B3 en entree
ADMUX |= (1<<MUX1)|(1<<MUX0)|(1<<ADLAR); //MUX = 0010 donc sortie PB4 et ADLAR a 1 pour avoir les bits de poids fort en premier
ADCSRA |= (1<<ADEN)|(1<<ADPS2); //On divise 1Mhz par 16 (62.5 KHz) < 200 KHz, ADEN conversion autorisee
};
char ADC_read_value(void)
{
ADCSRA|=(1<<ADSC);
while(ADCSRA & (1<<ADSC));
return ADCH;
};
float ADC_averaging(void)
{
float valeur_finale=0;
char precision;
for(precision = 75; precision > 0 ; precision --)
{
valeur_finale = valeur_finale +(((ADC_read_value() * 0.01961) - valeur_finale) / 15);
}
return valeur_finale;
};
float measureLed1(void)
{
float adcLed;
led2_stop();
led1_init();
_delay_ms(TIMING);
adcLed=ADC_averaging();
_delay_ms(TIMING);
return adcLed;
};
float measureLed2(void)
{
float adcLed;
led1_stop();
led2_init();
_delay_ms(TIMING);
adcLed=ADC_averaging();
_delay_ms(TIMING);
return adcLed;
};
char compareLed(void)
{
float adcLed1 = measureLed1();
float adcLed2 = measureLed2();
float adcCompare = adcLed1 - adcLed2;
if (adcCompare < -VOLTMIN) // adcLed2 > adcLed1
{
return LEFT;
}
else if (adcCompare > VOLTMIN)
{
return RIGHT;
}
else
{
if((adcLed1 > VOLTMIN) && (adcLed2 > VOLTMIN))
{
return FRONT;
}
else
{
return NOTHING;
};
};
};

View file

@ -0,0 +1,31 @@
/*
* led_receptor.h
*
* Created: 03/12/2021 14:29:30
* Author: 40008304
*/
#ifndef LED_RECEPTOR_H_
#define LED_RECEPTOR_H_
#include "led_gen.h"
#define F_CPU 1000000
#include <util/delay.h>
#define FRONT 0x51
#define RIGHT 0x52
#define LEFT 0x53
#define NOTHING 0x54
#define ERROR 0xF0
#define VOLTMIN 1
#define TIMING 250
void ADC_init(void);
char ADC_read_value(void);
float ADC_averaging(void);
float measureLed1(void);
float measureLed2(void);
char compareLed(void);
#endif /* LED_RECEPTOR_H_ */

34
i2c_test_attiny85/led_test.c Executable file
View file

@ -0,0 +1,34 @@
/*
* led_test.c
*
* Created: 03/12/2021 15:28:35
* Author: 40008304
*/
#include "led_test.h"
void testLed(void)
{
char sendingData = compareLed();
switch(sendingData)
{
case NOTHING:
PORTB |= (1<<PINB0); //les deux sont eteintes
PORTB |= (1<<PINB2);
break;
case FRONT:
PORTB &= ~(1<<PINB0); //les deux sont allumees
PORTB &= ~(1<<PINB2);
break;
case RIGHT:
PORTB &= ~(1<<PINB0); //a droite allumee (led0)
PORTB |= (1<<PINB2);
break;
case LEFT:
PORTB |= (1<<PINB0); //a gauche allumee (led1)
PORTB &= ~(1<<PINB2);
break;
default:
break;
};
}

16
i2c_test_attiny85/led_test.h Executable file
View file

@ -0,0 +1,16 @@
/*
* led_test.h
*
* Created: 03/12/2021 15:28:48
* Author: 40008304
*/
#ifndef LED_TEST_H_
#define LED_TEST_H_
#include "led_receptor.h"
void testLed(void);
#endif /* LED_TEST_H_ */

View file

@ -6,158 +6,60 @@
*/ */
#include <avr/io.h> #include <avr/io.h>
#define F_CPU 1000000
#include <util/delay.h>
#define FRONT 0x51 #include "led_gen.h"
#define RIGHT 0x52 #include "led_receptor.h"
#define LEFT 0x53 #include "led_test.h"
#define NOTHING 0x54 #include "USI_TWI_Slave.h"
#define ERROR 0xF0
#define VOLTMIN 1
void led1_init(void); #define MSTR_TEST_WR 0x31
void led2_init(void); #define MSTR_TEST_RE 0x32
void led1_stop(void);
void led2_stop(void); #define SLAVE_ADRESS 0x01
void ADC_init(void); #define NOM_CONSTRUC 0x08
char ADC_read_value(void); #define NOM_CAPTEUR 0x10
float ADC_averaging(void); #define VALEUR_DEMAN 0x49
float measureLed1(void); #define BASIC_MODE 0x42
float measureLed2(void);
char compareLed(void);
int main(void) int main(void)
{ {
DDRB |= (1<<PB0); unsigned char cmd, i, val;
DDRB |= (1<<PB2); unsigned char nom_capteur[9]={'I','U','T','V','i','D','A','v'};
unsigned char sensor_type[9]={'S','u','m','o','E','y','e','s'};
USI_TWI_Slave_Initialise(SLAVE_ADRESS);
led2_init(); led2_init();
led1_init(); led1_init();
ADC_init(); ADC_init();
char sendingData;
while (1) while (1)
{ {
sendingData = compareLed(); if( USI_TWI_Data_In_Receive_Buffer() )
switch(sendingData)
{ {
case NOTHING: cmd = USI_TWI_Receive_Byte();
PORTB |= (1<<PINB0); //les deux sont eteintes
PORTB |= (1<<PINB2); switch(cmd){
break; case MSTR_TEST_WR :
case FRONT: val=USI_TWI_Receive_Byte();
PORTB &= ~(1<<PINB0); //les deux sont allumees break;
PORTB &= ~(1<<PINB2);
break; case MSTR_TEST_RE :
case RIGHT: USI_TWI_Transmit_Byte(0x0F);
PORTB &= ~(1<<PINB0); //a droite allumee (led0) break;
PORTB |= (1<<PINB2);
break; case NOM_CONSTRUC :
case LEFT: for (i=0;i<8;i++){USI_TWI_Transmit_Byte(nom_capteur[i]);}
PORTB |= (1<<PINB0); //a gauche allumee (led1) break;
PORTB &= ~(1<<PINB2); case NOM_CAPTEUR :
break; for (i=0;i<8;i++){USI_TWI_Transmit_Byte(sensor_type[i]);}
default: break;
break;
case VALEUR_DEMAN :
USI_TWI_Transmit_Byte(0x45);
break;
case BASIC_MODE :
USI_TWI_Transmit_Byte(0x46);
break;
};
}; };
}; };
val++;
} }
void led1_init(void)
{
DDRB |= (1<<PB1);
TCCR1|=(1<<CTC1)|(1<<COM1A0); //on active le mode CTC en comparant OCR1C, COM1A1 <20> 1 pour desactiver /OC1A
OCR1C=16; //d'apres retroingenieurie OCR1C=16
TCCR1|=(1<<CS10); //on active la clock avec CS10 = 1, pas de prediv (plus precis pour haute freq)
}
void led2_init(void)
{
DDRB |= (1<<PB4);
GTCCR|=(1<<COM1B0); //COM1B0 a 1 pour desactiver /OC1A
OCR1B=16; //d'apres retroingenieurie OCR1B=16
TCCR1|=(1<<CS10); //on active la clock avec CS10 = 1, pas de prediv (plus precis pour haute freq)
}
void led1_stop(void)
{
TCCR1 &= ~(1<<COM1A0);
}
void led2_stop(void)
{
GTCCR &= ~(1<<COM1B0);
}
void ADC_init(void)
{
DDRB &=~(1<<PB3); //Pin B3 en entree
ADMUX |= (1<<MUX1)|(1<<MUX0)|(1<<ADLAR); //MUX = 0010 donc sortie PB4 et ADLAR a 1 pour avoir les bits de poids fort en premier
ADCSRA |= (1<<ADEN)|(1<<ADPS2); //On divise 1Mhz par 16 (62.5 KHz) < 200 KHz, ADEN conversion autorisee
};
char ADC_read_value(void)
{
ADCSRA|=(1<<ADSC);
while(ADCSRA & (1<<ADSC));
return ADCH;
};
float ADC_averaging(void)
{
float valeur_finale=0;
char precision;
for(precision = 75; precision > 0 ; precision --)
{
valeur_finale = valeur_finale +(((ADC_read_value() * 0.01961) - valeur_finale) / 15);
}
return valeur_finale;
};
float measureLed1(void)
{
float adcLed;
led2_stop();
led1_init();
_delay_ms(250);
adcLed=ADC_averaging();
_delay_ms(250);
return adcLed;
};
float measureLed2(void)
{
float adcLed;
led1_stop();
led2_init();
_delay_ms(250);
adcLed=ADC_averaging();
_delay_ms(250);
return adcLed;
};
char compareLed(void)
{
float adcLed1 = measureLed1();
float adcLed2 = measureLed2();
float adcCompare = adcLed1 - adcLed2;
if (adcCompare < -VOLTMIN) // adcLed2 > adcLed1
{
return LEFT;
}
else if (adcCompare > VOLTMIN)
{
return RIGHT;
}
else
{
if((adcLed1 > VOLTMIN) && (adcLed2 > VOLTMIN))
{
return FRONT;
}
else
{
return NOTHING;
};
};
};

7
i2c_test_attiny85/test_led.c Executable file
View file

@ -0,0 +1,7 @@
/*
* test_led.c
*
* Created: 03/12/2021 15:25:24
* Author: 40008304
*/