Additions from 03/12/2021: Refactoring to multiple files.
This commit is contained in:
parent
f2c5b40d7d
commit
900988633e
11 changed files with 686 additions and 142 deletions
220
i2c_test_attiny85/USI_TWI_Slave.c
Executable file
220
i2c_test_attiny85/USI_TWI_Slave.c
Executable 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
176
i2c_test_attiny85/USI_TWI_Slave.h
Executable 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 */ \
|
||||
}
|
|
@ -135,9 +135,33 @@
|
|||
</ToolchainSettings>
|
||||
</PropertyGroup>
|
||||
<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">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="USI_TWI_Slave.c">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
<Compile Include="USI_TWI_Slave.h">
|
||||
<SubType>compile</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
|
||||
</Project>
|
34
i2c_test_attiny85/led_gen.c
Executable file
34
i2c_test_attiny85/led_gen.c
Executable 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
19
i2c_test_attiny85/led_gen.h
Executable 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_ */
|
81
i2c_test_attiny85/led_receptor.c
Executable file
81
i2c_test_attiny85/led_receptor.c
Executable 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;
|
||||
};
|
||||
};
|
||||
};
|
31
i2c_test_attiny85/led_receptor.h
Executable file
31
i2c_test_attiny85/led_receptor.h
Executable 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
34
i2c_test_attiny85/led_test.c
Executable 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
16
i2c_test_attiny85/led_test.h
Executable 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_ */
|
|
@ -6,158 +6,60 @@
|
|||
*/
|
||||
|
||||
#include <avr/io.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
|
||||
#include "led_gen.h"
|
||||
#include "led_receptor.h"
|
||||
#include "led_test.h"
|
||||
#include "USI_TWI_Slave.h"
|
||||
|
||||
void led1_init(void);
|
||||
void led2_init(void);
|
||||
void led1_stop(void);
|
||||
void led2_stop(void);
|
||||
void ADC_init(void);
|
||||
char ADC_read_value(void);
|
||||
float ADC_averaging(void);
|
||||
float measureLed1(void);
|
||||
float measureLed2(void);
|
||||
char compareLed(void);
|
||||
#define MSTR_TEST_WR 0x31
|
||||
#define MSTR_TEST_RE 0x32
|
||||
|
||||
#define SLAVE_ADRESS 0x01
|
||||
#define NOM_CONSTRUC 0x08
|
||||
#define NOM_CAPTEUR 0x10
|
||||
#define VALEUR_DEMAN 0x49
|
||||
#define BASIC_MODE 0x42
|
||||
|
||||
int main(void)
|
||||
{
|
||||
DDRB |= (1<<PB0);
|
||||
DDRB |= (1<<PB2);
|
||||
unsigned char cmd, i, val;
|
||||
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();
|
||||
led1_init();
|
||||
ADC_init();
|
||||
char sendingData;
|
||||
while (1)
|
||||
{
|
||||
sendingData = compareLed();
|
||||
switch(sendingData)
|
||||
if( USI_TWI_Data_In_Receive_Buffer() )
|
||||
{
|
||||
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;
|
||||
cmd = USI_TWI_Receive_Byte();
|
||||
|
||||
switch(cmd){
|
||||
case MSTR_TEST_WR :
|
||||
val=USI_TWI_Receive_Byte();
|
||||
break;
|
||||
|
||||
case MSTR_TEST_RE :
|
||||
USI_TWI_Transmit_Byte(0x0F);
|
||||
break;
|
||||
|
||||
case NOM_CONSTRUC :
|
||||
for (i=0;i<8;i++){USI_TWI_Transmit_Byte(nom_capteur[i]);}
|
||||
break;
|
||||
case NOM_CAPTEUR :
|
||||
for (i=0;i<8;i++){USI_TWI_Transmit_Byte(sensor_type[i]);}
|
||||
break;
|
||||
|
||||
case VALEUR_DEMAN :
|
||||
USI_TWI_Transmit_Byte(0x45);
|
||||
break;
|
||||
case BASIC_MODE :
|
||||
USI_TWI_Transmit_Byte(0x46);
|
||||
break;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
val++;
|
||||
}
|
7
i2c_test_attiny85/test_led.c
Executable file
7
i2c_test_attiny85/test_led.c
Executable file
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* test_led.c
|
||||
*
|
||||
* Created: 03/12/2021 15:25:24
|
||||
* Author: 40008304
|
||||
*/
|
||||
|
Loading…
Add table
Reference in a new issue