Outils pour utilisateurs

Outils du site


robotics:computing:communication_twi_entre_atmega

Différences

Cette page vous affiche les différences entre la révision choisie et la version actuelle de la page.

Lien vers cette vue comparative

robotics:computing:communication_twi_entre_atmega [2013/09/27 15:49]
ldo [Slave]
robotics:computing:communication_twi_entre_atmega [2013/09/27 15:56] (Version actuelle)
ldo [Master]
Ligne 169: Ligne 169:
 Ce code permet d'​envoyer une donnée à un esclave. Ce code permet d'​envoyer une donnée à un esclave.
  
-Dans un premier temps, on va définir la vitesse de communication en initialisant TWBR et le prescaler dans twiMasterInitialise().+Dans un premier temps, on va définir la vitesse de communication en initialisant TWBR et le prescaler dans twi_master_setup().
 <code c> <code c>
 /* /*
Ligne 178: Ligne 178:
  */  */
  
-/* ATMEGA48 @20MHz +volatile uint8_t slave_address;​
- * 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>​+volatile uint8_t twi_flag_read_complete = 1; 
 +volatile uint8_t twi_flag_write_complete = 1;
  
-//sets bitrate and prescaler +volatile uint8_t *twi_receive_buffer;​ 
-void twiMasterInitialise(unsigned char bitRateunsigned char prescaler)+volatile uint8_t *twi_transmit_buffer;​ 
 +volatile uint8_t twi_i = 0; 
 + 
 +uint8_t twi_mode; 
 +uint8_t twi_nb_data_to_transmittwi_nb_data_to_receive;​ 
 + 
 +ISR(TWI_vect)
 { {
- PRR = (0 << ​PRTWI); // the PRTWI bit in PRR must be written to zero to enable the TWI +  uint8_t status; 
- TWSR prescaler ​0x03+ 
- TWBR bitRate;+  status ​TWSR & 0xF8; 
 +  switch ​(status) 
 +    { 
 +  case (TW_START): /* 0x08 : start condition transmitted */ 
 +  case (TW_REP_START):​ /* 0x10 : repeated START condition transmitted */ 
 +    twi_address();​ 
 +    twi_i = 0
 +    break; 
 +  case (TW_MT_ARB_LOST):​ /* 0x38 : arbitration lost in SLA+RW, SLA+R received, ACK returned */ 
 +    break; 
 + 
 +    /* Master Transmitter */ 
 +  case (TW_MT_SLA_ACK):​ /* 0x18 : SLA+W transmitted;​ ACK received */ 
 +  case (TW_MT_SLA_NACK):​ /* 0x20 : SLA+W transmitted;​ NACK received */ 
 +    TWDR = twi_transmit_buffer[0];​ 
 +    TWCR = (1 << ​TWEA) | (1 << TWEN) | (1 << TWIE) | (1 << TWINT); 
 +    twi_i++; 
 +    break; 
 + 
 +  case (TW_MT_DATA_ACK):​/* 0x28 : data has been transmitted;​ ACK has been received *
 +  case (TW_MT_DATA_NACK):​ /* 0x30 : data has been transmitted;​ NACK has been received */ 
 +    if (twi_i ​== twi_nb_data_to_transmit) 
 +      { 
 +        if (twi_mode == WRITE) 
 +          { 
 +            twi_stop();​ 
 +            twi_flag_write_complete = 1; 
 +          } 
 +        else // READ 
 +          { 
 +            slave_address++;​ 
 +            twi_start();​ 
 +          } 
 +      } 
 +    else 
 +      { 
 +        twi_data(twi_transmit_buffer[twi_i]);​ 
 +        twi_i++; 
 +      } 
 +    break; 
 + 
 +    /* Master Receiver */ 
 +  case (TW_MR_SLA_ACK):/​* 0x40 : SLA+R has been transmitted;​ ACK has been received */ 
 + 
 +  case (TW_MR_SLA_NACK):​ /* 0x48 : SLA+R has been transmitted;​ NACK has been received */ 
 +    if (twi_nb_data_to_receive == 1) 
 +      { 
 +        TWCR &= ~(1 << TWEA)/* desactiver ACK pour la derniere demande */ 
 +      } 
 +    break; 
 +  case (TW_MR_DATA_ACK):/​* 0x50 : data received, ACK transmitted */ 
 +  case (TW_MR_DATA_NACK):​ /* 0x58 : data received, NACK transmitted */ 
 +    twi_receive_buffer[twi_i] ​TWDR; 
 +    twi_i++; 
 + 
 +    if (twi_i == (twi_nb_data_to_receive - 1)) 
 +      { 
 +        TWCR &= ~(1 << TWEA); /* desactiver ACK pour la derniere demande */ 
 +      } 
 +    if (twi_i == twi_nb_data_to_receive) 
 +      { 
 +        twi_flag_read_complete = 1; 
 +        twi_stop();​ 
 +      } 
 +    break; 
 + 
 +  default: 
 +    break; 
 +    } 
 + 
 +  TWCR |= (1 << TWINT); // TWINT flag bit is cleared
 } }
  
-void twiError(void)+/* 
 + * twi master setup 
 + * SCLfreq = CPUfreq / (16 + 2 * TWBR * presc) 
 + * */ 
 +void 
 +twi_master_setup(void)
 { {
 +  PORTC = (1 << PC5) | (1 << PC4); // activate internal pull_ups for twi 
 +  TWSR = 0x00;    // no prescaler 
 +  TWBR = 72; // 100kHz @16Mhz 
 +  //TWBR = 0x0C;    // 400 KHz @16MHz 
 +  TWCR = (1 << TWEA) | (1 << TWEN) | (1 << TWIE) | (1 << TWINT); 
 +  SREG |= (1 << SREG_I);
 } }
  
-void twiWait(unsigned char myStatus)+void 
 +TWI_wait(void)
 { {
- while (!(TWCR & (1 << TWINT))) +  ​while (!(TWCR & (1 << TWINT))) 
- ; +    ;
- if ((TWSR & 0xF8) != myStatus) +
-+
- twiError();​ +
- }+
 } }
  
-/* send START condition ​bit */ +/* transmit ​START condition */ 
-void twiStart(void)+void 
 +twi_start(void)
 { {
- /* TWINT : TWI interrupt flag +  ​TWCR = (1 << ​TWEA) | (1 << ​TWEN) | (<< ​TWIE) | (1 << ​TWINT(1 << TWSTA); /* send start condition */
- * TWSTA : TWI START condition bit +
- * TWSTO : TWI STOP condition bit +
- * TWEN : TWI enable bit */ +
- TWCR = (1 << ​TWINT) | (1 << ​TWSTA) | (<< ​TWSTO) | (1 << ​TWEN)+
- twiWait(TW_START);+
 } }
  
-/* send slave address */ +/* transmit ​slave address ​SLA */ 
-void twiAddress(unsigned char myAddress)+void 
 +twi_address(void)
 { {
- TWDR = myAddress+  ​TWDR = slave_address/* load SLA into TWDR */ 
- TWCR = (1 << TWINT) | (0 << TWSTA) | (0 << TWSTO) | (1 << TWEN); + 
- twiWait(TW_MT_SLA_ACK); // 0x18, 0x20 or 0x38+  ​TWCR &~(1 << TWSTA); /* desactivate START */
 } }
  
-/* send data */ +/* transmit ​data */ 
-void twiData(unsigned char myData)+void 
 +twi_data(uint8_t data)
 { {
- TWDR = myData; +  ​TWDR = data;
- TWCR = (1 << TWINT) | (0 << TWSTA) | (0 << TWSTO) | (1 << TWEN); +
- twiWait(TW_MT_DATA_ACK);+
 } }
  
-/* send STOP condition ​bit */ +/* transmit ​STOP condition */ 
-void twiStop(void)+void 
 +twi_stop(void)
 { {
- TWCR = (1 << TWINT) | (0 << TWSTA) | (1 << TWSTO) | (1 << TWEN);+  ​TWCR |= (1 << TWSTO); ​/* STOP */
 } }
  
-/* write data to slaveAddress */ +void 
-void twiWriteData(unsigned char slaveAddressunsigned char data)+twi_write_bytes(uint8_t adduint8_t nb_bytes, volatile uint8_t *buffer)
 { {
- twiStart(); +  if (twi_flag_write_complete == 1) 
- twiAddress(slaveAddress)+    { 
- twiData(data)+      twi_flag_write_complete = 0
- twiStop();+      ​slave_address = add << 1
 +      ​twi_transmit_buffer = buffer
 +      ​twi_start(); 
 +    }
 } }
  
 +void
 +twi_read_bytes(uint8_t add, volatile uint8_t *reg, uint8_t nb_bytes,
 +    volatile uint8_t *buffer)
 +{
 +  if (twi_flag_read_complete == 1)
 +    {
 +      twi_flag_read_complete = 0;
 +      twi_flag_write_complete = 0;
  
-int main(void)+      slave_address = add; 
 + 
 +      twi_transmit_buffer = reg; 
 + 
 +      twi_mode = READ; 
 +      twi_nb_data_to_transmit = 1; 
 +      twi_nb_data_to_receive = nb_bytes; 
 + 
 +      twi_receive_buffer = buffer; 
 + 
 +      twi_start();​ 
 +      while (twi_flag_read_complete == 0) 
 +        ; 
 +    } 
 +
 + 
 +void 
 +setup(void)
 { {
- twiMasterInitialise(92, 0); //set TWBR = 92 for 100kHz SCL @ 20MHz+  twi_master_setup(); 
 +}
  
- while (1) +int 
-+main(void) 
- twiWriteData(0x200x05); //write 0x05 @0x20 +
- } +  uint8_t * buf; 
- return 1;+  setup(); 
 +  ​while (1) 
 +    
 +      ​twi_read_bytes(0x680x42, 1, buf); 
 +    }
 } }
 </​code>​ </​code>​
robotics/computing/communication_twi_entre_atmega.1380289785.txt.gz · Dernière modification: 2013/09/27 15:49 par ldo