stepper motor and PIC 16F877

Thread Starter

Electronic.art

Joined Feb 19, 2011
8
Hello,

Exuse my bad English

Topic: I ordered two unipolar stepper motors 6 son, "using the two control circuits L297 and L298, under the control of PIC 16F877 that receives commands from a PC connected by a DB9-max 232,

http://img4.hostingpics.net/pics/317592forum.png

For this I must set the USART and timer1.

Problem: I compile without problem, but when I simulate the linking COMUNICATION TERMINAL with Proteus engines do not run properly
 

Thread Starter

Electronic.art

Joined Feb 19, 2011
8
Thank you for your help, here is my code written in mikroC for PIC version 8:

Rich (BB code):
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 speed [16];
unsigned short int cmd_moteur;



/ *

   Order Received:
         b7: Controls 1: 0 Speed: Commands
         b6: Engine Choice 1: 2 0 Engine: Engine 1
         b5: Marche_Arret 1: On 0: Off
         b4: Motor1 Sense 1: 0:
         b0-b3: Speed Engine


   Devices:
         cmd_recu = 1: Judgement of the two engines (cmd_moteur = 1)
         cmd_recu = 2: Engine 1 and Engine 2 in March (cmd_moteur = 2)
         cmd_recu = 4: Engine 1 Engine 2 in March and off (cmd_moteur = 4)
         cmd_recu = 8: Engine 1 and Engine 2 to Off in March (cmd_moteur = 8)


   PortB Pin Assignment:
         RC2: Enable Engine 2
         RC1: Enable Engine 1
         RB4: Sense Engine 2
         RB0: Sense Engine 1
         RB5: Motor Control 2
         RB1: 1 Motor Control

* /





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 / / Controls if bit7 = 0
        goto command


        btfsc cmd_recu, 6 / / Engine ...
        goto moteur2

        btfss cmd_recu, 5 / / Marche_Arret Engine 1
        bcf PORTC, 1 / / Stop Motor 1

        btfsc cmd_recu, 4 / / Direction of Engine ...
        goto sens2_Moteur1

        bsf PORTB, 0 / / Motor 1 Direction 1
        goto vitesse_moteur1
sens2_Moteur1:
        bcf PORTB, 0 / / Motor 1 Direction 2

vitesse_moteur1:
        movlw 0x0f
        andwf cmd_recu, 1 / / cmd_recu & 0x0f -> cmd_recu

        movlw speed
        ADDWF cmd_recu, 0 / / address vitesse_L [cm_recu] -> W
        movwf FSR / / W -> FSR: register indirect addressing
        movf INDF, 0 / / vitesse_L [cmd_recu] -> W
        movwf tmoteur1_L

        bsf STATUS, IRP / / Addressing the area 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 Engine 2
        bcf PORTC, 2 / / Stop Motor 2

        btfsc cmd_recu, 4
        goto sens2_Moteur2

        bsf PORTB, 4 / / Direction 1 Engine 2
        goto vitesse_moteur2
sens2_Moteur2:
        bcf PORTB, 4 / / Sens 2 Engine 2

vitesse_moteur2:
        movlw 0x0f
        andwf cmd_recu, 1 / / cmd_recu & 0x0f -> cmd_recu

        movlw speed
        ADDWF cmd_recu, 0 / / address vitesse_L [cmd_recu] -> W
        movwf FSR / / W -> FSR: register indirect addressing
        movf INDF, 0 / / vitesse_L [cmd_recu] -> W
        movwf tmoteur2_L


        bsf STATUS, IRP / / Addressing the area 0x120 - 0x16f
        movf INDF, 0 / / vitesse_H [cmd_recu] -> W
        movwf tmoteur2_H
        bcf STATUS, IRP



        goto fin_vitesse




commands:
        btfsc cmd_recu, 0
        goto arret_total

        btfsc cmd_recu, 1
        goto Start

        btfsc cmd_recu, 2
        goto market.1

        btfsc cmd_recu, 3
        goto market2


        goto fin_vitesse / / Return if another command ...


arret_total: / / Judgement of 2 Engines
        bcf PORTC, 1 / / Enable disabled
        bcf PORTC, 2
        movlw 1
        movwf cmd_moteur / / save the state of the command
        bcf T1CON, 0 / / Stop the Timer 1: TMR1ON = 0
        bsf STATUS, RP0 / / Bank 1
        bcf PIE1, 0 / / Disable interr.Timer 1
        bcf STATUS, RP0 / / Bank 0
        Bcf PIR1, 0 / / Clear the flag of Timer 1
        goto fin_vitesse

On: / / Starting of Motors 2
        bsf PORTC, 1
        bsf PORTC, 2
        movlw 2
        movwf cmd_moteur
        tso T1CON, 0 / / Start Timer 1: TMR1ON = 0
        bsf STATUS, RP0 / / Bank 1
        bsf PIE1, 0 / / Enable interr.Timer 1
        bcf STATUS, RP0 / / Bank 0
                                    / / Add to comparison between t1 and t2
                                    / / To determine the value of 'm' !!!!!!

        goto fin_vitesse

Market.1: / / Engine 1 start
        bsf PORTC, 1
        bcf PORTC, 2
        movlw 4
        movwf cmd_moteur
        tso T1CON, 0 / / Start Timer 1: TMR1ON = 0
        bsf STATUS, RP0 / / Bank 1
        bsf PIE1, 0 / / Enable interr.Timer 1
        bcf STATUS, RP0 / / Bank 0
        goto fin_vitesse

Market2: / / motor 2 reverse
        bcf PORTC, 1
        bsf PORTC, 2
        movlw 8
        movwf cmd_moteur
        tso T1CON, 0 / / Start Timer 1: TMR1ON = 0
        bsf STATUS, RP0 / / Bank 1
        bsf PIE1, 0 / / Enable 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 / / Skip ...
            goto retour_interr

            nop / / Disable the timer!
            goto retour_interr


     }

/ / Control of both engines ...
     asm {
Marche_:
           nop
     }


     if (m == 1) / / the Timer1 has been assigned to Engine 1
     {
        / / PortB.F1 PortB.F1 = ~ / / reverse the order of the engine 1
/ / T1 = tm1;

          asm {

              movlw 0x02
              xorwf PORTB, 1

              movf tmoteur1_L, 0 / / reload t1 which was amended
              movwf _t1
              movf tmoteur1_H, 0
              movwf _t1 1

          }
     }
     else if (m == 2) / / the Timer1 has been assigned to Engine 2
     {
        / / PortB.F5 PortB.F5 = ~ / / reverse motor control 2
/ / T2 = tm2;

          asm {
          
              movlw 0x20
              xorwf PORTB, 1

              movf tmoteur2_L, 0 / / reload t2 which was amended
              movwf _t2
              movf tmoteur2_H, 0
              movwf _t2 1

          }


     }
     else if (m == 3) / / Timer1 is assigned to the 2 engines
     {
      / / PortB.F1 PortB.F1 = ~ / / reverse the order of 2 engines
      / / = ~ PortB.F5 PortB.F5;
/ / T1 = tm1;
/ / T2 = tm2;

          asm {
          
              movlw 0x02
              xorwf PORTB, 1
              
              movlw 0x20
              xorwf PORTB, 1

              movf tmoteur1_L, 0 / / reload t1 and t2
              movwf _t1
              movf tmoteur1_H, 0
              movwf _t1 1

              movf tmoteur2_L, 0 / / reload t2 which was amended
              movwf _t2
              movf tmoteur2_H, 0
              movwf _t2 1

          }
     }


     if (t1 <t2) / / Timer1 will be assigned to Engine 1
     {
        t2 = t2-t1 / / t2 modified
        TTMP ~ = t1;
/ / = TMR1L TTMP;
/ / TMR1H TTMP =>> 8;

          asm {

              movf _ttmp, 0 / / Load Timer1 t1
              movwf TMR1L
              movf _ttmp 1.0
              movwf TMR1H

          }

        m = 1;
     }
     else if (t1> t2) / / Timer1 will be assigned to Engine 2
     {
        t1 = t1-t2 / / modified t1
        TTMP ~ = t2;
/ / = TMR1L TTMP;
/ / TMR1H TTMP =>> 8;

          asm {

              movf _ttmp, 0 / / Load Timer1 t1
              movwf TMR1L
              movf _ttmp 1.0
              movwf TMR1H

          }

        m = 2;
     }
     else / / Timer1 will be awarded to 2 engines
     {
        TTMP ~ = t1;
/ / = TMR1L TTMP;
/ / TMR1H TTMP =>> 8;

          asm {

              movf _ttmp, 0 / / load Timer1 with t1 = t2
              movwf TMR1L
              movf _ttmp 1.0
              movwf TMR1H

          }

        m = 3;
     }

     asm {

        goto retour_interr
     }




/ / Motor Control 1 only ...
    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

   }
 
Last edited by a moderator:

Thread Starter

Electronic.art

Joined Feb 19, 2011
8
Rich (BB code):
/ / Motor Control 2 only ...
   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;

/ *
speed [0] = 0x10;
speed [1] = 0x11;
speed [2] = 0x12;
speed [3] = 0x13;
speed [4] = 0x14;
speed [5] = 0x15;
speed [6] = 0x16;
speed [7] = 0x17;
speed [8] = 0x18;
speed [9] = 0x19;
speed [10] = 0x1a;
speed [11] = 0x1b;
speed [12] = 0x1c;
speed [13] = 0x1d;
speed [14] = 0x1e;
speed [15] = 0x1f * /

speed [0] = 0;


asm {


        bcf STATUS, RP0
      bcf STATUS, RP1

        movlw 0x10 / / Loading of LSB
        movwf _vitesse / / speed instructions in the address
        movlw 0x11 / / _vitesse located in 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 / / Load the MSB of
        movwf _vitesse / / speed instructions in the address
        movlw 0x21 / / _vitesse located in 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;

  Trisca = 0b11000000;
  TRISB = 0;
  PORTB = 0b10001000;

  m = 3 / / to remove (m will be initialized in
                                    / / Receiving the setting command
                                    / / Start both engines simultaneously)!


  Usart_Init (9600);

  PIR1.RCIF = 0, / / clear USART ROTI
  PIR1.TMR1IF = 0, / / clear TMR1IF

/ / T1CON.TMR1ON = 1 / / Timer1 Enabled internal clock is
  Intcons = 0x80, / / enable general interrupt

  PIE1.RCIE = 1 / / enable USART interrupts Reception
/ / PIE1.TMR1IE = 1 / / enable TMR1 interrupts
  INTCON.PEIE = 1 / / enable TMR1 interrupts and USART



while (1);



}
 
Last edited by a moderator:

spinnaker

Joined Oct 29, 2009
7,830
First this post should be in the embedded forum.

Why are you programming in C but using so much assembler? There really should be no need for that. If you want to program in assembly then just use an assembler. But you really should use C it will be much easier.

You are trying to do too much all at once. If I understand you correctly, you are having a problem communicating to the terminal in Proteus.

Write a small program to do just that. Something simple like to display "Hello World" on the terminal. You can then move on from there.

If you have a more simple program you will increase your chances that someone can help you. Programming in C might also help.
 

Thread Starter

Electronic.art

Joined Feb 19, 2011
8
Yes normally that's right, here is the algorithm that I wrote before programming:

Algorithm: For the USART:
Communication takes place on two pins and RC6/TX RC7/RX.
For transmission:
1 - Ensure that the TXI interrupt is not enabled.
2 - Configure TX/RC6 pin input.
3 - Configure registry TXSTA.
4 - Initialize the register SPBRG to set the baud rate
5 - Place the data to be transmitted in TXREG.

For reception:
1 - Ensure that the RCI interruption is not validated .
2 - Configure RX/RC7 pin input.
3 - Initialize SPBRG register to set the speed of the reception.
4 - Configure registry RCSTA.
5 - Wait flag ROTI which gives the end of the reception. [1], [2], [6] [7]


The flowchart of main program:
Senior Program -> Configure I / O ports ---> Upload speeds > Setup > Configuration-USART-Timer1 interrupts > OK


The flowchart of subroutine interrupt processing:
Interruption -> A byte received ->
If yes: The disruption caused by the USART Interrupt Processing   End of interrupt processing

If no: Timer1 Overflow
If yes: The disruption caused by Timer1 Interrupt Processing > End of interrupt processing
If not: Back to the main program (main)

The flowchart of subroutine treatment interruption caused by the USART

The interruption caused by the USART > Return the flag to "0"
PIR1.RCIF = 0 > cmd_recu = Data received
If yes: The data received is a Command
If no: The data received is a speed



chart of the console command:
Data received is a control>B = 6 mode control console
The different orders start are determined as follows:
cmd_recu = 00000001 Total Stop (Stop both engines).
cmd_recu = 00000010 Walk (Start both engines).
cmd_recu = 00000100 March 1 (Start and stop the moteur2 MOTOR 1).
cmd_recu = 00001000 March 2 (Start and stop the moteur2 MOTOR 1).


Console control >cmd_recu = 1
If yes: Blackout cmd_moteur = 1 > Stop 2 Engines, Off TMR1> Fin_interr
If no: cmd_recu = 2
If yes: Start >total cmd_moteur = 2 Start the 2 motors, activated TMR1> Fin_interr
If no: cmd_recu = 4
If yes: Start > cmd_moteur = 4, moteurs2 Stop, Start MOTOR 1, off TMR1 > Fin_interr
If yes: cmd_recu = 8> cmd_moteur Marche 2 = 4, moteurs1 Stop, Start moteur2, off TMR1 > Fin_interr
If not: Blackout > cmd_moteur = 1, Stop 2, Engines, Off TMR1 >Fin_interr


The flow chart for determining the speed
> speed B6 = 1
If yes: Engine 2 > B5 = 0
If yes > Portc.F2 = 0, Judgement of moteur2 B4 = 1 >
If yes Sens2 > Determination of moteur2 speed moteur2 > Load Timer1 Fin_vitesse
If not> Direction 1 of moteur2 Determination speed moteur2 > Load Timer1 Fin_vitesse
Same diagram for motor 2
 

spinnaker

Joined Oct 29, 2009
7,830
Sorry should have been debug above. What have yo done to debug.

And you never answered why you are using so much assembler in C. You are only making things a lot harder for yourself.
 

spinnaker

Joined Oct 29, 2009
7,830
I use mikroC because at school we were taught to use mikroC, the program seems to work correctly, I think I have an error in the schema!
Then use C and not in line assembler.

The code is not correct if it is nor working as expected.

An error in the schema? What do you mean by schema?
 

spinnaker

Joined Oct 29, 2009
7,830
You need to convert to all C and simplify your code. Get rid of all of those gotos/ It is no wonder you are having problems, as we say it is spaghetti code.
 
Top