DAC with PIC16F877

Discussion in 'Embedded Systems and Microcontrollers' started by CVMichael, Sep 3, 2008.

  1. CVMichael

    Thread Starter AAC Fanatic!

    Aug 3, 2007
    First I tried to convert digital to analog using resistors, and many digital bits, but I find it such a waste of binary bits this way.

    Then I had the idea to charge a capacitor by giving it impulses from the PIC using only one bit.

    This is what I did:

    I did not calculate any of the resistor/capacitor, I just approximated...

    And this is the code in MikroC
    Code ( (Unknown Language)):
    2. void main() {
    3.      unsigned int adc0 = 0;
    4.      unsigned int adc1 = 0;
    6.      ADCON0 = 0x80;
    7.      TRISA  = 0xFF;
    9.      PORTD = 0;
    10.      TRISD = 0;
    12.      do {
    13.           adc0 = Adc_Read(0);
    14.           adc1 = Adc_Read(1);
    16.           if (adc0 > adc1)
    17.                PORTD.F4 = 1;
    18.           else
    19.                PORTD.F4 = 0;
    20.      } while (1);
    21. }
    So all it does is to try to mimic the analog input 0.

    But this was just a test, I plan to use the analog generated to change the power of a stepper mottor. At low RPM I plan to give lower power, and increase the power as I increase the RPM.

    I don't have an assciloscope to see exactly the output of the generated analog, but measuring with a voltmeter it seems pretty good.

    Is is good enough for changing the power of a stepper motor ?

    By the way, I plan to connect the analog output to a transistor that will be connected to the stepper motor driver, I don't plan to connct it directly (in case you are thinking about that)...

    PS. The microcontroller is running at 20 MHz
    Last edited: Sep 3, 2008
  2. SgtWookie


    Jul 17, 2007
    Ahh, it's "oscilloscope" :)

    Well, usually one would use a current sense resistor to determine the current flowing through a stepper motor. Look up the datasheets for L297 and L298.

    But I think you like playing with hardware a bit more than that ;)

    So, take a look at the LiniStepper:
    I think this is a pretty neat thing for do-it-yourselfers. It's all open source; all of the schematics, board layouts, source code, theory of operation, everything is right there. They even use PICs to control the board to control the stepper motor. You could use your PIC16F877 to control a bunch of those things.

    Or, you could learn a lot from how that one works, and perhaps build a better mousetrap :)
  3. CVMichael

    Thread Starter AAC Fanatic!

    Aug 3, 2007
    Thanks for the link, I will go through it as soon as I can.

    Do you know any better ways to convert from digital to analog ? (something more precise, and that does not take too many bits off the microcontroller ?)

    Also... What do you mean by this ? :
    So I find out the current flowing... what then ?

    I want to change the power of the stepper motor depending on the demand, instead of giving it full power all the time. This way it won't depleate the batteries too fast...
    Last edited: Sep 4, 2008
  4. SgtWookie


    Jul 17, 2007
    It's really a very informative site. It's somewhat rare to find someone willing to make freely availabe a stepper motor controller with such versatility.
    Actually, the PIC16F877A has two PWM channels, and a 10-bit ADC (Analog to Digital Converter) with 8 channels.
    With PWM, you can charge/discharge a suitably-sized capacitor via a suitably-sized resistor. After about 5 RC time constants have gone by, the capacitor will have a charge of (ON time/OFF time) x Vdd. It would be best to limit maximum current on the I/O pin to <=10mA in order to decrease thermal rise in the IC itself, even though the uC is rated for 25mA. If you're running on batteries, consider limiting max current to <1mA.
    Rlimit = E/I; since E=5v, you can plug in the other numbers yourself. ;)

    An L297 is a stepper motor controller IC, and an L298 is an H-bridge. H-bridges are very useful for controlling both plain DC motors and stepper motors. The L297 datasheet from ST Microelectronics shows the basic interconnections on page 1.
    When the voltage across the sense resistor exceeds the limit you have set, you turn off the MOSFET that is providing a current path to Rsense for a period of time, and then turn it back on. It's a form of PWM, but sensed by the actual current through the motor, and controlled by the current flow limit that you have set.
    You're much better off using PWM control rather than something linear. Try to read and understand the L297 datasheet.