What's wrong with my DC motor !?

Discussion in 'Embedded Systems and Microcontrollers' started by josephgebran, Jun 20, 2011.

  1. josephgebran

    Thread Starter New Member

    Jun 5, 2011
    10
    0
    Hello all, i am working on a simple DC motor control in 1 direction only. I will attach the code written in HITECH C Compiler for PIC16F887.
    Code ( (Unknown Language)):
    1. #include <htc.h>
    2. #include <stdlib.h>
    3. #define _XTAL_FREQ 8000000
    4. #define  TMR2_PRESCALER 4
    5.  
    6. __CONFIG(0x28C4);    // config word 1
    7. __CONFIG(0x3eff);    // config word 2 (in sequence)
    8.  
    9.  
    10. #define byte unsigned char
    11. #define word unsigned int
    12. #define dword unsigned long
    13.  
    14.  
    15. typedef union _word_VAL
    16. {
    17.     word Val;
    18.     struct { byte LB; byte HB; } byte1;
    19. } word_VAL;
    20.  
    21. byte x1,x2,x3,speed;
    22. byte ccpr1l_copy,ccpr2l_copy;
    23. void PWM1_Init(word x),PWM1_Set_Duty(byte x),PWM1_Start(),PWM1_Stop();
    24. void PWM2_Init(word x),PWM2_Set_Duty(byte x),PWM2_Start(),PWM2_Stop();
    25. void init();
    26.  
    27. void Move_Forward(int speed);
    28. void Clutch();
    29.  
    30. void main()
    31. {
    32.     init();
    33.     while(1)
    34.     {speed=1;
    35.     Move_Forward(speed);
    36.     __delay_ms(2000);
    37.     Clutch();
    38.     __delay_ms(2000);
    39.     speed=3;
    40.     Move_Forward(speed);
    41.     __delay_ms(2000);
    42.     Clutch();
    43.     __delay_ms(2000);
    44. }  
    45. }           // End main program
    46.  
    47. void init()
    48. {
    49. OSCCON=0b01110001;   //frequency = 8M
    50. ANSEL=0b1110000;     //Enable PortA Analog Input,AN4,AN5,AN6
    51. ANSELH=0;            //Disable PortB Analog Input
    52. C1ON=0;              //turn off
    53. C2ON=0;              //comparators
    54. TRISA=0b11110000;    //RA0,RA1,RA2,RA3 Digital Outputs for stepper motor of Camera,AN4 Analog Input for Light Sensor
    55. TRISB=0b11101011;    //RB2,RB4 Digital Outputs for Horn and Flashlight
    56. TRISC=0b11110000;    //RC0,RC3 Digital Outputs for DC motor, CCP1,CCP2 for PWM Output
    57. TRISD=0b11000000;    //RD0,RD1,RD2,RD3 Digital Outputs for stepper motor of Robot ,RD4 Digital Output for Camera,RD5 Digital Output for Clutch
    58. T2CON=0b00000001;    // prescaler=4
    59. CCP1CON=0b00001100;
    60. CCP2CON=0b00001100;
    61. CCPR1H=CCPR1L=CCPR2H=CCPR2L=0;
    62. ccpr1l_copy=ccpr2l_copy=0;
    63. PWM1_Init(5000);   //Initialize PWM modules at
    64. PWM2_Init(5000);   //5KHz frequency
    65. RCSTA=0b10010000;
    66. TXSTA=0b00100100;
    67. BAUDCTL=0b00000000;
    68. SPBRG=207;
    69. }
    70.  
    71. void Move_Forward(int speed)
    72. { byte current_duty;
    73.         switch(speed)
    74.         { case 1:
    75.             current_duty = 20;
    76.             break;
    77.           case 2:
    78.             current_duty = 127;
    79.             break;
    80.           case 3:
    81.             current_duty = 240;
    82.             break;
    83.           case 0:
    84.             RC0=0;
    85.             PWM1_Stop();
    86.             break; }
    87.    if (current_duty!=0)      
    88.    
    89.     {PWM1_Set_Duty ( current_duty );
    90.    PWM1_Start();
    91.    RC0=1; }
    92. }
    93.  
    94.  void Clutch()
    95.  { RD5=1;
    96.    RC0=0;
    97.    RC3=0;
    98.    PWM1_Stop();
    99.    PWM2_Stop();
    100.    }
    101.  
    102. void PWM1_Init(word x)
    103. {
    104. PR2=((_XTAL_FREQ/(4*TMR2_PRESCALER))/x)-1;
    105. }
    106.  
    107. void PWM1_Set_Duty(byte x)
    108. {
    109. ccpr1l_copy=x*(PR2+1)/100;
    110. }
    111.  
    112.  
    113. void PWM1_Start()
    114. {  
    115. CCPR1L=ccpr1l_copy;
    116. }
    117.    
    118. void PWM1_Stop()
    119. {
    120. CCPR1L=0;  
    121. }
    122.    
    123. void PWM2_Init(word x)
    124. {
    125. PR2=(500000/x)-1;  
    126. }
    127.  
    128. void PWM2_Set_Duty(byte x)
    129. {
    130. ccpr2l_copy=x*(PR2+1)/100;
    131. }
    132.  
    133.  
    134. void PWM2_Start()
    135. {
    136. CCPR2L=ccpr2l_copy;
    137. }
    138.    
    139. void PWM2_Stop()
    140. {
    141. CCPR2L=0;    
    142. }
    143.    
    I Connected the circuit, and the motor is rotating for 2 seconds, stops for 2 seconds, and then rotates again for 2 seconds but i can't feel any difference in its rotation speed ! Help. Thank You
     
  2. #12

    Expert

    Nov 30, 2010
    16,304
    6,814
    You might get better results by posting this in "Embedded systems and microcontrollers". The people who watch that forum would likely be able to read your code.
     
  3. stahta01

    Member

    Jun 9, 2011
    133
    21
    The first problem is that you are trying to put a value bigger that 255 into a single byte like ccpr2l_copy.

    Tim S.

    Code ( (Unknown Language)):
    1. ccpr2l_copy=x*(PR2+1)/100;
    20 * 5 = 100
    240 * 5 = 0x4B0 (0xB0 is 176)
    These are rough guesses on the values, the difference 100 and 176 might not be noticeable.
     
  4. josephgebran

    Thread Starter New Member

    Jun 5, 2011
    10
    0
    I didn't exactly understand what part of the equation i should change, can u please help me again?
     
  5. stahta01

    Member

    Jun 9, 2011
    133
    21
    You need a variable large enough to hold the result; an Byte can NOT hold a value larger than 255.

    Tim S.
     
  6. #12

    Expert

    Nov 30, 2010
    16,304
    6,814
    Excellent! Old farts like me lurk in the Chat and Projects section. We can be very good with beginners, but several of us haven't learned microprocessors. Glad to see this getting some work done.

    good luck!
     
  7. josephgebran

    Thread Starter New Member

    Jun 5, 2011
    10
    0
    Stahta i know a byte can't have a value bigger than 255 but my question was can i use sth else than ccpr2l ?!
     
  8. stahta01

    Member

    Jun 9, 2011
    133
    21
    Lookup CCPR1L and CCPR1H (or CCPR2L and CCPR2H) in the datasheet.
    Use Division and Modulus "%" to separate the 16 bit result.

    Tim S.
     
  9. josephgebran

    Thread Starter New Member

    Jun 5, 2011
    10
    0
    can u help me with the equation? i mean if i want to seperate the 16 bits into two 8 bits, i will divide the number by what?!
     
  10. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,392
    1,605
    I am unfamiliar with the Hitech C compiler, I've done something similar with the Sourceboost C compiler. You may need to translate this to work.

    What I have is a 10 bit number residing in PWMset, defined as unsigned short (16 bit unsigned number). We need the least significant bit into the DC1B0 bit of CCP1CON, the next bit into the DC1B1 bit of CCP1CON, and the next 8 bits into CCPR1L. The individual bits are each coppied one at a time, then the 8 bits are found by shifting over the 2 places and assigning, like so:

    Code ( (Unknown Language)):
    1.  
    2.         unsigned short    PWMset;
    3. ...
    4.  
    5.         ccp1con.DC1B0 = PWMset.0;    // first change 2 LSB's
    6.         ccp1con.DC1B1 = PWMset.1;
    7.         ccpr1l = PWMset>>2;          // now copy over MSB
     
Loading...