Menu

Generating a Sawtooth Signal with Programmable Ramp Generator

2016-12-03
2016-12-03
  • William Roth

    William Roth - 2016-12-03

    This example code demonstrates how a PIC with a Programmable Ramp Generator (PRG) peripheral can produce a sawtooth signal and route the output to an I/O pin. A PIC 16F1769 was used, but any PIC with a PRG peripheral should work in a similar manner.

    PIC chips with Core Independent Peripherals (CIPS) allow tasks to be done with out taking up valuble core resources. In this example the following CIPS are used. Timer2, DAC1, OPA0, OPA1, PWM3 & PRG0. No external components are required.

    The code below will generate a 38KHz sawtooth signal on Pin 7. The signal is referenced to 0V via the DAC a DAC level of 0. The rate of rise is .2V/us . The peak amplitude is 4.2V

    By adjusting PWM, DAC Level, PRG Mode & rise/fall rates, a sawtooth, falling ramp, or triangle signal can be generated at various frequencies and rising/falling rates.

    Here is the code to get started. I used a 4x 20 LCD display for code development/debugging. The Printbits sub displays a register in binary format. Example: Printbits PRG1CON0,0. This will print the register bits on line 0 of the LCD Display.

    '''A demonstration program for GCB.
    '''---------------------------------------------------
    '''Program to Demo Programable Ramp Generater
    '''William Roth
    '''12.01.2016
    '''****************************************************
    
      #chip 16F1769, 32
      #config OSC = INTOSC, MCLRE = ON, WDTE = OFF, PPS1WAY = OFF
      #OPTION Explicit
    
    ''   'Using SWI2C for Display
      #define I2C_MODE Master
      #define I2C_DATA PORTB.4
      #define I2C_CLOCK PORTB.6
      #define I2C_DISABLE_INTERRUPTS ON
      #define LCD_IO 10
      #define LCD_I2C_Address_1 0x4E
    
      #define FOSC 1
      #define FOSC4 2
    
      CLS
      PRINT "Great Cow Basic"
      Locate 1,0
      Print "PRG Demo"
      Locate 2,0
      Print ChipNameStr
      wait 1 S
    
    INIT:
      INIT_PWM3    ;Setup PWM3
      START_PWM3   ;Start the PWM
      INIT_DAC1    ;Setup DAC1
      INIT_OPA1    ;Setup OPAMP1
      INIT_OPA2    ;Setup OPAMP2
      INIT_PRG1    ;Setup PRG1
    
    MAIN:
    
      START_PRG1      ;  GO!
    
    '---- Main loop ----
    Do
    
        'Main program goes here
    
    LOOP
    
    '------- Sub Routines ----------
    Sub INIT_DAC1
      DAC1CON0 = b'00000000'    ; Defaults
      DAC1REFH = b'00000000'    ;
      DAC1REFL = b'00000000'    ;
      SET DAC1CON0.5 OFF        ; DAC1 is on NO Output on RA0
      SET DAC1CON0.7 ON         ; ENABLE DAC1
      SET DAC2LD ON             ; Write DAC Val to Buffers
    End Sub
    
    Sub INIT_OPA1
      OPA1PCHS = b'00000010'    ; POS INput is DAC1 OUT
      OPA1CON  = b'10010000'    ;Enable with Unity Gain (Buffer)
    End Sub
    
    Sub INIT_OPA2
      OPA2PCHS = b'00001000'    ;POSIN = PRG1 OUT
      OPA2CON  = b'10010000'    ; Enable with Unity Gain
      ;PRG Output will be on RC3 Pin7
    End Sub
    
    Sub INIT_PRG1
        ;Setting up Ramp Generator as Rising Ramp
        ;DAC1 / OPA1 as Reference Supply source
        ;PWM3 as timing source
        SET PRG1CON0.7 ON   'Enable Module
    
        Do while PRG1CON1.2 = 0 'wait for PRG Ready
        Loop
    
        SET PRG1CON0.3 ON   ;Mode = Rising
        SET PRG2CON0.2 OFF
    
        SET PRG1CON0.5 ON   ;Edge Triggered
        SET PRG1CON0.4 ON
    
        SET PRG1CON0.1 ON   ;One shot enabled (See Datasheet)
    
        SET PRG1CON1.1 ON   ;  Set Polarity
        SET PRG1CON1.0 OFF  ;  Set Polarity
    
        PRG1CON2 = b'00000000'   ; Slope rate default .2 us/v
        PRG1FTSS = b'00000101'   ; Falling Timing Source PWM3
        PRG1RTSS = b'00000101'   ; Rising  Timing source PWM3
    End Sub
    
    Sub START_PRG1
        Set PRG1CON0.0 ON    ; GO!  Start the PRG
    End Sub
    
    Sub START_PWM3
         Set TMR2IF OFF          ; Clear the bit
         Set T2CON.7 ON          ;Start the timer
         PWM3CON = b'10000000'   ; Start the PWM
    End Sub
    
    Sub Stop_PWM3
         PWM3CON = b'00100000'    ; Stop the PWM
         Set TMR2IF OFF          ; Clear the bit
         Set T2CON.7 OFF         ;Start the timer
         TMR2 = 0
    End Sub
    
    Sub INIT_PWM3
         T2PR = 200            ;Default is 255 at POR
         T2CLKCON = FOSC4
         T2CON = b'00100000'   ;Set TMR2 Prescale
         PWM3CON = 0           ; Clear
         PWM3DCH = 175         ; High bits
         PWM3DCL = 0           ; Low Bits
     End Sub
    
    Sub printbits(databyte,LCD_line)
      Locate LCD_line,0
      Print "                    " 'clear the line
      locate LCD_line,0
      Print databyte.7 : Print " "
      Print databyte.6 : Print " "
      Print databyte.5 : Print " "
      Print databyte.4 : Print " "
      Print databyte.3 : Print " "
      Print databyte.2 : Print " "
      Print databyte.1 : Print " "
      Print databyte.0 : Print " "
    end sub
    end
    
     
  • stan cartwright

    stan cartwright - 2017-03-10

    Could be useful to control x/y scope and bresenham's line algo to do vector graphics like asteroids was , 2 ramp generators clocked at different frequency.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.