Commande de robot par FPGA : Différence entre versions
m |
|||
| Ligne 44 : | Ligne 44 : | ||
<br /> | <br /> | ||
On envisage l'implantation de 4 capteurs CNY70 au lieu de 2 vu précédemment dans le projet inter-semestre de 1ere année. | On envisage l'implantation de 4 capteurs CNY70 au lieu de 2 vu précédemment dans le projet inter-semestre de 1ere année. | ||
| − | == | + | ==Programme C== |
| + | <source lang=C> | ||
| + | //#include "stdint.h" | ||
| + | #include "avr/io.h" | ||
| + | //#include "avr/pgmspace.h" | ||
| + | #undef F_CPU | ||
| + | #define F_CPU 25000000UL | ||
| + | #include "util/delay.h" | ||
| + | #define DATAPRESENT 2 | ||
| + | #define PORTA _SFR_IO8(0x1B) | ||
| + | /* | ||
| + | //****************************************************************************************************************************** | ||
| + | // function readFIFOandAskForNextData() | ||
| + | // purpose: read FIFO and put data in array and start the request of next data | ||
| + | // arguments: array of unsigned char to store FIFO data | ||
| + | // | ||
| + | // return: | ||
| + | // note: you cannot understand if you never read the corresponding VHDL code (in io2.vhd) | ||
| + | //****************************************************************************************************************************** | ||
| + | void readFIFOandAskForNextData(unsigned char nunchukDATA[]){ | ||
| + | unsigned char i; | ||
| + | while(!(TWCR & (1<<DATAPRESENT))); // attente données dans le FIFO | ||
| + | for (i=0;i<6;i++) {//lecture du Nunchuk du FIFO dans tableau | ||
| + | nunchukDATA[i]=TWDR; | ||
| + | PORTA=TWDR; | ||
| + | } | ||
| + | // on demande une nouvelle lecture par le pérphérique : toutes données seront pour la prochaine fois | ||
| + | TWCR |= (1<<0); //depart | ||
| + | TWCR &= ~(1<<0);// arret pour attendre la prochaine fois : voir machine d'états pour comprendre | ||
| + | } | ||
| − | == | + | int main() { |
| + | unsigned char data[6]; | ||
| + | while(1) { | ||
| + | readFIFOandAskForNextData(data); | ||
| + | if((data[5] & 0x01) ==0) PORTD =0x90; else PORTD=0x00; | ||
| + | if((data[5] & 0x01) ==0) PORTB =0x90; else PORTB=0x00; | ||
| + | _delay_ms(500); | ||
| + | } | ||
| + | } | ||
| + | */ | ||
| + | void readFIFOandAskForNextData(unsigned char nunchukDATA[]); | ||
| + | void enAvant(unsigned char droite, unsigned char gauche); | ||
| + | void enArriere(unsigned char droite, unsigned char gauche); | ||
| + | void tourneDroite(unsigned char gauche); | ||
| + | void tourneGauche(unsigned char gauche); | ||
| + | |||
| + | int main(int argc, char * argv[]) | ||
| + | { | ||
| + | unsigned char nunchukDATA[6],vitesseDroite,vitesseGauche,avant; | ||
| + | while(1){ | ||
| + | readFIFOandAskForNextData(nunchukDATA); | ||
| + | if (!(nunchukDATA[5] & 1)) {// Z button | ||
| + | /* | ||
| + | if (nunchukDATA[0]>0xC0) tourneDroite(0x55); | ||
| + | else if (nunchukDATA[0]<0x30) tourneGauche(0x55); | ||
| + | else if (nunchukDATA[1]>0xC0) enAvant(0x55,0x55); | ||
| + | else if (nunchukDATA[1]<0x30) enArriere(0x55,0x55); | ||
| + | else enAvant(0x00,0x00); | ||
| + | */ | ||
| + | if (nunchukDATA[1]>0xA0) {vitesseDroite=vitesseGauche=nunchukDATA[1]-0x80; avant=1;} | ||
| + | else if (nunchukDATA[1]<0x60) {vitesseDroite=vitesseGauche=0x80-nunchukDATA[1];avant=0; } | ||
| + | else {vitesseGauche=vitesseDroite=0x00;} | ||
| + | if (nunchukDATA[0]>0xA0) vitesseDroite = vitesseDroite -nunchukDATA[0]+0x80; | ||
| + | else if (nunchukDATA[0]<0x60) vitesseGauche = vitesseGauche + nunchukDATA[0]-0x80; | ||
| + | if (avant) enAvant(vitesseGauche,vitesseDroite); else enArriere(vitesseGauche,vitesseDroite); | ||
| + | } else if (!(nunchukDATA[5] & 2)) {// C button | ||
| + | if (nunchukDATA[2]>0xB0) tourneDroite(0x55); | ||
| + | else if (nunchukDATA[2]<0x55) tourneGauche(0x55); | ||
| + | else if (nunchukDATA[3]>0x90) enAvant(0x55,0x55); | ||
| + | else if (nunchukDATA[3]<0x80) enArriere(0x55,0x55); | ||
| + | else enAvant(0x00,0x00); | ||
| + | } | ||
| + | else enAvant(0x00,0x00); | ||
| + | PORTA = vitesseGauche; | ||
| + | _delay_ms(100); | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | } | ||
| + | return 0; | ||
| + | } | ||
| + | |||
| + | /* | ||
| + | int main(int argc, char * argv[]) | ||
| + | { | ||
| + | unsigned char nb; | ||
| + | while(1){ // boucle de 1/10 s | ||
| + | nb++; | ||
| + | // Reset compteur | ||
| + | DDRB |= 0x80; | ||
| + | DDRB &= 0x7F; // c'est arti | ||
| + | if (nb == 9) { // environ 1s | ||
| + | PORTD = PIND; // affichage compteur sur LEDs | ||
| + | nb = 0; | ||
| + | } // if | ||
| + | _delay_ms(100); | ||
| + | } | ||
| + | return 0; | ||
| + | } | ||
| + | |||
| + | */ | ||
| + | |||
| + | //****************************************************************************************************************************** | ||
| + | // function readFIFOandAskForNextData() | ||
| + | // purpose: read FIFO and put data in array and start the request of next data | ||
| + | // arguments: array of unsigned char to store FIFO data | ||
| + | // | ||
| + | // return: nothing | ||
| + | // note: you cannot understand if you never read the corresponding VHDL code (in iotimer.vhd) | ||
| + | //****************************************************************************************************************************** | ||
| + | void readFIFOandAskForNextData(unsigned char nunchukDATA[]){ | ||
| + | unsigned char i; | ||
| + | while(!(TWCR & (1<<DATAPRESENT))); // attente données dans le FIFO | ||
| + | for (i=0;i<6;i++) {//lecture du Nunchuk du FIFO dans tableau | ||
| + | nunchukDATA[i]=TWDR; | ||
| + | //PORTA=TWDR; | ||
| + | } | ||
| + | // on demande une nouvelle lecture par le pérphérique : toutes données seront pour la prochaine fois | ||
| + | TWCR |= (1<<0); //depart | ||
| + | TWCR &= ~(1<<0);// arret pour attendre la prochaine fois : voir machine d'états pour comprendre | ||
| + | } | ||
| + | |||
| + | //****************************************************************************************************************************** | ||
| + | // function enAvant() | ||
| + | // purpose: goAhead | ||
| + | // arguments: left and right speed | ||
| + | // | ||
| + | // return: nothing | ||
| + | // note: you cannot understand if you never read the corresponding VHDL code (in iotimer.vhd) | ||
| + | //****************************************************************************************************************************** | ||
| + | void enAvant(unsigned char droite, unsigned char gauche) { | ||
| + | // par sécurité toute fonction commence par l'arrêt des moteurs | ||
| + | PORTD = 0x00; | ||
| + | PORTB = 0x00; | ||
| + | _delay_ms(10); | ||
| + | // les deux moteurs en marche avant | ||
| + | // choix de la direction : en avant : voir code iotimer.vhd | ||
| + | PORTC = 0x02; | ||
| + | PORTD = droite; | ||
| + | PORTB = gauche; | ||
| + | } | ||
| + | |||
| + | //****************************************************************************************************************************** | ||
| + | // function enArriere() | ||
| + | // purpose: goBack | ||
| + | // arguments: left and right speed | ||
| + | // | ||
| + | // return: nothing | ||
| + | // note: you cannot understand if you never read the corresponding VHDL code (in iotimer.vhd) | ||
| + | //****************************************************************************************************************************** | ||
| + | void enArriere(unsigned char droite, unsigned char gauche) { | ||
| + | // par sécurité toute fonction commence par l'arrêt des moteurs | ||
| + | PORTD = 0x00; | ||
| + | PORTB = 0x00; | ||
| + | _delay_ms(10); | ||
| + | // les deux moteurs en marche arriere | ||
| + | // choix de la direction : en avant : voir code iotimer.vhd | ||
| + | PORTC = 0x01; | ||
| + | PORTD = droite; | ||
| + | PORTB = gauche; | ||
| + | } | ||
| + | |||
| + | //****************************************************************************************************************************** | ||
| + | // function TourneDroite() | ||
| + | // purpose: turn on the right | ||
| + | // arguments: left speed (right speed is zero) | ||
| + | // | ||
| + | // return: nothing | ||
| + | // note: you cannot understand if you never read the corresponding VHDL code (in iotimer.vhd) | ||
| + | //****************************************************************************************************************************** | ||
| + | void tourneDroite(unsigned char gauche) { | ||
| + | // par sécurité toute fonction commence par l'arrêt des moteurs | ||
| + | PORTD = 0x00; | ||
| + | PORTB = 0x00; | ||
| + | _delay_ms(10); | ||
| + | // les deux moteurs en marche avant | ||
| + | // choix de la direction : en avant : voir code iotimer.vhd | ||
| + | PORTC = 0x02; | ||
| + | PORTB = gauche; | ||
| + | } | ||
| + | |||
| + | //****************************************************************************************************************************** | ||
| + | // function tourneGauche() | ||
| + | // purpose: turn on the left | ||
| + | // arguments: right speed (left speed is zero) | ||
| + | // | ||
| + | // return: nothing | ||
| + | // note: you cannot understand if you never read the corresponding VHDL code (in iotimer.vhd) | ||
| + | //****************************************************************************************************************************** | ||
| + | void tourneGauche(unsigned char droite) { | ||
| + | // par sécurité toute fonction commence par l'arrêt des moteurs | ||
| + | PORTD = 0x00; | ||
| + | PORTB = 0x00; | ||
| + | _delay_ms(10); | ||
| + | // les deux moteurs en marche avant | ||
| + | // choix de la direction : en avant : voir code iotimer.vhd | ||
| + | PORTC = 0x02; | ||
| + | PORTD = droite; | ||
| + | } | ||
| + | |||
| + | </source> | ||
Version du 21 mars 2014 à 09:53
Sommaire
Présentation du robot arexx
Information sur la Basys 2
La Basys2 est une carte FPGA conçue par Digilent. Elle permet la simulation de vrais circuits numériques. La programmation de circuits numériques se fait à l'aide du logiciel XilinX. Grâce à sa grande collection de périphériques d'entrées et de sorties, on peut simuler une grande gamme de circuits numériques.
Caractéristiques :
-Xilinx Spartan 3-E FPGA 100k ou 250k portes;
-72Kbits de RAM et fréquence de transfert de 500MHz;
-2 ports USB 2.0 pour les transferts de configurations et de données;
-Fréquence de l'oscillateur (25,50 et 100MHz) réglable par l'utilisateur;
-Trois régulateurs de tension intégrés (1,2V, 2,5V, 3,3V) permettent l'utilisation
des sources d'alimentations externes 3.5V-5.5V;
-8 LED, 4 Afficheurs sept segments, 4 boutons poussoirs,
8 interrupteurs à glissière, 1 ports PS/2 et 1 port VGA-8bits;
Lien : User Guide Basys2
Carte capteur à photo-transistors
Le CNY70 est un capteur à réflexion optique c'est à dire qu'il est composé d'un photo-transistor filtrant la lumière visible et d'une diode infrarouge. Il permet de détecter un contraste noir-blanc à faible distance (inférieur à 5mm).
On envisage l'implantation de 4 capteurs CNY70 au lieu de 2 vu précédemment dans le projet inter-semestre de 1ere année.
Programme C
//#include "stdint.h"
#include "avr/io.h"
//#include "avr/pgmspace.h"
#undef F_CPU
#define F_CPU 25000000UL
#include "util/delay.h"
#define DATAPRESENT 2
#define PORTA _SFR_IO8(0x1B)
/*
//******************************************************************************************************************************
// function readFIFOandAskForNextData()
// purpose: read FIFO and put data in array and start the request of next data
// arguments: array of unsigned char to store FIFO data
//
// return:
// note: you cannot understand if you never read the corresponding VHDL code (in io2.vhd)
//******************************************************************************************************************************
void readFIFOandAskForNextData(unsigned char nunchukDATA[]){
unsigned char i;
while(!(TWCR & (1<<DATAPRESENT))); // attente données dans le FIFO
for (i=0;i<6;i++) {//lecture du Nunchuk du FIFO dans tableau
nunchukDATA[i]=TWDR;
PORTA=TWDR;
}
// on demande une nouvelle lecture par le pérphérique : toutes données seront pour la prochaine fois
TWCR |= (1<<0); //depart
TWCR &= ~(1<<0);// arret pour attendre la prochaine fois : voir machine d'états pour comprendre
}
int main() {
unsigned char data[6];
while(1) {
readFIFOandAskForNextData(data);
if((data[5] & 0x01) ==0) PORTD =0x90; else PORTD=0x00;
if((data[5] & 0x01) ==0) PORTB =0x90; else PORTB=0x00;
_delay_ms(500);
}
}
*/
void readFIFOandAskForNextData(unsigned char nunchukDATA[]);
void enAvant(unsigned char droite, unsigned char gauche);
void enArriere(unsigned char droite, unsigned char gauche);
void tourneDroite(unsigned char gauche);
void tourneGauche(unsigned char gauche);
int main(int argc, char * argv[])
{
unsigned char nunchukDATA[6],vitesseDroite,vitesseGauche,avant;
while(1){
readFIFOandAskForNextData(nunchukDATA);
if (!(nunchukDATA[5] & 1)) {// Z button
/*
if (nunchukDATA[0]>0xC0) tourneDroite(0x55);
else if (nunchukDATA[0]<0x30) tourneGauche(0x55);
else if (nunchukDATA[1]>0xC0) enAvant(0x55,0x55);
else if (nunchukDATA[1]<0x30) enArriere(0x55,0x55);
else enAvant(0x00,0x00);
*/
if (nunchukDATA[1]>0xA0) {vitesseDroite=vitesseGauche=nunchukDATA[1]-0x80; avant=1;}
else if (nunchukDATA[1]<0x60) {vitesseDroite=vitesseGauche=0x80-nunchukDATA[1];avant=0; }
else {vitesseGauche=vitesseDroite=0x00;}
if (nunchukDATA[0]>0xA0) vitesseDroite = vitesseDroite -nunchukDATA[0]+0x80;
else if (nunchukDATA[0]<0x60) vitesseGauche = vitesseGauche + nunchukDATA[0]-0x80;
if (avant) enAvant(vitesseGauche,vitesseDroite); else enArriere(vitesseGauche,vitesseDroite);
} else if (!(nunchukDATA[5] & 2)) {// C button
if (nunchukDATA[2]>0xB0) tourneDroite(0x55);
else if (nunchukDATA[2]<0x55) tourneGauche(0x55);
else if (nunchukDATA[3]>0x90) enAvant(0x55,0x55);
else if (nunchukDATA[3]<0x80) enArriere(0x55,0x55);
else enAvant(0x00,0x00);
}
else enAvant(0x00,0x00);
PORTA = vitesseGauche;
_delay_ms(100);
}
return 0;
}
/*
int main(int argc, char * argv[])
{
unsigned char nb;
while(1){ // boucle de 1/10 s
nb++;
// Reset compteur
DDRB |= 0x80;
DDRB &= 0x7F; // c'est arti
if (nb == 9) { // environ 1s
PORTD = PIND; // affichage compteur sur LEDs
nb = 0;
} // if
_delay_ms(100);
}
return 0;
}
*/
//******************************************************************************************************************************
// function readFIFOandAskForNextData()
// purpose: read FIFO and put data in array and start the request of next data
// arguments: array of unsigned char to store FIFO data
//
// return: nothing
// note: you cannot understand if you never read the corresponding VHDL code (in iotimer.vhd)
//******************************************************************************************************************************
void readFIFOandAskForNextData(unsigned char nunchukDATA[]){
unsigned char i;
while(!(TWCR & (1<<DATAPRESENT))); // attente données dans le FIFO
for (i=0;i<6;i++) {//lecture du Nunchuk du FIFO dans tableau
nunchukDATA[i]=TWDR;
//PORTA=TWDR;
}
// on demande une nouvelle lecture par le pérphérique : toutes données seront pour la prochaine fois
TWCR |= (1<<0); //depart
TWCR &= ~(1<<0);// arret pour attendre la prochaine fois : voir machine d'états pour comprendre
}
//******************************************************************************************************************************
// function enAvant()
// purpose: goAhead
// arguments: left and right speed
//
// return: nothing
// note: you cannot understand if you never read the corresponding VHDL code (in iotimer.vhd)
//******************************************************************************************************************************
void enAvant(unsigned char droite, unsigned char gauche) {
// par sécurité toute fonction commence par l'arrêt des moteurs
PORTD = 0x00;
PORTB = 0x00;
_delay_ms(10);
// les deux moteurs en marche avant
// choix de la direction : en avant : voir code iotimer.vhd
PORTC = 0x02;
PORTD = droite;
PORTB = gauche;
}
//******************************************************************************************************************************
// function enArriere()
// purpose: goBack
// arguments: left and right speed
//
// return: nothing
// note: you cannot understand if you never read the corresponding VHDL code (in iotimer.vhd)
//******************************************************************************************************************************
void enArriere(unsigned char droite, unsigned char gauche) {
// par sécurité toute fonction commence par l'arrêt des moteurs
PORTD = 0x00;
PORTB = 0x00;
_delay_ms(10);
// les deux moteurs en marche arriere
// choix de la direction : en avant : voir code iotimer.vhd
PORTC = 0x01;
PORTD = droite;
PORTB = gauche;
}
//******************************************************************************************************************************
// function TourneDroite()
// purpose: turn on the right
// arguments: left speed (right speed is zero)
//
// return: nothing
// note: you cannot understand if you never read the corresponding VHDL code (in iotimer.vhd)
//******************************************************************************************************************************
void tourneDroite(unsigned char gauche) {
// par sécurité toute fonction commence par l'arrêt des moteurs
PORTD = 0x00;
PORTB = 0x00;
_delay_ms(10);
// les deux moteurs en marche avant
// choix de la direction : en avant : voir code iotimer.vhd
PORTC = 0x02;
PORTB = gauche;
}
//******************************************************************************************************************************
// function tourneGauche()
// purpose: turn on the left
// arguments: right speed (left speed is zero)
//
// return: nothing
// note: you cannot understand if you never read the corresponding VHDL code (in iotimer.vhd)
//******************************************************************************************************************************
void tourneGauche(unsigned char droite) {
// par sécurité toute fonction commence par l'arrêt des moteurs
PORTD = 0x00;
PORTB = 0x00;
_delay_ms(10);
// les deux moteurs en marche avant
// choix de la direction : en avant : voir code iotimer.vhd
PORTC = 0x02;
PORTD = droite;
}
