Fórum témák

» Több friss téma
Cikkek » HMC6352 iránytűmodul - I2C (TWI) használata AVR-rel
HMC6352 iránytűmodul - I2C (TWI) használata AVR-rel
Szerző: Fizikus, idő: Nov 27, 2010, Olvasva: 23923, Oldal olvasási idő: kb. 3 perc
Lapozás: OK   5 / 9

AVR program

Az AVR kódja elég egyszerű: a soros porton keresztül kapott parancs után (`m` karakter) a TWI (I2C) buszon keresztül lekérdezi az iránytűmodul mágneses északi iránnyal bezárt irányszögét, majd az eredményt UART-on keresztül elküldi a PC-re. Most is az előző cikkben ismertetett ún. call-and-response módszert használjuk a Processing-gel történő szinkronizálásra. Az AVR csak akkor végez el egy mérést és továbbítja annak eredményét a PC felé, ha előtte a Processing-től erre utasítást kap.

  1. /*************************************************************************
  2. * Title:    I2C master library using hardware TWI interface
  3. * Author:   Peter Fleury <<a href="mailto:pfleury@gmx.ch">pfleury@gmx.ch</a>>  <a href="http://jump.to/fleury">http://jump.to/fleury</a>
  4. **************************************************************************/
  5. /*
  6. ADC + UART
  7. Hardware: ATmega8 @ 7.372800MHz
  8. PC Software:Hyper terminal @ 9600 baud, Nincs Paritas Bit, 1 Stop Bit, Flow Control = NONE
  9. */
  10. #define F_CPU 7372800UL // rendszer orajel: 7.3728 MHz
  11. #define USART_BAUDRATE 9600  // soros kommunikácio sebessege: 9600 bps
  12. #define UBRR_ERTEK ((F_CPU / (USART_BAUDRATE * 16UL)) - 1) // UBRR
  13. #define SCL_CLOCK  100000L // I2C sebessege Hz-ben
  14. #define I2C_READ    1    // adatiranyt jelzo bit - olvasas
  15. #define I2C_WRITE   0    // adatiranyt jelzo bit - iras
  16. #define HMC6352  0x42      // iranytumodul I2C cime
  17. #include <avr/io.h>
  18. #include <inttypes.h>
  19. #include <util/delay.h>
  20. #include <compat/twi.h>
  21. void KonfigUART() // UART beallitasa
  22. {
  23.    // 9600 bps soros kommunikácio sebesseg beallitasa
  24.    UBRRL = UBRR_ERTEK;    // UBRR_ERTEK also 8 bitjenek betoltese az UBRRL regiszterbe
  25.    UBRRH = (UBRR_ERTEK>>8);  // UBRR_ERTEK felso 8 bitjenek betoltese az UBRRH reg.-be
  26.    // Aszinkron mod, 8 Adat Bit, Nincs Paritas Bit, 1 Stop Bit
  27.    UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);
  28.    //Ado es Vevo aramkorok bekapcsolasa + az RX interrupt engedelyezese
  29.    UCSRB |= (1 << RXEN) | (1 << TXEN);   //
  30. }
  31. char UARTAdatFogad() // Ez a fuggveny a beerkezo adatokat kiolvassa az UDR regiszter bejovo pufferebol
  32. {
  33.    while(!(UCSRA & (1<<RXC)))  // Varakozas amig nincs uj bejovo adat
  34.    {
  35.       //Varakozas
  36.    }
  37.    //Most mar van beerkezett adat, amit kiolvasunk a pufferbol
  38.    return UDR;
  39. }
  40. void UARTAdatKuld(char data) // Ez a fuggveny a kuldendo adatot beirja az UDR regiszter kimeno pufferjebe
  41. {
  42.    while(!(UCSRA & (1<<UDRE)))  // Varakozas amig az Ado kesz nem lesz az adatkuldesre
  43.    {
  44.       //Varakozas
  45.    }
  46.    // Az Ado mar kesz az adatkuldesre, a kuldendo adatot a kimeno pufferjebe irjuk
  47.    UDR=data;
  48. }
  49. /*************************************************************************
  50. I2C periferia inicializalasa
  51. *************************************************************************/
  52. void i2c_init(void)
  53. {
  54.   TWSR = 0;            
  55.   TWBR = ((F_CPU/SCL_CLOCK)-16)/2;
  56. }
  57. /*************************************************************************
  58. Startjel kiadasa, majd az eszkozazonosito cim es adatirany elkuldese
  59. Fuggv. parameter: I2C eszkozazonosito cim, adatirany
  60. Fuggv. altal visszadott ertek: 0 = eszkoz elerheto, 1= eszkoz elerese sikertelen
  61. *************************************************************************/
  62. unsigned char i2c_start(unsigned char address)
  63. {
  64.     uint8_t   twst;
  65.  // START jel kuldese
  66.  TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
  67.  // varakozas amig az atvitel be nem fejezodik
  68.  while(!(TWCR & (1<<TWINT)));
  69.  // TWI Statusz Register ertekenek ellenorzese, elooszto bitek kimaszkolasa.
  70.  twst = TW_STATUS & 0xF8;
  71.  if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;
  72.  // eszkozazonosito cim kuldese
  73.  TWDR = address;
  74.  TWCR = (1<<TWINT) | (1<<TWEN);
  75.  // varakozas amig az atvitel be nem fejezodik es az ACK/NACK nyugtazas be nem erkezik
  76.  while(!(TWCR & (1<<TWINT)));
  77.  // TWI Statusz Register ertekenek ellenorzese, elooszto bitek kimaszkolasa.
  78.  twst = TW_STATUS & 0xF8;
  79.  if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
  80.  return 0;
  81. }
  82. /*************************************************************************
  83. Startjel kiadasa, majd az eszkozazonosito cim es adatirany elkuldese
  84. Ha az eszkoz foglalt, varakozas amig kesz nem lesz (ack polling)
  85. Fuggv. parameter: I2C eszkozazonosito cim, adatirany
  86. *************************************************************************/
  87. void i2c_start_wait(unsigned char address)
  88. {
  89.     uint8_t   twst;
  90.     while ( 1 )
  91.     {
  92.      // START jel kuldese
  93.      TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
  94.      // varakozas amig az atvitel be nem fejezodik
  95.      while(!(TWCR & (1<<TWINT)));
  96.      // TWI Statusz Register ertekenek ellenorzese, elooszto bitek kimaszkolasa.
  97.      twst = TW_STATUS & 0xF8;
  98.      if ( (twst != TW_START) && (twst != TW_REP_START)) continue;
  99.      // eszkozazonosito cim kuldese    
  100.      TWDR = address;
  101.      TWCR = (1<<TWINT) | (1<<TWEN);
  102.      // varakozas amig az atvitel be nem fejezodik    
  103.      while(!(TWCR & (1<<TWINT)));
  104.      // TWI Statusz Register ertekenek ellenorzese, elooszto bitek kimaszkolasa.    
  105.      twst = TW_STATUS & 0xF8;
  106.      if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) )
  107.      {  
  108.          // az eszkoz foglalt, Stop jel kuldese, irasi muvelet befejezese        
  109.          TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
  110.          //  varakozas amig a Stop utasitas vegre nem hajtodik es az I2C busz szabad nem lesz
  111.          while(TWCR & (1<<TWSTO));
  112.          continue;
  113.      }
  114.      //if( twst != TW_MT_SLA_ACK) return 1;
  115.      break;
  116.      }
  117. }  
  118.  
  119. /*************************************************************************
  120. Ismetelt Startjel kiadasa, majd az eszkozazonosito cim es adatirany elkuldese
  121. Fuggv. parameter: I2C eszkozazonosito cim, adatirany
  122. Fuggv. altal visszadott ertek: 0 = eszkoz elerheto, 1= eszkoz elerese sikertelen
  123. *************************************************************************/
  124. unsigned char i2c_rep_start(unsigned char address)
  125. {
  126.     return i2c_start( address );
  127. }
  128. /*************************************************************************
  129. Stopjel kuldese, kommunikacio lezarasa ,I2C bus szabadda tetele *************************************************************************/
  130. void i2c_stop(void)
  131. {
  132.  // STOP jel kuldese
  133.  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
  134.  //  varakozas amig a Stop utasitas vegre nem hajtodik es az I2C busz szabad nem lesz
  135.  while(TWCR & (1<<TWSTO));
  136. }  
  137. /*************************************************************************
  138. Egy bajt kuldese az I2C eszkozre
  139. Fuggv. parameter:    byte to be transfered
  140. Fuggv. altal visszaadott ertek: 0 iras sikeres, 1 iras sikertelen *************************************************************************/
  141. unsigned char i2c_write( unsigned char data )
  142. {
  143.   uint8_t   twst;
  144.  //  adat irasa a korabban megcimzett eszkozbe
  145.  TWDR = data;
  146.  TWCR = (1<<TWINT) | (1<<TWEN);
  147.  // varakozas amig az atvitel be nem fejezodik
  148.  while(!(TWCR & (1<<TWINT)));
  149. // TWI Statusz Register ertekenek ellenorzese, elooszto bitek kimaszkolasa.
  150.  twst = TW_STATUS & 0xF8;
  151.  if( twst != TW_MT_DATA_ACK) return 1;
  152.  return 0;
  153. }  
  154. /*************************************************************************
  155. Egy bajt kiolvasasa az I2C eszkozbol, tovabbi adatok kerese
  156. Fuggv. altal visszaadott ertek:  az I2C eszkozbol kiolvasott bajt *************************************************************************/
  157. unsigned char i2c_readAck(void)
  158. {
  159.  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
  160.  while(!(TWCR & (1<<TWINT)));    
  161.       return TWDR;
  162. }  
  163. /*************************************************************************
  164. Egy bajt kiolvasasa az I2C eszkozbol, a kiolvasast Stop bit koveti
  165. Fuggv. altal visszaadott ertek:  az I2C eszkozbol kiolvasott bajt *************************************************************************/
  166. unsigned char i2c_readNak(void)
  167. {
  168.  TWCR = (1<<TWINT) | (1<<TWEN);
  169.  while(!(TWCR & (1<<TWINT)));
  170.     return TWDR;
  171. }  
  172.  
  173.  
  174. int iranymeres()
  175.  {
  176.      unsigned char hi_byte;
  177.      unsigned char lo_byte;
  178.   i2c_init();    // I2C inicializalasa
  179.   i2c_start_wait(HMC6352+I2C_WRITE);  // iranytumodul I2C cim es adatirany (iras) megadasa
  180.   i2c_write('A');        //  iranyszogmeresre utasito parancs
  181.   i2c_stop();         // Stopjel kuldese, I2C busz szabadda tetele
  182.    _delay_ms(10);         // varakozas 10 ms-ig
  183.   i2c_rep_start(HMC6352+I2C_READ);       // ismetelt Start jel (Restart) + adatirany (olvasas)
  184.   hi_byte = i2c_readAck();         // iranyszog beolvasasa az iranytumodulrol(magas bajt)
  185.   lo_byte = i2c_readNak();       //iranyszog beolvasasa az iranytumodulrol(alacsony bajt)
  186.   i2c_stop();   // Stopjel kuldese, I2C bus szabadda tetele
  187.   return  ((hi_byte << 8) | lo_byte);
  188.  }
  189. intmain(void)  // Foprogram
  190. {
  191.  KonfigUART();   // UART Konfiguralasa
  192.  unsigned int H = 0;
  193.  char data;
  194.  while(1)
  195.  {
  196. data = UARTAdatFogad();  // A berekezo bajt fogadasa
  197.  if(data == 'm') // Ha a fogadott bajt a 'm'-mel egyezik meg, megmerjuk az iranyszoget
  198.   {
  199.    H =  iranymeres();
  200.    UARTAdatKuld('0'+(H/1000) % 10);  // Ezresek ertekenek kiirasa
  201.    UARTAdatKuld('0'+(H/100) % 10);  // Szazasok ertekenek kiirasa
  202.    UARTAdatKuld('0'+(H/10) % 10);   // Tizesek ertekenek kiirasa
  203.    UARTAdatKuld('0'+H % 10);    // Egyesek ertekenek kiirasa
  204.    UARTAdatKuld('\n');     // Kovetkezo sor
  205.    UARTAdatKuld('\r');     // Ugras a sor elejere
  206.    _delay_ms(100);         // várakozás 0.1 másodpercig
  207.   }
  208.  }
  209. }


A cikk még nem ért véget, lapozz!
Következő: »»   5 / 9
Értékeléshez bejelentkezés szükséges!
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem