Outils pour utilisateurs

Outils du site


robotics:electronics:shield_arduino_ls7366r

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:electronics:shield_arduino_ls7366r [2012/05/23 17:51]
ldo [Typon]
robotics:electronics:shield_arduino_ls7366r [2014/10/03 14:38] (Version actuelle)
gdo [Typon]
Ligne 1: Ligne 1:
 ====== Présentation des LS7366R ====== ====== Présentation des LS7366R ======
  
-Le LS7366R est un compteur 32 bits spécialisé pour les horloges en quadrature (type codeur incrémentaux). Il peut être configuré en compteur 1, 2 3 ou 4 octets. Il dispose également d'une entrée index. Il communique avec un microcontrolleur via une liaison SPI.+Le [[http://​www.lsicsi.com/​pdfs/​Data_Sheets/​LS7366R.pdf|LS7366R]] ​est un compteur 32 bits spécialisé pour les horloges en quadrature (type codeur incrémentaux). Il peut être configuré en compteur 1, 2 3 ou 4 octets. Il dispose également d'une entrée index. Il communique avec un microcontrolleur via une liaison SPI.
  
 ===== Entrées / Sorties ===== ===== Entrées / Sorties =====
Ligne 50: Ligne 50:
  
 Nous réalisons un robot avec deux moteurs à courant continu que nous voulons asservir. Les moteurs ont chacun un codeur incrémental en quadrature (sortie A et B) et nous souhaitons également mettre deux roues codeuses indépendantes. Cela fait donc 4 codeurs à traiter. ​ Nous réalisons un robot avec deux moteurs à courant continu que nous voulons asservir. Les moteurs ont chacun un codeur incrémental en quadrature (sortie A et B) et nous souhaitons également mettre deux roues codeuses indépendantes. Cela fait donc 4 codeurs à traiter. ​
-Pour cela, nous utilisons une carte ARDUINO UNO et une shield moteur ARDUINO pour le contrôle des moteurs (2 x 2A basée sur un L298). Sur le principe des shield ARDUINO, nous avons donc fait une carte avec les 4 compteurs LS7366R communiquant via la liaison SPI.+Pour cela, nous utilisons une carte [[http://​arduino.cc/​en/​Main/​arduinoBoardUno|ARDUINO UNO]] et une [[http://​www.dfrobot.com/​wiki/​index.php?​title=Arduino_Motor_Shield_%28L298N%29_%28SKU:​DRI0009%29|shield moteur ARDUINO]] pour le contrôle des moteurs (2 x 2A basée sur un [[http://​www.st.com/​internet/​com/​TECHNICAL_RESOURCES/​TECHNICAL_LITERATURE/​DATASHEET/​CD00000240.pdf|L298]]). Sur le principe des shield ARDUINO, nous avons donc fait une carte avec les 4 compteurs LS7366R communiquant via la liaison SPI.
  
 ===== Shéma fonctionnel ===== ===== Shéma fonctionnel =====
Ligne 61: Ligne 61:
  
 {{:​robotics:​electronics:​typon.jpg|}} {{:​robotics:​electronics:​typon.jpg|}}
-====== Test ====== 
-Dans un premier temps, nous avons fait un petit programme de test pour communiquer avec le compteur. Nous avons utiliser une Arduino uno (ou duemilanove 2009). 
-Nous générons une horloge sur la sortie PD3 (30 Hz) à mettre sur l'​entrée A du compteur. ​ 
-MDR0 = 0x00 non quadrature count mode (horloge sur A et direction sur B) 
-MDR1 = 0x03 : comptage sur 1 octet 
  
-test 1 : test communication avec le LS7366 +Vous pouvez télécharger ​le typon au format Kicad ici : {{:​robotics:​electronics:​counter_shield.kicad_pcb.zip|}} 
-vérifier que la valeur inscrite dans le registre ​MDR0 est correcte +====== Implementation ====== 
-test 2 : test comptage sens positif ​(B=1) +===== Fonctions de base ===== 
-Il faut mettre ​5V sur l'​entrée ​du compteur.+Nous avons écrite quelques fonctions de base pour le compteur. Ces fonctions permettent de lire et d'​écrire dans les registres de configuration et compteur. 
 +<code c> 
 + 
 +/* LS7366R opcode list */ 
 +#define CLR_CNTR 0x20 /​* clear CNTR register to zero */ 
 + 
 +#define READ_MDR0 0x48 /​* read MDR0 */ 
 +#define READ_MDR1 ​      ​0x50 ​   /* read MDR1 */ 
 +#define READ_CNTR 0x60 /​* transfer CNTR to OTR */ 
 + 
 +#define WRITE_MDR0 0x88 /​* write serial data into MDR0 */ 
 +#define WRITE_MDR1 0x90 /​* write serial data into MDR1 */ 
 + 
 +/* configuration MDRO */ 
 +#define NON_QUADRATURE ​ 0x00    /* non-quadrature count mode */ 
 +#define X1_QUADRATURE ​  ​0x01 ​   /* x1 quadrature count mode */ 
 + 
 +/* configuration MDR1 */ 
 +#define _1_BYTE 0x03 /​* 1-byte counter mode */ 
 + 
 + 
 +/* remise a zero du compteur */ 
 +void 
 +clr(char op_code) 
 +
 +  PORT_SPI |(<< DD_SS); 
 +  ​PORT_SPI &= ~(1 << DD_SS); /* slave select */ 
 +  SPI_master_transmit(op_code);/​* send command */ 
 +  PORT_SPI |= (1 << DD_SS); /* slave unselect */ 
 +
 + 
 +/* ecriture (envoi d'une commande) */ 
 +void 
 +write(char op_code, char data) 
 +
 +  PORT_SPI |= (1 << DD_SS); 
 +  PORT_SPI &= ~(1 << DD_SS); /* slave select */ 
 +  SPI_master_transmit(op_code);/​* send command */ 
 +  SPI_master_transmit(data);/​* send command */ 
 +  PORT_SPI |= (1 << DD_SS); /* slave unselect */ 
 +
 + 
 +/* lecture */ 
 +char 
 +read(char op_code) 
 +
 +  char data; 
 +  PORT_SPI |= (1 << DD_SS); 
 +  PORT_SPI &= ~(1 << DD_SS); /* slave select */ 
 +  data = SPI_master_transmit(op_code);/​* send command */ 
 +  data = SPI_master_transmit(0x00);/​* start dummy transmission to read data from LS7366R */ 
 +  PORT_SPI |= (1 << DD_SS); /* slave unselect */ 
 +  return data; 
 +
 + 
 +</​code>​ 
 + 
 +===== Tests ===== 
 +==== Mode compteur ==== 
 +Dans un premier temps, nous avons fait un petit programme de test pour tester le mode compteur. Nous avons utilisé une ARDUINO UNO (ou duemilanove 2009) et un compteur LS7366R. \\ 
 +Nous générons une horloge sur la sortie PD5 (30 Hz) à mettre sur l'​entrée ​du compteur. ​\\ 
 +MDR0 = 0x00 non quadrature count mode (horloge sur A et direction sur B) \\ 
 +MDR1 = 0x03 : comptage sur 1 octet
  
-test 3 : test comptage sens negatif ​(B=0) +  * test 1 : test communication avec le LS7366R. Vérifier que la valeur inscrite dans le registre MDR1 est correcte 
-Il faut mettre l'​entrée B du compteur à la masse.+  * test 2 : test comptage sens positif (B=1). Il faut mettre 5V sur l'​entrée B du compteur. 
 +  * test 3 : test comptage sens négatif ​(B=0)Il faut mettre l'​entrée B du compteur à la masse.
  
-<​code>​+<​code ​c>
 /* /*
  * main.c  * main.c
Ligne 82: Ligne 140:
  ​* ​     Author: ldo  ​* ​     Author: ldo
  *  *
- ​* Arduino duemilanove 2009+ ​* Arduino duemilanove 2009 ou ARDUINO UNO
  ​* Atmega328P 16MHz  ​* Atmega328P 16MHz
  */  */
  
-#​include<​avr/​io.h>​ /​* pour les definitions des registres */+#include <​avr/​io.h>​ /​* pour les definitions des registres */
 #include <​avr/​interrupt.h>​ /* pour les interruptions */ #include <​avr/​interrupt.h>​ /* pour les interruptions */
 +#include <​avr/​delay.h>​
 +
 +#include "​spi.h"​
  
 /* SPI port */ /* SPI port */
-#define DDR_SPI DDRB /* SPI port B */+#define DDR_SPI DDRB /* SPI on port B */
 #define PORT_SPI PORTB #define PORT_SPI PORTB
-#define DD_SS 2 /* SS/ : PB2 */+#define DD_SS 1 /* SS/ : PB1 */
 #define DD_MOSI 3 /* MOSI : PB3 */ #define DD_MOSI 3 /* MOSI : PB3 */
 #define DD_MISO 4 /​* MISO : PB4*/ #define DD_MISO 4 /​* MISO : PB4*/
 #define DD_SCK 5 /* SCK : PB5 */ #define DD_SCK 5 /* SCK : PB5 */
  
-/* LS7366R opcode list */ 
-#define CLR_CNTR 0x20 /​* clear CNTR register to zero */ 
  
-#define READ_MDR0 0x48 /* read MDR0 */ +/* generation d'une horloge pour simuler l'​entrée A du compteur ​*/ 
-//#define READ_MDR1 +void 
-#define READ_CNTR 0x60 /​* transfer CNTR to OTR */ +generation_horloge(void)
-//#define READ_OTR 0x68 +
- +
-#define WRITE_MDR0 0x88 /​* write serial data into MDR0 */ +
-#define WRITE_MDR1 0x90 /​* write serial data into MDR1 */ +
- +
-//#define LOAD_OTR 0xE4 /​* load CNTR to OTR in "​parallel"​ */ +
- +
-#define CONF_MDR0 0x00 /​* non-quadrature count mode */ +
-#define CONF_MDR1 0x03 /​* 1-byte counter mode */ +
- +
-void initPort(void)+
 { {
- /* configuration des ports : '​1'​ pour sortie ​*/ +  _delay_ms(15); ​/* attente 15 ms */ 
- DDRD 0b11111111; /* PORTD en sortie ​*/+  PORTD ^(1 << 5); /* inverse PD5 */
 } }
  
-void SPI_MasterInit(void)+/* test communication */ 
 +void 
 +test_communication(char data)
 { {
- DDR_SPI ​= (1 << DD_MOSI(1 << DD_SCK) | (1 << ​DD_SS); /* set MOSI, SCK and SSoutput */ +  data read(READ_MDR1)
- SPCR (<< SPE) | (1 << MSTR) | (1 << SPR0); /* Enable SPI, Master, set clock rate fck/16 */+  if (data == _1_BYTE) 
 +    { 
 +      PORTD |(1 << ​4); // PD4 = 1 
 +    }
 } }
  
-char SPI_MasterTransmit(char data)+/* test comptage sens positif ​(B=1) */ 
 +void 
 +test_comptage_positif(signed ​char data)
 { {
- SPDR = data; /* load byte to data register */ +  if (data > 100) 
- while (!(SPSR & (1 << ​SPIF))) +    { 
- ; /* wait for transmission complete *+      PORTD |= (1 << ​4); // PD4 = 1 
- data SPDR; /* load received byte *+    } 
- return data;+  else 
 +    { 
 +      PORTD &~(1 << 4); // PD4 = 0 
 +    }
 } }
  
-void clr(char op_code)+/* test comptage sens negatif (B=0) */ 
 +void 
 +test_comptage_negatif(signed ​char data)
 { {
- PORT_SPI |= (<< DD_SS); +  if (data -100
- PORT_SPI &~(1 << ​DD_SS); /* slave select *+    { 
- SPI_MasterTransmit(op_code);/​* send command */ +      PORTD |= (1 << ​4); // PD4 = 1 
- PORT_SPI |= (1 << ​DD_SS); /* slave unselect */+    } 
 +  ​else 
 +    { 
 +      PORTD &~(1 << ​4); // PD4 = 0 
 +    }
 } }
  
-void write(char op_code, char data)+void 
 +init_port(void)
 { {
- PORT_SPI |= (1 << DD_SS); +  ​/* configuration des ports : '​1'​ pour sortie ​*/ 
- PORT_SPI &= ~(1 << DD_SS); ​/* slave select ​*/ +  DDRB = 0xFF /* PORTB en sortie ​*/ 
- SPI_MasterTransmit(op_code);/* send command ​*/ +  PORTB = 0x00; 
- SPI_MasterTransmit(data);/* send command ​*/ +  DDRD = 0xFF; /* PORTD en sortie ​*/ 
- PORT_SPI |(1 << DD_SS)/* slave unselect */+  ​PORTD ​0x00;
 } }
  
-char read(char op_code)+void  
 +init(void)
 { {
- char data; +  init_port(); 
- PORT_SPI |= (1 << DD_SS); +  ​SPI_master_init(); 
- PORT_SPI &= ~(1 << DD_SS); /* slave select */ +  ​_delay_ms(100);
- data = SPI_MasterTransmit(op_code);/* send command */ +
- data = SPI_MasterTransmit(0x00);/​* start dummy transmission to read data from LS7366R */ +
- PORT_SPI |= (1 << DD_SS); /* slave unselect */ +
- return data;+
 } }
  
-void attente(void)+int 
 +main(void)
 { {
- unsigned int i = 0;+  signed char data;
  
- while ​(i < 48000) +  init();
-+
- asm("​nop"​);​ +
- i++; +
-+
-}+
  
-int main(void+  // configuration du LS7366R 
-{ +  write(WRITE_MDR0, NON_QUADRATURE); 
- char data;+  ​write(WRITE_MDR1,​ _1_BYTE); 
 +  ​clr(CLR_CNTR);
  
- initPort(); +  while (1
- PORTD 0x00;+    { 
 +      /* lecture du compteur */ 
 +      data read(READ_CNTR);
  
- SPI_MasterInit();+      test_communication(data); 
 +      //​test_comptage_positif(data);​ 
 +      //​test_comptage_negatif(data);​ 
 +    }
  
- /* configuration du LS7366R */ +  return 1
- write(WRITE_MDR0,​ CONF_MDR0)+} 
- write(WRITE_MDR1,​ CONF_MDR1); +</​code>​
- clr(CLR_CNTR);​+
  
- while (1) +==== Mode quadrature ==== 
- +Nous avons fait un petit programme ​pour tester le mode quadrature x1. Les sorties ​et B du codeur sont reliées aux entrées A et B du compteur. Nous comptons toujours sur octet.
- /* generation d'une horloge ​pour simuler l'​entrée ​A du compteur ​*/ +
- attente();​ /* attente 15 ms */ +
- PORTD ^= (<< 3); /* inverse PD3 */+
  
- /* lecture du compteur *+<code c> 
- data read(READ_CNTR);+void 
 +test_quadrature_x1(signed char data) 
 +
 +  if (data > 0) 
 +    { 
 +      PORTD |= (1 << 4); // PD4 = 1 
 +    } 
 +  else 
 +    { 
 +      PORTD &~(1 << 4); // PD4 = 0 
 +    } 
 +}
  
- /* test communication */ +int 
- /*data = read(READ_MDR0); +main(void
- if (data == CONF_MDR0) +
-  +  ​signed char data;
- PORTD = 0xFF; +
- }*/+
  
- /* test comptage sens positif ​(B=1) */ +  init();
- if (data < 50) +
-+
- PORTD |= (1 << 2); /* PD2 = 1 */ +
-+
- else +
-+
- PORTD &= ~(1 << 2); /* PD2 = 0 */+
  
- if (data > 100+  // configuration du LS7366R 
- { +  write(WRITE_MDR0, X1_QUADRATURE); 
- clr(CLR_CNTR);​ +  ​write(WRITE_MDR1,​ _1_BYTE); 
-+  clr(CLR_CNTR);​
- }+
  
- /* test comptage sens negatif ​(B=0) */ +  while (1) 
- /* if (data > -50) +    { 
-+      /* lecture du compteur ​*/ 
- PORTD=0xFF; +      data = read(READ_CNTR);
-+
- else +
-+
- PORTD=0x00;​ +
- if (data<​-100) +
-+
- clr(CLR_CNTR); +
-+
- }*/ +
- }+
  
- return 1;+      test_quadrature_x1(data);​ 
 +    } 
 + 
 +  ​return 1;
 } }
 +
 </​code>​ </​code>​
robotics/electronics/shield_arduino_ls7366r.1337788291.txt.gz · Dernière modification: 2012/09/20 10:52 (modification externe)