Tag Archives: Signal

Digital Sawtooth Signal Generation with FPGA

Hello,

On my previous post, I explained how to create a sawtooth signal at 10kHz with a microcontroller (MSP430). Since it gave a discrete increase of the ramp due to low number of steps, 128 steps in that case, I tried to create a signal with higher frequency and higher number of steps accordingly.

For this purpose, I used a Nexys3 FPGA board which has a Spartan 6 Xilinx chip on it. Internal clock of this board is 100MHz, but to reach this speed from DIO pins, VHDC expansion connector must be used. There was no available connector for this interface, so I tried my best from Pmod connectors.

You can find the theoretical part from the the previous post, so I will skip that and directly explain the implementation. I used different from the previous version, I used TI DAC902U, which is essentially the same but has 12-bit parallel input capacity. The external connections are also the same.

The following figure shows the best available clock signal I could obtain from the Pmod connectors. It is not like a square wave, but works fine for my purpose. The frequency is 12.5 MHz, and a good point is that at least it is highly accurate and stable even though shape is not so good.

FPGA Clock Signal Output at 12.5 MHz

FPGA Clock Signal Output at 12.5 MHz

In the following figure you can see the connections between the FPGA Board and the DAC.

Nexys3 - DAC Connections

Nexys3 – DAC Connections

Verilog code for this counter is pretty simple. I have done it in behavioral style to reduce the work required. Moreover, there would not be any performance difference in such a small scale hardware description.

module Counter(
   input Clk,
   output [13:0] Count
   );

reg [13:0] Count;

   always@(negedge Clk) begin
      if(Count == 9999) Count = 0;
      Count = Count + 1;
   end

endmodule

Instead of creating a frequency divider and a counter separately (They are the same thing eventually.)  I built a 14-bit counter and used 12 most significant bits of it. 11 of those are the clock count from 0 to 1249 and the least significant one is the clock signal supply of the DAC.

Results:

Sawtooth Signal Output

Sawtooth Signal Output

A Closer Look to the Falling Edge

A Closer Look to the Falling Edge

There is an obvious improvement on both rising and falling edges of the signal. The rise is much smoother and the fall does not have that short peak to the negative voltages.

As always, you can contact me about anything related or unrelated to the post.

Thank you for your visit in my blog.

Gunay TURAN

p.s. I Have found such a contact form in the WordPress interface. Hope it will make it easier to contact me 🙂 I will add one of those to each post…

 

 

 

Digital Sawtooth Signal Generation with MSP430

Hello,

Sawtooth signals have various applications for example FMCW radars, audio applications, CRT screens, etc. By using an operational amplifier, a voltage comparator, and a transistor switch you can create your own sawtooth signal. The idea behind this analog circuit is to charging a capacitor linearly and rapidly discharging it. However, it is pretty difficult to get a rapid falling edge from an analog circuit, so the circuit with those component creates an asymmetrical  triangular wave.

Analog Sawtooth Signal at 10 kHz

Analog Sawtooth Signal at 10 kHz

To overcome this problem, you can create a digital sawtooth generator that falls to zero (or to the offset you set) in no time. What you need is a digital-to-analog converter (DAC) and a controlling unit, in this case an MSP430G2553. Most DAC ICs use serial SPI or I2C interface and this reduces the speed dramatically because you are sending whole DAC count bit by bit. What if you need a sawtooth signal around a MHz, or more? For this purpose, there are parallel input high-speed DAC ICs which can give update rates up to 2.5 GSPS. In this application, I used a 10-bit 165 MSPS digital to analog converter, DAC900, to produce a 10 kHz sawtooth signal.

The signal is continuously increasing, and then roll back to zero. Therefore, it is easy to figure out what kind of parallel input to give to the DAC, a binary counter. When it reaches its maximum value, it rolls back to zero. Now, we need to calculate the maximum number of steps to fit in 100us (10kHz).

MSP430G2553 has a DCO at maximum of 16MHz, but this is the speed of the CPU clock, not the frequency of counting, since each instruction takes several cpu cycles, effective counting frequency will be reduced. One other point is that C is a high level language and its instructions take longer than Assembly instructions. Therefore, coding with Assembly will be a more effective solution.  Let us first calculate the counting frequency with full resolution, 10-bits. For this, we need to use an 11-bit counter so we can use the LSB as the DAC clock. If use the LSB as the clock, its period will determine our counting frequency.

10 bit resolution means 1024 DAC steps. If we divide 100us to 1024 we will get 97ns counting/clock period, requiring a bit more than 10MHz. This is unfortunately is not possible to get as a clock frequency because to count with two ports (since one port has 8 DIO pins, we need two of them to make a 11-bit counter), two nested loops and a comparison function is required. This will load the CPU and slow it down. I tried this method, and got maximum of 822kHz of counting frequency. Then how about counting with this frequency, and reducing the number of steps? 822kHz gives us 1.22us of count period, which means 90 steps for 100us! If we used only one port, we would have 8-bit counter and 7-bit resolution, giving us 128 steps. In that case I got approximately 1.6MHz count, which results in 80us to reach to the top value with 128 steps. This is not a big problem because we can slow down our DCO and get the required frequency. In order to use 128 steps to get 100us period, required clock frequency is 1.28MHz (Not CPU clock but the DAC clock). This value can be reached by appropriate DCO setting, which you will see in the following Assembly code[1].

 

;-------------------------------------------------------------------------------
; MSP430 Assembler Code Template for use with TI Code Composer Studio;
;-------------------------------------------------------------------------------
            .cdecls C,LIST,"msp430.h"       ; Include device header file

;-------------------------------------------------------------------------------
            .text                           ; Assemble into program memory
            .retain                         ; Override ELF conditional linking
                                            ; and retain current section
            .retainrefs                     ; Additionally retain any sections
                                            ; that have references to current
                                            ; section
;-------------------------------------------------------------------------------
RESET       mov.w   #__STACK_END,SP         ; Initialize stackpointer
StopWDT     mov.w   #WDTPW|WDTHOLD,&WDTCTL  ; Stop watchdog timer

;-------------------------------------------------------------------------------
                                            ; Main loop here
;-------------------------------------------------------------------------------
;DCO settings to ~1.28MHz
DcoSetng	clr.b 	&DCOCTL ; Select lowest DCOx
			bis.b 	#RSEL3+RSEL2+RSEL1+RSEL0,&BCSCTL1
			bis.b 	#DCO2,&DCOCTL 

SetupP1     bis.b   #255,&P1DIR
Mainloop    inc     &P1OUT
            jmp     Mainloop

;-------------------------------------------------------------------------------
;           Stack Pointer definition
;-------------------------------------------------------------------------------
            .global __STACK_END
            .sect 	.stack

;-------------------------------------------------------------------------------
;           Interrupt Vectors
;-------------------------------------------------------------------------------
            .sect   ".reset"                ; MSP430 RESET Vector
            .short  RESET

With this settings our counter is ready to use and the following figure is the capture of the clock output:

Clock output from MSP430

Clock output from MSP430

Having our counter, now we need to connect it to the DAC. I directly used the basic connection instructions given in the datasheet of the DAC900. To read a value from oscilloscope, I connected a 100 ohm resistor between the current output pin and ground.

DAC900 Connections [2]

DAC900 Connections [2]

Here is the realization of this circuit on breadboard:

MSP430 and DAC900 Connections

MSP430 and DAC900 Connections

DAC900 does not come with DIP packages, so I got one SOIC-28, and soldered it on my homemade SOIC-to-DIP converter circuit. You can buy one of those coverters. I must admit that I am quite shocked about the price because similar products cost $2 in Turkey…

In the following two figures you can see the results:

Sawtooth Signal Obtained from the DAC

Sawtooth Signal Obtained from the DAC

 

A Close-up to the Falling Edge of the Sawtooth

A Close-up to the Falling Edge of the Sawtooth

You can see the rising is noisy due to the long thin cables, but a more important problem is that there isn’t the smooth increase of the ramp as I got in the analog circuit. However, the greatest advantage of this circuit is the real rapid falling edge.

To solve the problem with discrete increase of the ramp, I used an FPGA board, and created a sawtooth with 1250 steps. It gave much better results, and I will post that later…

Please feel free to contact me about any problems, suggestions, etc…

Thank you

Gunay TURAN

 

References:

[1] This code is taken from TI’s example codes for CCS and modified.

[2] http://www.ti.com/lit/ds/symlink/dac900.pdf