Bonjour,
Sujet : Je dois commander deux moteurs pas à pas unipolaires 6 fils, « à l’aide des deux circuits de commande L297 et L298, sous le contrôle du pic 16f877 qui reçoit les instructions depuis un PC relier par un DB9-max 232, (figure 1 en pièce jointe) » ;
Pour cela je dois programmer l’usart et le timer1.
Problème: Je compile sans problème, mais lorsque je simule en reliant la COMUNICATION TERMINAL avec PROTEUS, les moteurs ne tournent pas convenablement,
Merci pour votre aide, voici mon code écrit avec MikroC for pic version 8 :
unsigned int t1,t2,ttmp;
unsigned char m;
unsigned short int cmd_recu;
unsigned short int tmoteur1_L;
unsigned short int tmoteur1_H;
unsigned short int tmoteur2_L;
unsigned short int tmoteur2_H;
unsigned short int vitesse[16];
unsigned short int cmd_moteur;
/*
Commande Reçue :
b7 : Commandes 1 : Vitesse 0 : Commandes
b6 : Choix Moteur 1 : Moteur 2 0 : Moteur 1
b5 : Marche_Arret 1 : Marche 0 : Arret
b4 : Sens Moteur1 1 : 0 :
b3-b0 : Vitesse Moteur
Comandes :
cmd_recu = 1 : Arret des deux moteurs (cmd_moteur = 1)
cmd_recu = 2 : Moteur 1 et Moteur 2 en Marche (cmd_moteur = 2)
cmd_recu = 4 : Moteur 1 en Marche et Moteur 2 en Arret (cmd_moteur = 4)
cmd_recu = 8 : Moteur 1 en Arret et Moteur 2 en Marche(cmd_moteur = 8)
PortB Pin Assignation :
RC2 : Enable Moteur 2
RC1 : Enable Moteur 1
RB4 : Sens Moteur 2
RB0 : Sens Moteur 1
RB5 : Commande Moteur 2
RB1 : Commande Moteur 1
*/
void interrupt()
{
if(PIR1.RCIF == 1) // if data is received
{
PIR1.RCIF = 0;
cmd_recu = USART_Read();
// Usart_Write(cmd_recu);
asm {
bcf STATUS,RP0 // Bank 0
bcf STATUS,RP1
movf cmd_recu,0 // Usart_Write(cmd_recu);
movwf TXREG
btfss cmd_recu,7 // Commandes si bit7 = 0
goto commandes
btfsc cmd_recu,6 // Moteur...
goto moteur2
btfss cmd_recu,5 // Marche_Arret Moteur 1
bcf PORTC,1 // Arret Moteur 1
btfsc cmd_recu,4 // Sens du Moteur...
goto sens2_Moteur1
bsf PORTB,0 // Sens 1 Moteur 1
goto vitesse_moteur1
sens2_Moteur1 :
bcf PORTB,0 // Sens 2 Moteur 1
vitesse_moteur1 :
movlw 0x0f
andwf cmd_recu,1 // cmd_recu & 0x0f -> cmd_recu
movlw vitesse
addwf cmd_recu,0 // adresse de vitesse_L[cm_recu] -> W
movwf FSR // W -> FSR : registre d'adressage indirect
movf INDF,0 // vitesse_L[cmd_recu] -> W
movwf tmoteur1_L
bsf STATUS,IRP // Adressage de la zone 0x120 - 0x16f
movf INDF,0 // vitesse_H[cmd_recu] -> W
movwf tmoteur1_H
bcf STATUS,IRP
goto fin_vitesse
moteur2 :
btfss cmd_recu,5 // Marche_Arret Moteur 2
bcf PORTC,2 // Arret Moteur 2
btfsc cmd_recu,4
goto sens2_Moteur2
bsf PORTB,4 // Sens 1 Moteur 2
goto vitesse_moteur2
sens2_Moteur2 :
bcf PORTB,4 // Sens 2 Moteur 2
vitesse_moteur2 :
movlw 0x0f
andwf cmd_recu,1 // cmd_recu & 0x0f -> cmd_recu
movlw vitesse
addwf cmd_recu,0 // adresse de vitesse_L[cmd_recu] -> W
movwf FSR // W -> FSR : registre d'adressage indirect
movf INDF,0 // vitesse_L[cmd_recu] -> W
movwf tmoteur2_L
bsf STATUS,IRP // Adressage de la zone 0x120 - 0x16f
movf INDF,0 // vitesse_H[cmd_recu] -> W
movwf tmoteur2_H
bcf STATUS,IRP
goto fin_vitesse
commandes :
btfsc cmd_recu,0
goto arret_total
btfsc cmd_recu,1
goto Marche
btfsc cmd_recu,2
goto Marche1
btfsc cmd_recu,3
goto Marche2
goto fin_vitesse // Retour si autre commande ...
arret_total : // Arret des 2 Moteurs
bcf PORTC,1 // Enable désactivé
bcf PORTC,2
movlw 1
movwf cmd_moteur // sauvegarde de l'état de la commande
bcf T1CON,0 // Arret du Timer 1 : TMR1ON = 0
bsf STATUS,RP0 // Bank 1
bcf PIE1,0 // Désactivation de interr.Timer 1
bcf STATUS,RP0 // Bank 0
Bcf PIR1, 0 // Effacement du flag du Timer 1
goto fin_vitesse
Marche : // Mise en marche des 2 Moteurs
bsf PORTC,1
bsf PORTC,2
movlw 2
movwf cmd_moteur
bsf T1CON,0 // Démarrage du Timer 1 : TMR1ON = 0
bsf STATUS,RP0 // Bank 1
bsf PIE1,0 // Activation de interr.Timer 1
bcf STATUS,RP0 // Bank 0
// à ajouter comparaison entre t1 et t2
// pour déterminer la valeur de 'm' !!!!!!
goto fin_vitesse
Marche1 : // Moteur 1 en marche
bsf PORTC,1
bcf PORTC,2
movlw 4
movwf cmd_moteur
bsf T1CON,0 // Démarrage du Timer 1 : TMR1ON = 0
bsf STATUS,RP0 // Bank 1
bsf PIE1,0 // Activation de interr.Timer 1
bcf STATUS,RP0 // Bank 0
goto fin_vitesse
Marche2 : // Moteur 2 en marche
bcf PORTC,1
bsf PORTC,2
movlw 8
movwf cmd_moteur
bsf T1CON,0 // Démarrage du Timer 1 : TMR1ON = 0
bsf STATUS,RP0 // Bank 1
bsf PIE1,0 // Activation de interr.Timer 1
bcf STATUS,RP0 // Bank 0
goto fin_vitesse
fin_vitesse :
nop
}
}
if(PIR1.TMR1IF == 1)
{
PIR1.TMR1IF = 0; // clear TMR1IF
asm {
btfsc cmd_moteur,1
goto Marche_
btfsc cmd_moteur,2
goto Marche_1
btfsc cmd_moteur,3
goto Marche_2
btfss cmd_moteur,0 // saut ...
goto retour_interr
nop // Désactivation du timer !!!
goto retour_interr
}
// Commande des deux moteurs...
asm {
Marche_ :
nop
}
if(m == 1) // le Timer1 a été attribué au moteur 1
{
//PortB.F1 = ~PortB.F1; // inverser la commande du moteur 1
// t1 = tm1;
asm {
movlw 0x02
xorwf PORTB,1
movf tmoteur1_L,0 // rechargement de t1 qui a été modifiée
movwf _t1
movf tmoteur1_H,0
movwf _t1+1
}
}
else if(m == 2) // le Timer1 a été attribué au moteur 2
{
//PortB.F5 = ~PortB.F5; // inverser la commande du moteur 2
// t2 = tm2;
asm {
movlw 0x20
xorwf PORTB,1
movf tmoteur2_L,0 // rechargement de t2 qui a été modifiée
movwf _t2
movf tmoteur2_H,0
movwf _t2+1
}
}
else if (m == 3) // Timer1 est attribué aux 2 moteurs
{
// PortB.F1 = ~PortB.F1; // inverser la commande des 2 moteurs
// PortB.F5 = ~PortB.F5;
// t1 = tm1;
// t2 = tm2;
asm {
movlw 0x02
xorwf PORTB,1
movlw 0x20
xorwf PORTB,1
movf tmoteur1_L,0 // rechargement de t1 et t2
movwf _t1
movf tmoteur1_H,0
movwf _t1+1
movf tmoteur2_L,0 // rechargement de t2 qui a été modifiée
movwf _t2
movf tmoteur2_H,0
movwf _t2+1
}
}
if(t1<t2) // Timer1 sera attribué au moteur 1
{
t2 = t2-t1; // modification de t2
ttmp = ~t1;
// TMR1L = ttmp;
// TMR1H = ttmp>>8;
asm {
movf _ttmp,0 // chargement du Timer1 par t1
movwf TMR1L
movf _ttmp+1,0
movwf TMR1H
}
m = 1;
}
else if(t1>t2) // Timer1 sera attribué au moteur 2
{
t1 = t1-t2; // modification de t1
ttmp = ~t2;
// TMR1L = ttmp;
// TMR1H = ttmp>>8;
asm {
movf _ttmp,0 // chargement du Timer1 par t1
movwf TMR1L
movf _ttmp+1,0
movwf TMR1H
}
m = 2;
}
else // Timer1 sera attribué au 2 moteurs
{
ttmp = ~t1;
// TMR1L = ttmp;
// TMR1H = ttmp>>8;
asm {
movf _ttmp,0 // chargement du Timer1 par t1 = t2
movwf TMR1L
movf _ttmp+1,0
movwf TMR1H
}
m = 3;
}
asm {
goto retour_interr
}
// Commande du moteur 1 seulement...
asm {
Marche_1 :
movlw 0x02
xorwf PORTB,1 // PortB.F1 = ~PortB.F1
comf tmoteur1_L,0
movwf TMR1L
comf tmoteur1_H,0
movwf TMR1H
goto retour_interr
}
// Commande du moteur 2 seulement...
asm {
Marche_2 :
movlw 0x20
xorwf PORTB,1 // PortB.F5 = ~Portb.F5
comf tmoteur2_L,0
movwf TMR1L
comf tmoteur2_H,0
movwf TMR1H
goto retour_interr
}
asm {
retour_interr :
nop
}
}
}
void main()
{
tmoteur1_L = 0xff;
tmoteur1_H = 0x55;
tmoteur2_L = 0x98;
tmoteur2_H = 0x00;
/*
vitesse[0] = 0x10;
vitesse[1] = 0x11;
vitesse[2] = 0x12;
vitesse[3] = 0x13;
vitesse[4] = 0x14;
vitesse[5] = 0x15;
vitesse[6] = 0x16;
vitesse[7] = 0x17;
vitesse[8] = 0x18;
vitesse[9] = 0x19;
vitesse[10] = 0x1a;
vitesse[11] = 0x1b;
vitesse[12] = 0x1c;
vitesse[13] = 0x1d;
vitesse[14] = 0x1e;
vitesse[15] = 0x1f; */
vitesse[0] = 0;
asm {
bcf STATUS,RP0
bcf STATUS,RP1
movlw 0x10 // Chargement des poids faibles des
movwf _vitesse // vitesses consignes dans l'adresse
movlw 0x11 // _vitesse située dans le Bank 0
movwf _vitesse+1
movlw 0x12
movwf _vitesse+2
movlw 0x13
movwf _vitesse+3
movlw 0x14
movwf _vitesse+4
movlw 0x15
movwf _vitesse+5
movlw 0x16
movwf _vitesse+6
movlw 0x17
movwf _vitesse+7
movlw 0x18
movwf _vitesse+8
movlw 0x19
movwf _vitesse+9
movlw 0x1a
movwf _vitesse+10
movlw 0x1b
movwf _vitesse+11
movlw 0x1c
movwf _vitesse+12
movlw 0x1d
movwf _vitesse+13
movlw 0x1e
movwf _vitesse+14
movlw 0x1f
movwf _vitesse+15
bcf STATUS,RP0
bsf STATUS,RP1
movlw 0x20 // Chargement des poids forts des
movwf _vitesse // vitesses consignes dans l'adresse
movlw 0x21 // _vitesse située dans le Bank 2
movwf _vitesse+1
movlw 0x22
movwf _vitesse+2
movlw 0x23
movwf _vitesse+3
movlw 0x24
movwf _vitesse+4
movlw 0x25
movwf _vitesse+5
movlw 0x26
movwf _vitesse+6
movlw 0x27
movwf _vitesse+7
movlw 0x28
movwf _vitesse+8
movlw 0x29
movwf _vitesse+9
movlw 0x2a
movwf _vitesse+10
movlw 0x2b
movwf _vitesse+11
movlw 0x2c
movwf _vitesse+12
movlw 0x2d
movwf _vitesse+13
movlw 0x2e
movwf _vitesse+14
movlw 0x2f
movwf _vitesse+15
bcf STATUS,RP0
bcf STATUS,RP1
}
cmd_moteur = 0;
TRISC=0b11000000;
TRISB = 0;
PORTB = 0b10001000;
m = 3; // à supprimer ( m sera initialisée dans
// la réception de la commande de mise
// en marche simultanée des deux moteurs)!!!
Usart_Init(9600);
PIR1.RCIF = 0; // clear USART RCIF
PIR1.TMR1IF = 0; // clear TMR1IF
// T1CON.TMR1ON = 1; // Timer1 Enabled on internal clock
INTCON = 0x80; // enable general interrupt
PIE1.RCIE = 1; // enable interrupts USART Reception
// PIE1.TMR1IE = 1; // enable interrupts TMR1
INTCON.PEIE = 1; // enable interrupts TMR1 and USART
while (1);
}
-----