Generate sawtooth with PIC?


Closed Thread
Results 1 to 11 of 11
  1. #1
    Join Date
    Jan 2009
    Posts
    22

    Default Generate sawtooth with PIC?

    I'd like to generate a sawtooth wave, 0 to +1.5v at several hundred Hz up to 1 kHz on a 16F690 or similar, to generate a time base for CRT.

    Suggestions for an efficient way to do this on a PIC?

    My alternatives are a 555 and RC circuit or parallel DAC. I've tried an I2C DAC, but it's too slow with I2CWRITE commands.

    Thanks.

  2. #2
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default Sawtooth wave form

    One way to do it would be to use Darrel Taylor's instant interrupts and PWM with a lookup table.

    You could use this code on a PIC18, and just change the lookup values to a linear increase, dropping back to zero when it gets to 1.5v. http://www.picbasic.co.uk/forum/cont...-DT-interrupts . You would have to modify the speed of the interrupt. You could probably get by with a lot less steps.

    For instance, the sinewave generated by the above code, is kind of like the red sine wave in this picture. If you were to change all the values in the lookup, you could generate your sawtooth, like the one in blue.

    You can pretty much change the lookup table to create any wave form you like. Since your's is linear, you wouldn't really need a lookup table, you could just do some addition inside your interrupt handler, to increase the duty. And drop to zero after reaching X.



    Let us know how it goes, whichever way you choose to go.

    Walter
    Attached Images Attached Images  
    Last edited by ScaleRobotics; - 2nd August 2010 at 17:48.
    http://www.scalerobotics.com

  3. #3
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default

    ... Or you can use a CLD. (see this application note) http://www.centralsemi.com/PDFs/prod...tion_notes.pdf

    Al.
    All progress began with an idea

  4. #4
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,615


    Did you find this post helpful? Yes | No

    Post

    Quote Originally Posted by gmglickman View Post
    I'd like to generate a sawtooth wave, 0 to +1.5v at several hundred Hz up to 1 kHz on a 16F690 or similar, to generate a time base for CRT.

    Suggestions for an efficient way to do this on a PIC?

    My alternatives are a 555 and RC circuit or parallel DAC. I've tried an I2C DAC, but it's too slow with I2CWRITE commands.

    Thanks.
    Hi,

    missing how many bits for resolution ...

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  5. #5
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Default

    If you build a D->A using an R-2R ladder network, my guess is that you could get well over 3Khz with 8 bit resolution. Simply increment a value and write it to a port. No need to do more, since 255 + 1 = 0.
    Charles Linquist

  6. #6
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Default

    I keep forgetting that you may be running at 4Mhz. In that case your max freq may be lower. I run everything at 40Mhz, so my comments are calibrated to that value.
    Charles Linquist

  7. #7
    Join Date
    Jan 2009
    Posts
    22


    Did you find this post helpful? Yes | No

    Default Generate sawtooth wave with PIC -- software solution.

    Great suggestions by some of the most knowledgable contributors to the list.

    I elected to go with a simple software approach using PWM, without lookup tables. Most of the code is to provide DT's Instant Interrupt.

    I initialize the 16F690 HPWM at 32kHz, zero duty. With each TMR1 interrupt I increment the duty register until I reach the desired maximum voltage on the sawtooth, then start over at zero. A low-pass RC filter smooths the output. Peak voltage and frequency are easily modified. I retained the oscope interrupt timing signal on RC.4; you will have to change some parameters if this is omitted.

    Other ways to tackle this include a 555-based generator, R2R ladder network or dedicated parallel-interface DACs. Microchip has an application note http://www.microchip.com/stellent/id...pnote=en011071 that may be helpful.

    Gary

    Code:
    '****************************************************************
    '*  Name    : oscope clock 16F690 sawtooth generator
    '*  Author  : gmg        Copyright (c) 2010 (yeah, right...)                                       
    '*  Date    : 7/28/2010                                                                            
    '*  Notes   : generates sawtooth wave for CRT time base 
    '            Horiz: 1.5v=10 div, Vert: 2.0v=8 div max on CRT
                passive low pass RC filter on PWM output RC.5         
    '************************************************************
    @ __config _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _CP_OFF & _WDT_OFF
    ADCON1=$0F                    'disable A/D 
    VRCON=0                       'volt ref off      
    CM1CON0.0=0 : CM2CON0.0=0   	'comparators off
    ANSEL=0 : ANSELH=0
    OSCCON=%01110000              ;8MHz intosc
    DEFINE OSC 8
    '-------------- pins
    'PWM_out           var    portc.5
    TRISC=0:TRISB=0
    PORTC=0: PORTB=0
    '-------------- variables
    version		con	107
    i               var      byte
    j               var      byte
    temp            var      BYTE 
    tempword        var      word
    duty_reg        var      word
    HLevel          var      byte
    VLevel          var      byte
    HOrigin         var      byte
    CLEAR
    read 0, temp
    if temp<>version then write 0, version	'store sw version in EEPROM 0
    
    '----  setup HPWM on PORTC.5
    hpwm 1, 0, 32000 		'32kHz PWMN out on PORTC.5
    
    '----- setup DT instant interrupt TMR1            
    INCLUDE "DT_INTS-14.bas"     ; Base Interrupt System
    INCLUDE "ReEnterPBP.bas"     ; Include if using PBP interrupts  (cf. asm interrupts)
    ASM
    INT_LIST  macro ;            IntSource,    Label,      Type,  ResetFlag?
                    INT_Handler   TMR1_INT,   ReloadTMR1,   ASM,  no    ; MUST be first
                    INT_Handler   TMR1_INT,   _T1handler,   PBP,  yes
        endm                                                                                  .
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    @Freq       = 6000                 ; interrupt frequency, 1.7msec period gives 600Hz screen sweep
    @Prescaler  = 1                   ; Timers Prescaler setting
    T1CON = $00                       ; $30 = Prescaler 1:8, TMR1 OFF   ; $00=1:1, $10=1:2, $20=1:4, $30=1:8 --  NB: T1CON Must match @Prescaler value
    @ INT_ENABLE  TMR1_INT            ; enable Timer 1 interrupts
    GOSUB StartTimer                  ; Start the Timer
    
    '-------   Main
    while 1=1		'loop forever   
    wend
    
    ;____This routine is Called on each TMR1 Interrupt____________________________
    T1handler:
           ISR:          
    duty_reg=duty_reg+1
    if duty_reg>140 then duty_reg=0       'increment duty_reg each interrupt for ramp function     
    trisc.5=1
    CCP1CON.4=duty_reg.0                 '10bit PWM 
    CCP1CON.5=duty_reg.1 
    tempword=duty_reg & %1111111100
    CCPR1L=tempword>>2
    trisc.5=0 
       HIGH PORTC.4    		'TEMP oscope timing pulse, retained to preserve timing
       PAUSEUS 10                
       LOW PORTC.4     
    @ INT_RETURN
    
    ;---[TMR1 reload - interrupt handler]-----------------------------------------
    ASM                               ; Calculate Timer Reload Constant
    ReloadInst  = 8                   ; # of Intructions used to reload timer
      if ((Prescaler == 1)||(Prescaler == 2)||(Prescaler == 4)||(Prescaler == 8))
    MaxCount    = 65536 + (ReloadInst / Prescaler)
    TimerReload = MaxCount - (OSC*1000000/4/Prescaler/Freq)
        if ((TimerReload < 0) || (TimerReload > (65535-ReloadInst)))
            error Invalid Timer Values - check"OSC", "Freq" and "Prescaler"
        endif
      else
          error Invalid Prescaler
      endif
    ENDASM
    
    @Timer1 = TMR1L                   ; map timer registers to a word variable
    Timer1       VAR WORD EXT
    TimerReload  CON EXT              ; Get the External Constant
    TMR1ON       VAR T1CON.0          ; Alias the Timers ON/OFF bit
    
    ;---Reload Timer1------
    ASM
    ReloadTMR1
        MOVE?CT  0, T1CON, TMR1ON     ;  1     stop timer
        MOVLW    LOW(TimerReload)     ;  1     Add TimerReload to the 
        ADDWF    TMR1L,F              ;  1     value in Timer1
        BTFSC    STATUS,C             ;  1/2
        INCF     TMR1H,F              ;  1
        MOVLW    HIGH(TimerReload)    ;  1
        ADDWF    TMR1H,F              ;  1
        MOVE?CT  1, T1CON, TMR1ON     ;  1     start timer
      INT_RETURN
    ENDASM
    
    ;---Start/Stop controls -----
    StartTimer:
        Timer1  = TimerReload         ; Load Timer
        TMR1ON = 1                    ; start timer
    RETURN
    
    StopTimer:
        TMR1ON = 0                    ; stop timer
    RETURN
    
    END
    Attached Images Attached Images  

  8. #8
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,615


    Did you find this post helpful? Yes | No

    Default

    Hi, Gmg

    You could use another Pic pin for "slamming" down the descending part of the signal : input when rising, ouput low when descending.

    may be also use a slamming buffer with a BS170 i.e. ... ( ~ 3 ohms Rds on )

    just an idea

    signal is pretty clean for a PWM filtered generator ...

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  9. #9
    timmers's Avatar
    timmers Guest


    Did you find this post helpful? Yes | No

    Default

    Why not do it in analogue?
    An RC circuit and a couple of digi-pots would do it. To get a linear ramp use a high-ish target voltage for the capacitor, say 10x the trip voltage (15v).
    For a CRT timebase it must be free of any harmonics.

  10. #10
    Join Date
    Jan 2009
    Posts
    22


    Did you find this post helpful? Yes | No

    Default

    Alain,

    Interesting idea. Do you mean using another pin to sink the filtered output after reaching the maximum voltage? I'll have to try that to see how it sharpens the drop.

    Timmers,

    Because I know even less about analog circuits than digital ones. You know: "when the only tool you have is a hammer, everything looks like a nail."

  11. #11
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,615


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by gmglickman View Post
    Alain,

    Interesting idea. Do you mean using another pin to sink the filtered output after reaching the maximum voltage? I'll have to try that to see how it sharpens the drop.
    Exactly GmG ...

    even use a small mosfet to get a sharper edge ... ( BS170 or 2N7000 )

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts