Outils pour utilisateurs

Outils du site


robotics:electronics:shield_arduino_ls7366r

Ceci est une ancienne révision du document !


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.

Entrées / Sorties

A et B : Les sorties A et B du codeur incrémental (idéalement en quadrature de phase) doivent être directement connectées aux entrées A et B du codeurs.

INDEX : L'entrée INDEX est une entrée programmable du compteur. Elle peut être directement reliée à la sortie INDEX du codeur incrémental (si celui-ci en a un) ou alors au microcontrolleur. Cette entrée peut avoir plusieurs fonctionnalités. Elle permet de charger le registre d'entrée ou de sortie ou alors de remettre le compteur à zéro.

FCKO et FCKI : Entrées pour connecter un oscillateur. Pour un filtrage correct des entrées, il faut que Ff > 4fQA avec Ff : fréquence interne de l'ocilateur et fQA : frequence max du signal A en quadrature.

CNT_EN : Permet le comptage quand cette entrée est à 1.

LFLAG et DFLAG : sorties programmables qui permettent d'annoncer un dépassement du compteur ou fonction de comparaison.

MOSI : entrée de la liaison SPI. les données sont reçues sur cette entrée.

MISO : sortie de la liaison SPI. les données sont envoyées sur cette sortie.

SS/ : sélectionne le compteur pour activer la liaison SPI., MOSI : utilisés pour la liaison SPI.

SCK : horloge du signal SPI.

Registres

CNTR : registre qui contient la valeur courante du compteur. Ce registre peut être directement lu mais pour éviter les problèmes de comptage, il est préférable d'utiliser OTR.

OTR : registre de sortie indiquant la valeur de CNTR. Ce registre peut être directement lu via la liaison SPI sans perturber le comptage. Il faut tout d'abord charger CNTR dans OTR (LOAD CNTR) puis lire OTR (READ OTR).

DTR : registre d’entrée qui contient la valeur de chargement de CNTR. La valeur contenue dans DTR peut être transférée dans CNTR logiciellement ou matériellement grâce à un signal sur INDEX.

STR : registre d’information sur l'état du compteur (dépassement et état du compteur, comparaison, direction de comptage et signe de la valeur)

IR : registre interne qui permet de sélectionner le registre et les actions lors des communications SPI.

MDR0 : registre qui configure le mode de quadrature, le mode de comptage et le mode d'indexage.

MDR1 : registre qui configure la taille du compteur et l’utilisation des flags.

Communication

L'horloge SCK générée par le micro permet d'avoir une liaison synchrone entre le micro et le LS7366 utilisé en esclave. Chaque transmission est composée de trames de 1 à 5 octets de données. La longueur des trames est automatiquement ajustée en fonction de la configuration du compteur. Chaque transmission débute par le passage à 0 de la ligne SS/. Elle débute par un octet d'instruction, les octets suivants sont considérés comme des données. La transmission se termine quand SS/ repasse à 1 (ligne au repos). Les données sont reçues sur l'entrée MOSI , le MSB en premier sur un état haut d'horloge. Les données sortantes sont envoyées sur la sortie MISO, le MSB en premier, sur un état bas d'horloge SCK.

Mise en oeuvre

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.

Shéma fonctionnel

Nous utilisons 4 compteur LS7366R et un oscillateur à quartz 40 MHz. Voici le schéma de la la shield LS7366R.

Typon

Pour l'instant, nous avons réaliser la carte avec des composants traditionnels. Il serait interressant de la refaire avec des composants CMS pour réduire sa taille et pouvoir laisser libre les borniers de la shield moteur.

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 vérifier que la valeur inscrite dans le registre MDR0 est correcte test 2 : test comptage sens positif (B=1) Il faut mettre 5V sur l'entrée B du compteur.

test 3 : test comptage sens negatif (B=0) Il faut mettre l'entrée B du compteur à la masse.

/*
 * main.c
 *
 *  Created on: Feb 28, 2012
 *      Author: ldo
 *
 *	Arduino duemilanove 2009
 *	Atmega328P 16MHz
 */

#include<avr/io.h>	/* pour les definitions des registres */
#include <avr/interrupt.h> /* pour les interruptions */

/* SPI port */
#define DDR_SPI DDRB	/* SPI port B */
#define PORT_SPI PORTB
#define DD_SS	2	/* SS/ : PB2 */
#define DD_MOSI 3	/* MOSI : PB3 */
#define DD_MISO	4	/* MISO : PB4*/
#define DD_SCK 5	/* SCK : PB5 */

/* LS7366R opcode list */
#define CLR_CNTR	0x20	/* clear CNTR register to zero */

#define READ_MDR0	0x48	/* read MDR0 */
//#define READ_MDR1
#define READ_CNTR	0x60	/* transfer CNTR to OTR */
//#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 */
	DDRD = 0b11111111; /* PORTD en sortie */
}

void SPI_MasterInit(void)
{
	DDR_SPI = (1 << DD_MOSI) | (1 << DD_SCK) | (1 << DD_SS); /* set MOSI, SCK and SS/ output */
	SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0); /* Enable SPI, Master, set clock rate fck/16 */
}

char SPI_MasterTransmit(char data)
{
	SPDR = data; /* load byte to data register */
	while (!(SPSR & (1 << SPIF)))
		; /* wait for transmission complete */
	data = SPDR; /* load received byte */
	return data;
}

void clr(char op_code)
{
	PORT_SPI |= (1 << DD_SS);
	PORT_SPI &= ~(1 << DD_SS); /* slave select */
	SPI_MasterTransmit(op_code);/* send command */
	PORT_SPI |= (1 << DD_SS); /* slave unselect */
}

void write(char op_code, char data)
{
	PORT_SPI |= (1 << DD_SS);
	PORT_SPI &= ~(1 << DD_SS); /* slave select */
	SPI_MasterTransmit(op_code);/* send command */
	SPI_MasterTransmit(data);/* send command */
	PORT_SPI |= (1 << DD_SS); /* slave unselect */
}

char read(char op_code)
{
	char data;
	PORT_SPI |= (1 << DD_SS);
	PORT_SPI &= ~(1 << DD_SS); /* slave select */
	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)
{
	unsigned int i = 0;

	while (i < 48000)
	{
		asm("nop");
		i++;
	}
}

int main(void)
{
	char data;

	initPort();
	PORTD = 0x00;

	SPI_MasterInit();

	/* configuration du LS7366R */
	write(WRITE_MDR0, CONF_MDR0);
	write(WRITE_MDR1, CONF_MDR1);
	clr(CLR_CNTR);

	while (1)
	{
		/* generation d'une horloge pour simuler l'entrée A du compteur */
		attente(); /* attente 15 ms */
		PORTD ^= (1 << 3); /* inverse PD3 */

		/* lecture du compteur */
		data = read(READ_CNTR);

		/* test communication */
		/*data = read(READ_MDR0);
		 if (data == CONF_MDR0)
		 {
			 PORTD = 0xFF;
		 }*/

		/* test comptage sens positif (B=1) */
		if (data < 50)
		{
			PORTD |= (1 << 2); /* PD2 = 1 */
		}
		else
		{
			PORTD &= ~(1 << 2); /* PD2 = 0 */

			if (data > 100)
			{
				clr(CLR_CNTR);
			}
		}

		/* test comptage sens negatif (B=0) */
		/*	if (data > -50)
		 {
			 PORTD=0xFF;
		 }
		 else
		 {
			 PORTD=0x00;
			 if (data<-100)
			 {
				 clr(CLR_CNTR);
			 }
		 }*/
	}

	return 1;
}
robotics/electronics/shield_arduino_ls7366r.1337787968.txt.gz · Dernière modification: 2012/09/20 10:52 (modification externe)