Programme de pic

Programme de pic - C - Programmation

Marsh Posté le 13-03-2005 à 18:29:48    

Bonjour je travaille sur un robot pour mes ppe, voici le programme d'origine en .c qui est programmé dans le µc d'origine.
 
/*
 LINE_OV.C (NLINE3.C) for old version IAR compiler.
 Warning   : This program source must not be opened to any media.
             This will be used for only personal purpose.
 Copyright : Microrobot Co.,Ltd
 Program : James Jeong
*/
 
#include <io51.h>
 
#define RIGHT_M        P1.7
#define LEFT_M         P1.6
 
#define LEFT_LED       P3.7
#define RIGHT_LED      P3.5
#define CENTER_LED     P3.3
 
#define SENSOR         P3.6
 
#define L_IR           P1.5
#define C_IR           P1.4
#define R_IR           P1.3
 
#define BUZZER         P3.2
#define JMP_SW         P3.4
 
#define ON             0
#define OFF            1
 
#define STOP           0
#define LEFT_SMALL     1
#define LEFT           2
#define GO             3
#define RIGHT          4
#define RIGHT_SMALL    5
#define FIND           5
 
bit l,c,r;
unsigned char mode;
 
void delay_15us( void )                 /* 15.25 us */
{
     data unsigned char i;
     for(i=3 ; i>0; i--);
}
 
void delay_50us( void )                 /* 51 us */
{
     data unsigned char i;
     for(i=14 ; i>0; i--);
}
 
void delay_100us( void )                /* 99.84 us */
{
     data unsigned char i;
     for(i=29 ; i>0; i--);
}
 
void delay_200us( void )                /* 200 us */
{
     data unsigned char i;
     for(i=59 ; i>0; i--);
}
 
void delay_400us( void )                /* 400 us */
{
     data unsigned char i;
     for(i=121 ; i>0; i--);
}
 
void delay( unsigned int i )
{
     for( ; i>0; i--);
}
 
void start_sign(void)
{
    unsigned char i;
    LEFT_LED=ON;
    for(i=0; i<50; i++)
    {
        BUZZER=ON;
        delay(150);
        BUZZER=OFF;
        delay(150);
    }
    LEFT_LED=OFF;
    RIGHT_LED=ON;
    for(i=0; i<100; i++)
    {
        BUZZER=ON;
        delay(100);
        BUZZER=OFF;
        delay(100);
    }
    RIGHT_LED=OFF;
    CENTER_LED=ON;
    for(i=0; i<150; i++)
    {
        delay(100);
        delay(100);
    }
    CENTER_LED=OFF;
}
 
void normal_speed(void)
{
 
    L_IR=ON;
    delay_15us();
    L_IR=OFF;
    l=SENSOR;            /* read left sensor */
 
    delay_400us();
 
    C_IR=ON;
    delay_15us();
    C_IR=OFF;
    c=SENSOR;            /* read center sensor */
 
    switch(mode)
    {
        case STOP        : LEFT_M = OFF; RIGHT_M = OFF; break;
        case LEFT_SMALL  : LEFT_M = ON ; RIGHT_M = OFF; break;
        case LEFT        : LEFT_M = OFF; RIGHT_M = OFF; break;
        case GO          : LEFT_M = OFF; RIGHT_M = ON; break;
        case RIGHT       : LEFT_M = OFF; RIGHT_M = OFF; break;
        case RIGHT_SMALL : LEFT_M = OFF; RIGHT_M = ON ; break;
    }
 
    delay_200us();
 
    switch(mode)
    {
        case STOP        : LEFT_M = OFF; RIGHT_M = OFF; break;
        case LEFT_SMALL  : LEFT_M = OFF; RIGHT_M = ON ; break;
        case LEFT        : LEFT_M = OFF; RIGHT_M = OFF; break;
        case GO          : LEFT_M = OFF; RIGHT_M = ON; break;
        case RIGHT       : LEFT_M = OFF; RIGHT_M = OFF; break;
        case RIGHT_SMALL : LEFT_M = ON ; RIGHT_M = OFF; break;
    }
 
    delay_200us();
 
    R_IR=ON;
    delay_15us();
    R_IR=OFF;
    r=SENSOR;            /* read right sensor */
 
    if(c)
    {
        if(l)
        {
            if(r)
            {
                if(mode != STOP) mode=GO;
            }
            else mode=LEFT_SMALL;
        }
        else if(r) mode=RIGHT_SMALL;
        else mode=GO;
    }
    else
    {
        if(l) mode=LEFT;
        else if(r) mode=RIGHT;
        else                           /* FIND MODE */
        {
            if(mode < 3) mode=LEFT;
            else if(mode >3) mode=RIGHT;
        }
    }
 
    switch(mode)
    {
        case STOP        : LEFT_M = OFF; RIGHT_M = OFF; break;
        case LEFT_SMALL  : LEFT_M = OFF; RIGHT_M = ON ; break;
        case LEFT        : LEFT_M = OFF; RIGHT_M = ON ; break;
        case GO          : LEFT_M = ON ; RIGHT_M = OFF; break;
        case RIGHT       : LEFT_M = ON ; RIGHT_M = OFF; break;
        case RIGHT_SMALL : LEFT_M = ON ; RIGHT_M = OFF; break;
    }
 
    LEFT_LED=!l; CENTER_LED=!c; RIGHT_LED=!r;
 
    delay_200us();
 
    switch(mode)
    {
        case STOP        : LEFT_M = OFF; RIGHT_M = OFF; break;
        case LEFT_SMALL  : LEFT_M = OFF; RIGHT_M = OFF; break;
        case LEFT        : LEFT_M = OFF; RIGHT_M = OFF; break;
        case GO          : LEFT_M = OFF; RIGHT_M = ON ; break;
        case RIGHT       : LEFT_M = OFF; RIGHT_M = OFF; break;
        case RIGHT_SMALL : LEFT_M = OFF; RIGHT_M = OFF; break;
    }
 
    delay_200us();
    if(mode==GO)  LEFT_M = OFF; RIGHT_M = OFF ;
    delay_200us();
    if(mode==GO)  LEFT_M = OFF; RIGHT_M = ON ;
    delay_200us();
 
    switch(mode)
    {
        case STOP        : LEFT_M = OFF; RIGHT_M = OFF; break;
        case LEFT_SMALL  : LEFT_M = OFF; RIGHT_M = OFF; break;
        case LEFT        : LEFT_M = OFF; RIGHT_M = ON ; break;
        case GO          : LEFT_M = ON ; RIGHT_M = OFF; break;
        case RIGHT       : LEFT_M = ON ; RIGHT_M = OFF; break;
        case RIGHT_SMALL : LEFT_M = OFF; RIGHT_M = OFF; break;
    }
 
}
 
void high_speed(void)
{
 
    L_IR=ON;
    delay_15us();
    L_IR=OFF;
    l=SENSOR;            /* read left sensor */
 
    delay_400us();
 
    C_IR=ON;
    delay_15us();
    C_IR=OFF;
    c=SENSOR;            /* read center sensor */
 
    switch(mode)
    {
        case STOP        : LEFT_M = OFF; RIGHT_M = OFF; break;
        case LEFT_SMALL  : LEFT_M = ON ; RIGHT_M = ON; break;
        case LEFT        : LEFT_M = OFF; RIGHT_M = ON ; break;
        case GO          : LEFT_M = ON ; RIGHT_M = ON ; break;
        case RIGHT       : LEFT_M = ON ; RIGHT_M = OFF; break;
        case RIGHT_SMALL : LEFT_M = ON ; RIGHT_M = ON ; break;
    }
 
    delay_400us();
 
    R_IR=ON;
    delay_15us();
    R_IR=OFF;
    r=SENSOR;            /* read right sensor */
 
    if(c)
    {
        if(l)
        {
            if(r)
            {
                if(mode != STOP) mode=GO;
            }
            else mode=LEFT_SMALL;
        }
        else if(r) mode=RIGHT_SMALL;
        else mode=GO;
    }
    else
    {
        if(l) mode=LEFT;
        else if(r) mode=RIGHT;
        else                           /* FIND MODE */
        {
            if(mode < 3) mode=LEFT;
            else if(mode >3) mode=RIGHT;
        }
    }
 
    switch(mode)
    {
        case STOP        : LEFT_M = OFF; RIGHT_M = OFF; break;
        case LEFT_SMALL  : LEFT_M = OFF; RIGHT_M = ON ; break;
        case LEFT        : LEFT_M = OFF; RIGHT_M = ON ; break;
        case GO          : LEFT_M = ON ; RIGHT_M = ON ; break;
        case RIGHT       : LEFT_M = ON ; RIGHT_M = OFF; break;
        case RIGHT_SMALL : LEFT_M = ON ; RIGHT_M = OFF; break;
    }
 
    LEFT_LED=!l; CENTER_LED=!c; RIGHT_LED=!r;
 
    delay_200us();
 
    switch(mode)
    {
        case STOP        : LEFT_M = OFF; RIGHT_M = OFF; break;
        case LEFT_SMALL  : LEFT_M = OFF; RIGHT_M = OFF; break;
        case LEFT        : LEFT_M = OFF; RIGHT_M = OFF; break;
        case GO          : LEFT_M = OFF; RIGHT_M = OFF; break;
        case RIGHT       : LEFT_M = OFF; RIGHT_M = OFF; break;
        case RIGHT_SMALL : LEFT_M = OFF; RIGHT_M = OFF; break;
    }
 
    delay_200us();
 
    switch(mode)
    {
        case STOP        : LEFT_M = OFF; RIGHT_M = OFF; break;
        case LEFT_SMALL  : LEFT_M = OFF; RIGHT_M = ON ; break;
        case LEFT        : LEFT_M = OFF; RIGHT_M = ON ; break;
        case GO          : LEFT_M = ON ; RIGHT_M = ON ; break;
        case RIGHT       : LEFT_M = ON ; RIGHT_M = OFF; break;
        case RIGHT_SMALL : LEFT_M = ON ; RIGHT_M = OFF; break;
    }
 
    delay_100us();
 
    switch(mode)
    {
        case STOP        : LEFT_M = OFF; RIGHT_M = OFF; break;
        case LEFT_SMALL  : LEFT_M = OFF; RIGHT_M = OFF; break;
        case LEFT        : LEFT_M = OFF; RIGHT_M = OFF; break;
        case GO          : LEFT_M = OFF; RIGHT_M = OFF; break;
        case RIGHT       : LEFT_M = OFF; RIGHT_M = OFF; break;
        case RIGHT_SMALL : LEFT_M = OFF; RIGHT_M = OFF; break;
    }
 
}
 
void main(void)
{
    start_sign();
    mode=STOP;
 
    while(1)
    {
        if( JMP_SW == ON ) high_speed();
        else normal_speed();
    }
 
}
 
Voila, cependant ce programme était sur un atmel et lorsque je le met sur MPLAB pour le mettre sur mon pic il me trouve plein d'erreurs. Comment puis je faire?

Reply

Marsh Posté le 13-03-2005 à 18:29:48   

Reply

Marsh Posté le 13-03-2005 à 18:35:47    

mouahahahahha tes fonctions de delay, n'importe quel compilateur les torpille direct !

Reply

Marsh Posté le 13-03-2005 à 18:36:39    

C'est à dire ? :??:  pcq MPLAB en voulait pas des fonctions delay...

Reply

Marsh Posté le 13-03-2005 à 19:05:12    

BitedOeuf a écrit :

C'est à dire ? :??:  pcq MPLAB en voulait pas des fonctions delay...


 
Paske tes fonctions "delay" ne sont pas des délais, ce sont que des boucles. Et la même boucle ne s'exécute pas forcément toujours à la même vitesse.
Si, en plus, ton compilo optimise un poil il risque de mettre tes variable "i" dans des registres et la vitesse sera encore différente.
 
T'as pas accès aux fonctions "usleep" ???

Reply

Marsh Posté le 13-03-2005 à 19:29:11    

Désolé je ne saisi pas tout  :(  je suis novice en programmation. On puet pas remplacer delay par autre chose alors si ça marche pas?  
 
Edit: Dans le pire des cas on peut refaire le programme, c'est juste un programme pour suivre une ligne et un mode recherche quand il en trouve plus.


Message édité par BitedOeuf le 13-03-2005 à 19:31:46
Reply

Marsh Posté le 13-03-2005 à 19:32:21    

Sve@r a écrit :

Paske tes fonctions "delay" ne sont pas des délais, ce sont que des boucles. Et la même boucle ne s'exécute pas forcément toujours à la même vitesse.
Si, en plus, ton compilo optimise un poil il risque de mettre tes variable "i" dans des registres et la vitesse sera encore différente.
 
T'as pas accès aux fonctions "usleep" ???


le compilo va carrément zapper la boucle

Reply

Marsh Posté le 13-03-2005 à 19:35:55    

Ce srait plus rapide de le refaire?


Message édité par BitedOeuf le 13-03-2005 à 19:36:15
Reply

Marsh Posté le 13-03-2005 à 22:48:08    

BitedOeuf a écrit :

Bonjour je travaille sur un robot pour mes ppe, voici le programme d'origine en .c qui est programmé dans le µc d'origine.


#include <io51.h>


Voila, cependant ce programme était sur un atmel et lorsque je le met sur MPLAB pour le mettre sur mon pic il me trouve plein d'erreurs. Comment puis je faire?


Le programme d'origine est prévu pour 8051. Il utilise des extensions comme <io51.c>, 'bit' , 'data' ou les ports P1.x etc.
 
Il faut comprendre à quoi ça correspond pour un 8051, faire la correspondance avec le PIC et adapter le code. Ca nécessite une bonne connaissance de ces 2 micro contrôleurs.
 
A propos des délais, il existe probablement sur le PIC (comme sur le 8051) des mécanismes de timers et d'interruptions qui permettent de les faire indépendamment de l'horloge...
 
Je pense que vu la simplicité de la chose, et sa forte dépendence au hard, il vaut mieux réécrire le code.


Message édité par Emmanuel Delahaye le 13-03-2005 à 22:51:22

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 14-03-2005 à 19:23:25    

oui effectivement refaire le programme adapté pour pic. Je vais vous donner ce qui est mis en entré sortie. Par contre y'avait deux truc que je ne savais ce que c'était deux variables AIN0 et AIN1  je pensais à des repères de comparaisons pour la détéction IR ?  :??:

Reply

Marsh Posté le 14-03-2005 à 20:14:33    

Effectivement, AIN désigne généralement les entrées de comparateur analogique.

Reply

Marsh Posté le 14-03-2005 à 20:14:33   

Reply

Marsh Posté le 16-03-2005 à 16:56:53    

Voici deux feuilles que j'ai scannée :
 
http://micropieces.free.fr/mrline3.jpg
http://micropieces.free.fr/mrline4.jpg
 
Je met juste les liens pcq les photos sont assez grandes. Donc sur une il y a le cable du circuit de base du robot, celui que je conserve et il y a aussi le bout de circuit qui contenait l'ancien µC que j'ai viré et remplacé.
Sur la deuxième il y a le comportement du robot, c'est sur ça que je travaille, en locurence le modifier en gardant la base mais qu'une fois un certain seuil de tension dépassé il quitte le circuit pour en rejoindre un autre, enfin avant tout faudrait que j'arrive à adapter le programme de base dans mon µC.  
Je reprécise au cas ou µC est un PIC 16F876, je lui ai mit un quartz de 20MHz et j'ai fais un petit PCB vite fait pour remplcer l'ancien. Voici les ports utilisés :
 
Moteur1: PortB bit 3 (RB3) Pin24
Moteur2: PortB bit 4 (RB4) Pin25
Right_IR: PortB bit 0 (RB0) Pin21
Center_IR: PortB bit 1 (RB1) Pin22
Left_IR: PortB bit 2 (RB2) Pin23
Buzzer: PortA bit3 (RA3) Pin5
PWLed: PortA bit5 (RA5) Pin7
AIN0: PortA bit2 (RA2) Pin4
AIN1: PortA bit0 (RA0) Pin2
Vbatt: PortA bit1 (RA1) Pin3
 
Voila, comme vous avez pu le voir sur les feuilles il y avait deux led sur le pcb du µC qui était le pour la signalisation de la ligne et la troisieme led ( center) était sur la base, donc je vais m'en servir comme un temoin de fonctionnement. J'ai laisser branché le buzzer au cas ou mais il est pas indispensable, si la programmation du buzzer est trop complexe je la laisserais de coté. Et pour finir Vbatt est mon entrée que je relierai à ma batterie pour mesurer sa tension.
 
Qu'en pensez vous ? C'est réalisable ? :(  

Reply

Marsh Posté le 16-03-2005 à 20:04:20    

BitedOeuf a écrit :

C'est à dire ? :??:  pcq MPLAB en voulait pas des fonctions delay...


La bibliothèque fournie avec MPLAB fournit de base des "delay".
Cela implique qu'il n'y a pas d'interruption !


Message édité par podone le 16-03-2005 à 20:04:36
Reply

Marsh Posté le 17-03-2005 à 18:51:33    

Bon je viens de comprendre le fonctionnement de la détéction IR, en fait l'atmel envoyait des signaux de 1.2V d'une durée de 20µs sur chaque led et recoit une tension de 2.08V si il y a précense sur le led qui à recu le signal et une tension de 4.80V volt si ya non précense. Et ça c'est sur le AIN1, je suppose que sur le AIN0 ça doit etre inversé nan ?  :??:

Reply

Marsh Posté le 17-03-2005 à 20:28:37    

En fait concretement il faut mettre quoi dans le microcontroleur ? Parce que en plus du programme principale j'ai vu que certain mette un fichier xxx.h ou xxx.inc avec xxx représentant le nom du µC  :(

Reply

Marsh Posté le 19-03-2005 à 10:33:59    

siou plé msieur dame j'aurais bsoin d'aide  :(

Reply

Marsh Posté le 23-03-2005 à 22:38:35    

BitedOeuf a écrit :

siou plé msieur dame j'aurais bsoin d'aide  :(


 
Bonjour,
 
Je te conseille d'utiliser les timers pour générer des delais fixes ... peux-tu donner plus d'infos sur ton PIC ... c'est lequel et les différentes entrées en fait .. un max d'infos serait les bienvenues ... surtout un schéma électrique et la réference du PIC ...
 
Si tu veux plus d'aide sur les pics et comment utiliser les timers, tu vas dans google et tu fais une recherche sur Bigonnoff ... la, normalement tu devrais déja trouver quelques infos ...
 
Le fichier *.h est un header, il te permet de déclarer et définir des prototypes de fonctions et aussi de définir des noms d'entrées/sorties ... Le fichier *.inc est un fichier qui donne toute les déclarations du pic, les registres, les noms des entrées et bien d'autres choses ...
 
Phil
@+

Reply

Marsh Posté le 30-03-2005 à 23:34:45    

Bonjour, qqun saurait pourquoi quand je met par ex led=1 mon compilateur C me met "Expecting LVALUE such as a variable name or *expression" je précise que mon compilateur est ccs. Par contre si je met un double égal (==) il me dit rien.
 
par ex pour mon programme :
 
 
#include "C:\Documents and Settings\Yoann\Bureau\PPe.h"
 
#define RIGHT_M        PIN_B4
#define LEFT_M         PIN_B3
 
#define CENTER_LED     PIN_A5
 
#define L_IR           PIN_B2
#define C_IR           PIN_B1
#define R_IR           PIN_B0
 
#define ON             1
#define OFF            0
 
#define STOP           0
#define LEFT_SMALL     1
#define LEFT           2
#define GO             3
#define RIGHT          4
#define RIGHT_SMALL    5
#define FIND           5
 
#define seuilfort 0x399
#define seuilfaible 0x334
 
 
unsigned char mode,l,c,r,SENSOR;
 
void start_sign(void)
{
    CENTER_LED==ON;
    delay_us(200);
    CENTER_LED==OFF;
    delay_us(200);
    CENTER_LED==ON;
    delay_us(200);
    CENTER_LED==OFF;
    delay_us(200);
    CENTER_LED==ON;
    delay_us(200);
    CENTER_LED==OFF;
}
 
void normal(void)
 
Je voudrais allumer et éteindre les leds consécutivement mais si je met led=1 ça me met le message et si je met un double égal ça dit rien  :??:

Reply

Marsh Posté le 31-03-2005 à 10:15:37    

BitedOeuf a écrit :

Bonjour, qqun saurait pourquoi quand je met par ex led=1 mon compilateur C me met "Expecting LVALUE such as a variable name or *expression" je précise que mon compilateur est ccs. Par contre si je met un double égal (==) il me dit rien.
 
par ex pour mon programme :
 
<rien à propos de 'led'...>
 
Je voudrais allumer et éteindre les leds consécutivement mais si je met led=1 ça me met le message et si je met un double égal ça dit rien  :??:


??? Comment est défini 'led' ?


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 31-03-2005 à 10:44:52    

BitedOeuf a écrit :


Je voudrais allumer et éteindre les leds consécutivement mais si je met led=1 ça me met le message et si je met un double égal ça dit rien  :??:


Je suppose que tu voulais parler de CENTER_LED...
si tu mets un "==", c'est normal que ça ne donne rien, ça se contente de faire une comparaison.
Si tu mets un "=", vu que les #define sont directement remplacés par leur valeur par le précompilateur, tu auras des expressions du type 1=1. Normal que le compilo râle, tu ne pas mettre une valeur dans un entier.
Pour en revenir à la programmation des pics, et vu comment tu l'implémente en C, j'imagine que tu as voulu retranscrire ce que tu faisais en assembleur pour pic (équivalent MOVWF, ...).
Il faut que tu expliques au compilateur que ton CENTER_LED n'est pas une constante, mais bien une pointeur sur le bit que tu cherches, dans les registres de ton PIC.
Ca se fait soit en passant par les SFR, soit par des pragmas spécifiques à CCS.
Je ne sais plus quel est le registre qui contient les ports A, mais tu peux définir des trucs du genre :

Code :
  1. #byte TRISA         =0x85


qui fera pointer TRISA vers le bon registre (un TRISA=0xff "équivaudra" à *((char*)0x85)=0xff)
Ou alors, ce qui correspond plus à ton cas :

Code :
  1. #bit TRISA_RA5      =0x85.5


qui pointera directement vers le bit 5 de TRISA (un TRISA_RA5=1 "équivaudra" à *((char*)0x85) |= 0x20
Regarde plus en détails la doc de ton CCS, tu devrais avoir plein d'exemples dessus (et sinon, google est ton ami, il y a plein d'exemples sur le web)
 
Mais là on sort du C standard...
 

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed