Pulse Width Modulation PWM using 16f84a and H-bridge

Discussion in 'Programmer's Corner' started by hbyte, Aug 18, 2012.

  1. hbyte

    Thread Starter New Member

    Aug 18, 2012
    4
    0
    I have a H-bridge that I wish to use to change the direction of a dc motor - works well using 16f84a to switch between pins connected to the h-bridge running at full speed without using PWM.

    The problem I have is when I implement PWM using a function I can no longer switch from one pin to the other. Here is the source code which compiles using Hi-Tech C. The result is that the comparitor is not realised
    and the state is not changed - only 1 pin remains active throughout using PWM. How can I acheive this using this MCU?

    Code ( (Unknown Language)):
    1.  
    2. #include <htc.h>
    3. #include <stdlib.h>
    4. #include <stdio.h>
    5. #include <pic16f84a.h>
    6.  
    7. unsigned int i;
    8.  
    9. #define __16F84A
    10.  
    11.     __CONFIG(CP_OFF & WDTE_OFF & PWRTE_ON & FOSC_XT);
    12.  
    13. /*PWM function*/    
    14. void _pwm(unsigned int state)
    15. {
    16.  
    17. unsigned int i;
    18.  
    19. for(i=0;i<1000;i++){
    20.  
    21. if(i>700){
    22. if(state==1){
    23. PORTB = 0b00010000;
    24. }
    25. else{
    26. PORTB = 0b00001000;
    27. }  
    28. }else{
    29. PORTB=0;
    30. }
    31.  
    32. }
    33.  
    34.         }
    35.  
    36.  
    37.  
    38.  
    39.  
    40.  
    41.  
    42. void main(void) {
    43.   /* set both ports as outputs */
    44.   TRISA = TRISB =0b00000000;   //0;
    45.  
    46.   /* start with 0V on all output pins/ports */
    47.   PORTA = 0;
    48.   PORTB = 0;
    49.  
    50. unsigned int state,t,i;
    51.  
    52.   /* an infinite loop; for ever run the following code */
    53.   while(1) {
    54.    
    55.   t++;
    56.  
    57. if(t>400000){         //why isnt this realised ?
    58. t=0;
    59. if(state==1){state=2;}else{state=1;}
    60.  
    61.  
    62.  
    63. }
    64.    
    65. _pwm(state);
    66.      }
    67.  
    68.  
    69.  
    70. }
    71.  
     
    Last edited by a moderator: Aug 18, 2012
  2. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    t is an unsigned int. What is the largest value an unsigned int can hold?
     
  3. hbyte

    Thread Starter New Member

    Aug 18, 2012
    4
    0
    Ok thanks for that , the maximum size I presume to be below the comparitor value. What can I use instead - will "int" suffice instead of "unsigned int" .

    Your help is appreciated.
     
  4. BAdhi

    New Member

    Jul 26, 2012
    5
    0
    Also i think that t is not initialized so you don't know it's initial value
     
  5. BMorse

    Senior Member

    Sep 26, 2009
    2,675
    234
    Unsigned Int max value is 65535 (16 Bits)

    the Value he is using to compare is 19 bits (400000)

    so 't' will just keep rolling over once 65535 is reached and will never reach 400000......
     
  6. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
  7. BMorse

    Senior Member

    Sep 26, 2009
    2,675
    234
    Yup, that is what I would do :) since that is a 32 bit int .... or even an unsigned short int which is 24 bits.....
     
  8. hbyte

    Thread Starter New Member

    Aug 18, 2012
    4
    0
    Neither unsigned long or unsigned short int works, initialised t=0 (thanks) and
    used ++t instead of t++.

    None of these changes the state/pins.

    The comparitor just doesnt work regardless of what type of int I am using.
    This seem's so trivial but I cant see the answer!
     
  9. BMorse

    Senior Member

    Sep 26, 2009
    2,675
    234
    could be your problem right here, you have 2 else statements, the last statement will always assign 0 to PORTB if state is not = to 1.

    Remove the last else and see what happens....
     
  10. hbyte

    Thread Starter New Member

    Aug 18, 2012
    4
    0
    If you can try testing it yourself. This part works ok it needs the second else to satisfy the pwm :-

    psuedo code:

    for (i=0;i<total;i++)
    if i<value
    then
    portb = 0;

    the duty cycle would be value/total * 100

    therefore

    value ~ motor speed

    If you start with state=2 then the motor turns in the opposite direction and stays there at a fixed speed dictated by the pwm the opposite direction for state=1.

    It is definately not realising the 2nd comparitor. It should change direction every 400000 cycles.
     
Loading...