Programme de pic - C - Programmation
Marsh Posté le 13-03-2005 à 18:35:47
mouahahahahha tes fonctions de delay, n'importe quel compilateur les torpille direct !
Marsh Posté le 13-03-2005 à 18:36:39
C'est à dire ? pcq MPLAB en voulait pas des fonctions delay...
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" ???
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.
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. |
le compilo va carrément zapper la boucle
Marsh Posté le 13-03-2005 à 19:35:55
Ce srait plus rapide de le refaire?
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.
|
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.
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 ?
Marsh Posté le 14-03-2005 à 20:14:33
Effectivement, AIN désigne généralement les entrées de comparateur analogique.
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 ?
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 !
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 ?
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
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
@+
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
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. |
??? Comment est défini 'led' ?
Marsh Posté le 31-03-2005 à 10:44:52
BitedOeuf a écrit : |
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 :
|
qui fera pointer TRISA vers le bon registre (un TRISA=0xff "équivaudra" à *((char*)0x85)=0xff)
Ou alors, ce qui correspond plus à ton cas :
Code :
|
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...
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?