Ceci est une ancienne révision du document !
Code Text
/*
* twislave.c
*
* Created on: 26 févr. 2010
* Author: gdo
*/
/* ATMEGA48 @20MHz * LOW FUSE : F7 * CKDIV8=1 no divided clock by 8 * CKOUT=1 no clock output on PORTB * SUT1..0=11 slowly rising power * CKSEL3..0=0111 full swing crystal oscillator */
#include <avr/interrupt.h> #include<util/twi.h>
void twiSlaveInitialise(unsigned char myAddress);
ISR(TWI_vect) {
switch (TWSR) { /* Slave Transmitter*/ case (TW_ST_SLA_ACK): /* 0xA8 : SLA+R received, ACK returned*/ break; case (TW_ST_ARB_LOST_SLA_ACK): /* 0xB0 : arbitration lost in SLA+RW, SLA+R received, ACK returned */ break; case (TW_ST_DATA_ACK): /* 0xB8 : data transmitted, ACK received */ break; case (TW_ST_DATA_NACK):/*0xC0 : data transmitted, NACK received */ break; case (TW_ST_LAST_DATA): /* 0xC8 : last data byte transmitted, ACK received */ break;
/* Slave Receiver */ case (TW_SR_SLA_ACK):/* 0x60 : SLA+W received, ACK returned */ break; case (TW_SR_ARB_LOST_SLA_ACK):/*0x68 : arbitration lost in SLA+RW, SLA+W received, ACK returned */ break; case (TW_SR_GCALL_ACK): /*0x70 : general call received, ACK returned */ break; case (TW_SR_ARB_LOST_GCALL_ACK): /* 0x78 : arbitration lost in SLA+RW, general call received, ACK returned */ break; case (TW_SR_DATA_ACK): /* 0x80 : data received, ACK returned */ break; case (TW_SR_DATA_NACK): /* 0x88 : data received, NACK returned */ break; case (TW_SR_GCALL_DATA_ACK): /* 0x90 : general call data received, ACK returned */ break; case (TW_SR_GCALL_DATA_NACK):/* 0x98 : general call data received, NACK returned */ break; case (TW_SR_STOP):/* 0xA0 : stop or repeated start condition received while selected */ break;
default: break; }
TWCR |= 0b10000000; // TWINT flag bit is cleared
}
void twiSlaveInitialise(unsigned char myAddress) {
PRR = (0 << PRTWI); // the PRTWI bit in PRR must be written to zero to enable the TWI TWAR = myAddress + 1; // Set own TWI slave address. Accept TWI General Calls. /* TWINT = 0 : * TWEA = 1 : enable ACK * TWSTA = 0: start condition * TWSTO = 0 : stop condition * TWEN = 1 : enable the TWI * TWIE = 1 : enable TWI interrupt */ TWCR = (0 << TWINT) | (1 << TWEA) | (0 << TWSTA) | (0 << TWSTO) | (1 << TWEN) | (1 << TWIE);
}
int main(void) {
twiSlaveInitialise(0x20); SREG = (1 << SREG_I); /* The Global Interrupt Enable bit must be set for the interrupts to be enabled */
while (1) { } return 1;
}
* /* * twiMaster.c * * Created on: 25 nov. 2009 * Author: gdo */ /* ATMEGA48 @20MHz * pull up resistor 1.5kohm * LOW FUSE : F7 * CKDIV8=1 no divided clock by 8 * CKOUT=1 no clock output on PORTB * SUT1..0=11 slowly rising power * CKSEL3..0=0111 full swing crystal oscillator */ #include<util/twi.h> sets bitrate and prescaler void twiMasterInitialise(unsigned char bitRate, unsigned char prescaler) { PRR = (0 « PRTWI); the PRTWI bit in PRR must be written to zero to enable the TWI TWSR = prescaler & 0x03; TWBR = bitRate; } void twiError(void) { } void twiWait(unsigned char myStatus) { while (!(TWCR & (1 « TWINT))) ; if ((TWSR & 0xF8) != myStatus) { twiError(); } } /* send START condition bit */ void twiStart(void) { /* TWINT : TWI interrupt flag * TWSTA : TWI START condition bit * TWSTO : TWI STOP condition bit * TWEN : TWI enable bit */ TWCR = (1 « TWINT) | (1 « TWSTA) | (0 « TWSTO) | (1 « TWEN); twiWait(TW_START); } /* send slave address */ void twiAddress(unsigned char myAddress) { TWDR = myAddress; TWCR = (1 « TWINT) | (0 « TWSTA) | (0 « TWSTO) | (1 « TWEN); twiWait(TW_MT_SLA_ACK); 0x18, 0x20 or 0x38 } /* send data */ void twiData(unsigned char myData) { TWDR = myData; TWCR = (1 « TWINT) | (0 « TWSTA) | (0 « TWSTO) | (1 « TWEN); twiWait(TW_MT_DATA_ACK); } /* send STOP condition bit */ void twiStop(void) { TWCR = (1 « TWINT) | (0 « TWSTA) | (1 « TWSTO) | (1 « TWEN); } /* write data to slaveAddress */ void twiWriteData(unsigned char slaveAddress, unsigned char data) { twiStart(); twiAddress(slaveAddress); twiData(data); twiStop(); } int main(void) { twiMasterInitialise(92, 0); set TWBR = 92 for 100kHz SCL @ 20MHz while (1) { twiWriteData(0x20, 0x05); write 0x05 @0x20 } return 1; } /**/ l'attente peut etre bloquante si l'esclave ne repond pas (planté ou pb de connection). Dans ce cas il faut mettre un timeOut.