Je vais utiliser pour les 2 projets un 68hc908jk8
Merci!
-----
Je vais utiliser pour les 2 projets un 68hc908jk8
Merci!
pour gérer les I/O, je pense pas qu'il soit nécessaire d'utiliser processor expert.
J'utilise processor expert lorsque la gestion de l'horloge est complexe et utilise une pll. La config des registres est relativement complexe dans ce cas.
C'est aussi intéressant si tu gères des buffers de réception et d'émission sur ta liaison série par exemple.
Mais pour des problèmes simples, autant écrire directement ton code.
A+
J'ai trouvé l'erreur, on ne peut apparement pas faire de déclaration de variable dans le main, il faut le faire avant en variable globale.
Pour le timer j'ai trouvé un truc mais je suis pas sur de tout alors je préfére demander
void Timer10s(void) {
T1SC_PS=6; //prédiviseur par 64
T1SC_TOIE=0; //pas d'interruption
T1SC0=0; // ????
T1SC1=0; // ????
T1MOD=1250000; // valeur à atteindre
T1SC_TSTOP=0; // comptage actif
T1SC_TRST=1; // réinitialise le compteur une fois le comptage terminé ???
__RESET_WATCHDOG(); // ???
}
1250000 car je veu 10 secondes, que le bus est à 8Mhz et que j'utilise un prédivideur de 64.
Si c'est juste, je place simplement cette fonction avant le main du fichier.c ?
Merci pour tes explications !
si tu peux, mais la variable sera locale à la fonction main().on ne peut apparement pas faire de déclaration de variable dans le main, il faut le faire avant en variable globale.
Tu ne peux pas faire une tempo de 10s avec un timer. Ton initialisation ne pourra pas fonctionner car un timer est constitué de registres 16 bits. La plus grande valeur possible est donc 65535.
Du coup, ta ligne:
T1MOD=1250000; // valeur à atteindre
ne passera pas.
Il faut donc travailler en interruptions. Configure ton timer pour faire une interruption toutes les 0,5s par exemple (c'est le plus long temps avec un compte rond:8 000 000/64/62500 = 2Hz)
à chaque interruption tu incrémentes un compteur jusqu'à ce qu'il atteigne 20.
De plus:
T1SC_PS=6; //prédiviseur par 64
ne passera pas non plus à moins que tu aies défini T1SC_PS.
Pourquoi ne pas définir directement le registre T1SC comme çà:
T1SC = 0b10000111; // valeur au hazard, pour exemple
A+
Dernière modification par Jack ; 03/05/2006 à 16h41.
Bonjour,
pour le timer j'ai regardé comment faire à l'aide des beans mais il y a beaucoup de choix possible et ca m'a l'air assez compliqué.
Sinon j'ai écris les fonctions suivantes juste au dessus du void main(void) (en espérant que ca soit juste...)
Fonction Timer1 permettant d'effectuer un comptage de 0.5 seconde
void Timer1(void) {
Configuration du Timer1: (de gauche à droite)
0: initialisation à 0 de l'état représentant la fin du comptage
1: activation des interruptions
0: permet d'activer ultérieurement le compteur (sinon compteur inactif)
1: réinitialise le timer à 0
0: aucune signification
110: prédiviseur par 64 (permet un grande précision)
T1SC=0b01010110;
Nombre à atteindre pour une durée de 0.5 seconde
Bus à 8Mhz, prédiviseur par 64, valeur souhaitée 0.5 seconde
Calcul: 0.5s/(1/8Mhz * 64) = 62500
0.5s car Timer 16 bits donc nombre maximum = 65535
T1MOD=62500;
}
Fonction activée lors des interruptions de la fonction précédente permettant de compter jusqu'à 10 secondes
void interrupt _TimerOverflow_1(void){
Compte le nombre de fois que 0.5 seconde se sont écoulée depuis l'activation du timer
duree++;
Réinitialisation de timer
T1SC=0b01010110;
T1MOD=62500;
Si les 10 secondes sont écoulées: réinitialisation de duree à 0 et mise à 1 d'une variable prévenant le programme principal
if (duree==20){
duree=0;
fin=1;
Sinon on relance le timer pour 0.5s supplémentaires
}else{
Timer1();
}
}
Si tu peux me dire si j'ai bon ou pas (pas d'erreur à la compilation en tout cas) ?
Merci !
Oups désolé pour la présentation, c'est un copier coller de codewarrior que je n'ai pas eu trop le temps de modifier (5 minutes seulement pour éditer un post...)
l'initialisation du timer a l'air correcte, j'aurais juste configuré le modulo avant le registre de contrôle et donc le lancement du compteur, mais ça doit aller.
Concernant le programme d'interruption, il y a 2 techniques: tu précises le N° de vecteur d'interruption ce qui donne:
void interrupt 6 _TimerOverflow_1(void){
à vérifier s'il s'agit bien du 6, le 0 étant le vecteur reset.
2ème solution, tu laisses comme tu as écrit et tu précises le numéro de vecteur dans le fichier .prm de ton projet
Encore un point: je pense que tu n'auras qu'une seule et unique interruption car tu réinitialises pas bien le timer. La doc dit qu'il faut lire le bit TOF (indicateur de fin de tempo) puis le mettre à 0. Le plus simple est d'écrire:
T1SC_TOF = 0; // Réarme le flag TOF
C'est traduit en assembleur en :
bclr 6,T1SC qui fait une lecture / modification / écriture du registre T1SC.
Pas la peine de réécrire T1MOD = 62500; puisque le registre n'a pas de raison de changer.
inutile également. Une fois le timer programmé, il va générer automatiquement ses interruptions toutes les 0,5s.Sinon on relance le timer pour 0.5s supplémentaires
}else{
Timer1();
}
A+
Ok, j'ai mis le T1MOD avant le T1SC, j'ai remplacé la réinitialisation en T1SC_TOF = 0, j'ai supprimé le else Timer1().
J'ai également rajouté dans le if(duree==20) T1SC_TSTOP = 1 afin de stopper le compteur une fois les 10 secondes écoulées.
Par contre pour le numéro du vecteur d'interruption, je trouve ca dans la doc ?
J'ai un peu regardé mais j'ai pas trouvé pour l'instant, c'est dans la partie timer ou c'est un truc plus "généraliste"?
Merci pour tes explications !!!
c'est plus général puisqu'il s'agit de la table des vecteurs d'interruption.
C'est à la fin du chapitre "memory map".
En regardant le vecteur TIM1 overflow est bien le N°6.
ok, je ne me souvenais plus que tu voulais un monostable en fait.J'ai également rajouté dans le if(duree==20) T1SC_TSTOP = 1 afin de stopper le compteur une fois les 10 secondes écoulées.
A+
J'ai pas réussir à voir où c'était mais je te fais confiance lol
Merci !
J'ai commencé le programme pour le microcontroleur de l'interface ethernet.
J'ai donc défini RXD comme la broche PTD_PTD7 par un define et la même chose pour les sorties et j'ai fait le programme suivant mais il me marque à chaque condition sauf la première "condition always FALSE" pourtant je vois pas où est le problème...
Activation du relai demandé par l'utilisateur
if (RXD == 0b00000001) S1 = 0;
if (RXD == 0b00000010) S2 = 0;
if (RXD == 0b00000011) S3 = 0;
if (RXD == 0b00000100) S4 = 0;
if (RXD == 0b00000101) S5 = 0;
if (RXD == 0b00000110) S6 = 0;
if (RXD == 0b00000111) S7 = 0;
if (RXD == 0b00001000) S8 = 0;
if (RXD == 0b00001001) S9 = 0;
Désactivation du relai demandé par l'utilisateur
if (RXD == 0b11110001) S1 = 1;
if (RXD == 0b11110010) S2 = 1;
if (RXD == 0b11110011) S3 = 1;
if (RXD == 0b11110100) S4 = 1;
if (RXD == 0b11110101) S5 = 1;
if (RXD == 0b11110110) S6 = 1;
if (RXD == 0b11110111) S7 = 1;
if (RXD == 0b11111000) S8 = 1;
if (RXD == 0b11111001) S9 = 1;
Désactivation de l'ensemble des relais
if (RXD == 0b11111111){
S1 = 1;
S2 = 1;
S3 = 1;
S4 = 1;
S5 = 1;
S6 = 1;
S7 = 1;
S8 = 1;
S9 = 1;
}
Merci encore pour ton aide !
j'avoue ne pas comprendre ce que tu fais.
Tu veux utliser une liaison série? Configure alors la SCI. Dès que tu auras validé la SCI en réception, le PTD7 sera utilisé comme entrée de réception des données (Rxd).
Ensuite il faut gérer la réception série à l'aide des autres registres de la SCI.
A+
En fait je pensais qu'en configurant le bean SCI on pouvait ensuite utiliser simplement le pin PTD_PTD7 (RxD en fait) comme avant, c'est à dire faire if(PTD_PTD7=0b00000000) pour vérifier si le code série récu sur la broche RxD est 00000000 mais apparement non...
dans tous les cas on ne gère pas la patte Rxd, mais les registres (ou le buffer de réception avec proc expert).
Processor expert est fait pour diminuer le temps de développement. Mais je pense qu'il est réservé aux développeurs ayant de l'expérience.
Dès qu'il y a un truc qui coince, si tu ne maîtrises pas bien les fonctions de base du µC, tu auras bien du mal à trouver la source du problème.
Si je peux me permettre un conseil, laisse pour l'instant proc expert. La gestion de la SCI est assez simple à mon avis. Dans le cas contraire, il te faudra utiliser les méthodes des beans (hé oui, c'est de la programmation objet).
A+
En fait pour l'instant (je sais pas si j'ai bon), j'ai juste mis le bean AsynchoSerial qui est dans la "case" SCI.
J'ai vérifié qu'il y avait 8 bits de données, 1 bit de stop et j'ai mi la vitesse de transmission à 19200 pour l'instant.
Et sinon d'après la doc je viens de voir que le registre de données c'est SCDR, donc j'ai juste à faire if(SCDR=0bxxxxxxxx) pour voir si c'est le code xxxxxxxx qui a été transmit, non ?
En tout cas je n'ai plus d'erreur à la compilation
Merci !
il faut d'abord tester qu'une nouvelle donnée est arrivée grâce au registre d'état SCS1, bits SCRF.
Là aussi, il vaut mieux travailler en interruptions sinon tu vas bloquer ton appli à attendre qu'un caractère arrive.
A+
Bonjour,
En fait je crois avoir compri globalement le fonctionnement et t'as du t'arracher les cheveux quand t'as vu mon programme LOL
Donc en fait une fois que le microcontroleur a réceptionné les données correctement il les met dans le registre SCDR et il indique que les données sont prêtes à être lues en mettant un 1 logique dans le bit 5 du registre SCS1.
Par contre la petite question c'est quand est ce que le bit repasse à 0 ? une fois ce bit lu ? une fois les données lues ? au bout d'un certain temps ?
Pour les interruptions je ne sais pas si c'est vraiment nécessaire étant donné que mon programme ne fait qu'activer ou désactiver une sortie en fonction du code reçu, donc s'il ne recoit pas de code il n'a rien à faire.
Et je pense donc qu'un simple if(SCS1_SCDR == 1) fera l'affaire à moins que j'ai encore loupé un truc ?
Enfin dernière petite question, la ligne de code à la fin qui est généré par processor expert, c'est pour que le main se fasse tout le temps et donc d'éviter d'avoir à écrire un while(1), c'est bien ca ?
Merci pour tes explications !
Pour cette aplication ci, peut être pas, mais pour une aplication futur, cela vaux probablement la peine de creuser le fonctionement des interruptions en général, et de faire qq chose de bien...Envoyé par Marc57Pour les interruptions je ne sais pas si c'est vraiment nécessaire
Si tu pensse a faire des routinnes asser modulaire, elle peuvent facilement reservir pour d'autre aplication apres.
je m'en remettrai. Ne compte cependant plus trop sur moi, je suis absent jusqu'à lundi. D'autres prendront surement le relai.En fait je crois avoir compri globalement le fonctionnement et t'as du t'arracher les cheveux quand t'as vu mon programme LOL
ouiDonc en fait une fois que le microcontroleur a réceptionné les données correctement il les met dans le registre SCDR et il indique que les données sont prêtes à être lues en mettant un 1 logique dans le bit 5 du registre SCS1.
Je ne sais pas si tu es fâché avec l'anglais, car c'est assez clair:Par contre la petite question c'est quand est ce que le bit repasse à 0 ? une fois ce bit lu ? une fois les données lues ? au bout d'un certain temps ?
"In normal operation, clear the SCRF bit by reading SCS1 with SCRF set and then reading the SCDR"
Pour les interruptions, Xavier35 a parfaitement répondu.
Comme il s'agit d'une boucle d'attente, l'idéal est:Et je pense donc qu'un simple if(SCS1_SCDR == 1) fera l'affaire à moins que j'ai encore loupé un truc ?
while (!SCS1_SCDR); // le µC reste bloqué ici dans l'attente de réception d'un caractère.
oui, c'est pour que le programme boucle en permanence.Enfin dernière petite question, la ligne de code à la fin qui est généré par processor expert, c'est pour que le main se fasse tout le temps et donc d'éviter d'avoir à écrire un while(1), c'est bien ca ?
Comme tu comptes apparemment rester coincé dans l'attente d'un caractère, attention au watchdog. Soit tu le réarme pendant ta boucle d'attente, soit tu l'inhibes carrément:
CONFIG1_COPD = 1;
A+++
Ok pour les interruptions, pas forcément nécessaire à ce programme mais très pratique en général.
Oups j'ai du zapper la ligne la dans la doc, dsl.
Oui malhreuseusement l'anglais c'est pas spécialement mon point fort...globalement ca va mais y'a toujours des trucs...
Par contre pour le watchdog j'ai vu que c'était un truc qui était censé éviter des bugs mais en fait je sais pas trop ce que c'est, j'y ai pas encore trop fait attention, faut que je regarde ca de plus près.
Merci pour vos explications !!!
Pour simplifier tres fort, c'est un truc qui fait un reset automatiquement quand on l'oublie.Envoyé par Marc57Par contre pour le watchdog j'ai vu que c'était un truc qui était censé éviter des bugs mais en fait je sais pas trop ce que c'est, j'y ai pas encore trop fait attention, faut que je regarde ca de plus près.
Cela n'évite pas les bug, mais quand il y en a un dans ton soft, et qu'il bloque tout, le watchdog va faire un reset tout seul, permettant de relancer la machine sant que tu ai a intervenir. C'est une arme a double tranchant, tres pratique quand c'est bien utilisé.
Ok, merci pour tes explications !!!
Bonjour,
je suis en train de developper une petite apli VB qui va bien pour commander tout ca et en fait je me suis aperçu qu'il fallait lors de la connection que je récupère l'état des sorties.
J'ai activé le sci et le transmetteur via processor expert et j'ai donc écrit le code suivant :
if (SCDR == 1000){ //lorsque je recoit le code 1000
if(SCS1_SCTE){} //lecture de SCTE
SCDR = S1; envoi de l'état de la sortie 1
if(SCS1_SCTE){}
SCDR = S2;
if(SCS1_SCTE){}
SCDR = S3;
if(SCS1_SCTE){}
SCDR = S4;
if(SCS1_SCTE){}
SCDR = S5;
if(SCS1_SCTE){}
SCDR = S6;
if(SCS1_SCTE){}
SCDR = S7;
if(SCS1_SCTE){}
SCDR = S8;
if(SCS1_SCTE){}
SCDR = S9;
}
En fait j'aurais juste voulu savoir si je me suis pas planté et s'il n'est pas possible de faire un truc comme ce qui suit afin d'éviter les répétitions? (cet exemple ne marche pas, c'est juste pour donner l'idée)
for (i=1;i<10;i++){
if(SCS1_SCTE){}
SCDR = Si
}
Merci
heu c'est if(SCDR == 100), 1000 sur 8 bits c'est chaud LOL
A quoi servent les accolades {}?if(SCS1_SCTE){}
SCDR = S2;
for (i=1;i<10;i++){for (i=1;i<10;i++){
if(SCS1_SCTE){}
SCDR = Si
}
if(SCS1_SCTE) SCDR = S[i];
}
en déclarant S ainsi:
byte S[10]; // S[0] à S[9]
A+
Euh...lolEnvoyé par JackA quoi servent les accolades {}?
Ok merci !Envoyé par Jackfor (i=1;i<10;i++){
if(SCS1_SCTE) SCDR = S[i];
}
en déclarant S ainsi:
byte S[10]; // S[0] à S[9]
A+
Oups, désolé
ça ne marchera pas, tous tes caractères ne seront pas envoyés. Il faut écrire:
for (i=1;i<10;i++){
while (!SCS1_SCTE);// attend que le registre d'émission soit vide
SCDR = S[i]; // maintenant on peut envoyer le caractère
}
Dernière modification par Jack ; 15/05/2006 à 13h46.
Ok ca marche
Merci !
Bonjour,
Je viens (enfin) de réaliser le programmateur spécial débutant du site 68hc08.net, j'ai vérifié les connexions qui m'ont l'air ok, j'ai bien les tensions 5 et 8V donc ca m'a l'air bon.
J'ai branché le microcontroleur en mettant les 8V sur /irq, j'ai mi la broche OSC sur OSC1, j'ai mi OSC2 et VSS à la masse, j'ai mis les 5V sur vdd, j'ai branché PAO sur PTB0, j'ai mis 5V sur PTB1 et PTB3 et 0v sur PTB2 comme indiqué dans la doc.
Lorsque je connecte l'appareil au pc et que je lance le logiciel de flashage (mode 3 avec vitesse de 9600) il me détecte apparement la plaquette (j'ai un Y à coté du truc 0, mais par contre pour les autres truc (de sécurité ou je sais pas quoi) j'ai N et il entre pas dans le mode monitor)
J'ai revérifié la plaque mais rien ne me choque...
Avec les symptomes du logiciel personne ne sait d'où pourrait éventuellement provenir le problème ?
Merci
En fait je vien de voir que j'ai plus que 7,1V au lieu des 8,2V sur /IRQ (alors que la pile est neuve...), c'est peu être ca le problème, c'est combien la tension minimum pour entrer dans le mode monitor ?
Merci