Can anyone point me to posts/tutorials for PicBasic Pro code to drive MCP4291 DAC? I did an advanced search of the Forum using keywork DAC and came up empty. Will probably be using a PIC16F676 to control the MCP4291 DAC.
Can anyone point me to posts/tutorials for PicBasic Pro code to drive MCP4291 DAC? I did an advanced search of the Forum using keywork DAC and came up empty. Will probably be using a PIC16F676 to control the MCP4291 DAC.
Hi jellis00
Here's an example in basic (but the wrong basic) for the MCP4921. It's a little past half way through:
http://www.mikroe.com/eng/chapters/v...r-13-examples/
This is what I have used to produce 3 sinewaves out of 3 MCP4921 DACs. Cant find an MCP4291
regardsCode:include "modedefs.bas" ANSEL = %00000000 'Disable analog inputs Channels 0 to 7 ANSELH = %00000000 'Disable analog inputs Channels 8 to 11 WPUB = %00000000 'Disable weak pull-ups ADCON0 = %00000000 'A/D Module is OFF CM1CON0 = %00000000 'Comparator1 Module is OFF CM2CON0 = %00000000 'Comparator2 Module is OFF INTCON = %00000000 'INTerrupts CONtrol TRISA = %00000000 'Set Input/Output (0 to 5) PORTA = %00000000 'Ports High/Low (0 to 5) TRISB = %00000000 'Set Input/Output (4 to 7) PORTB = %00000000 'Ports High/Low (4 to 7) TRISC = %01000000 'Set Input/Output (0 to 7) PORTC = %01000000 'Ports High/Low (0 to 7) addr var word [90] addr[1]=2139 addr[2]=2278 addr[3]=2415 addr[4]=2551 addr[5]=2684 addr[6]=2813 addr[7]=2938 addr[8]=3059 addr[9]=3175 addr[10]=3285 addr[11]=3389 addr[12]=3486 addr[13]=3576 addr[14]=3658 addr[15]=3732 addr[16]=3797 addr[17]=3854 addr[18]=3902 addr[19]=3940 addr[20]=3969 addr[21]=3989 addr[22]=3998 addr[23]=3998 addr[24]=3989 addr[25]=3969 addr[26]=3940 addr[27]=3902 addr[28]=3854 addr[29]=3797 addr[30]=3732 addr[31]=3658 addr[32]=3576 addr[33]=3486 addr[34]=3389 addr[35]=3285 addr[36]=3175 addr[37]=3059 addr[38]=2938 addr[39]=2813 addr[40]=2684 addr[41]=2551 addr[42]=2415 addr[43]=2278 addr[44]=2139 addr[45]=2002 addr[46]=1861 addr[47]=1722 addr[48]=1585 addr[49]=1449 addr[50]=1316 addr[51]=1187 addr[52]=1062 addr[53]=941 addr[54]=825 addr[55]=715 addr[56]=611 addr[57]=514 addr[58]=424 addr[59]=342 addr[60]=268 addr[61]=203 addr[62]=146 addr[63]=98 addr[64]=60 addr[65]=31 addr[66]=11 addr[67]=2 addr[68]=2 addr[69]=11 addr[70]=31 addr[71]=60 addr[72]=98 addr[73]=146 addr[74]=203 addr[75]=268 addr[76]=342 addr[77]=424 addr[78]=514 addr[79]=611 addr[80]=715 addr[81]=825 addr[82]=941 addr[83]=1062 addr[84]=1187 addr[85]=1316 addr[86]=1449 addr[87]=1585 addr[88]=1722 addr[89]=1861 addr[90]=1996 '------------------------------------------------------------------------------- ' Variables SCK VAR PORTB.6 'Clock pin CS1 VAR PORTC.0 'Chip Select Active low CS2 VAR PORTC.1 CS3 VAR PORTC.2 SDO VAR PORTC.7 'Data Out pin FREQ VAR BYTE SWITCH VAR PORTC.6 counter VAR word highbit var word lbit var highbit.byte0 hbit var highbit.byte1 '------------------------------------------------------------------------------- START: IF SWITCH THEN FREQ = 35 ELSE FREQ = 185 ENDIF for counter = 1 to 90 highbit = addr[counter] +20480 low cs1 SHIFTOUT SDO,SCK,msbfirst,[hbit] SHIFTOUT SDO,SCK,msbfirst,[lbit] high cs1 PAUSEUS FREQ low cs2 SHIFTOUT SDO,SCK,msbfirst,[hbit] SHIFTOUT SDO,SCK,msbfirst,[lbit] high cs2 PAUSEUS FREQ low cs3 SHIFTOUT SDO,SCK,msbfirst,[hbit] SHIFTOUT SDO,SCK,msbfirst,[lbit] high cs3 PAUSEUS FREQ next counter counter=1 GOTO START: END
aajgss
Here's another example like aajgss's for the MCP4921. It generates a sine or cosine wave.
Would like to try speeding it up, using the MSSI or MSSp modules. If anyone has an idea for this
please post.
Code:'**************************************************************** '* Name : DAC_MCP4921_WAVE.PBP * '* Author : MARK S * '* Date : 4/30/2011 * '* Version : 1.0 * '* Notes : DEMO 12BIT DAC MCP4921 - OUTPUTS SINE OR COSINE WAVE * '* : FIXED FREQUENCY SHIFTOUT VERY SLOW, TRY MSSP MODULE * '**************************************************************** 'PIC18F4680 PBP2.6, MPASM DEFINE OSC 20 'REGISTERS INTCON = %00000000 INTCON2.7 = 0 'weak pullups portB 'ADCON0 = %00000001 'A/D module enabled, channel 0 ADCON1 =%00001111 'ALL DIGITAL 'ADCON2 = %10101011 'Right justified, 12 Tad, Frc clock CMCON =%00000111 'COMP OFF T3CON = 0 CCP1CON = 0 'ECCP OFF ECCP1AS = 0 ECCP1DEL = 0 'PORTS TRISA = %00000000 ' PORTA ALL OUTPUT TRISB = %00000000 ' PORTB TRISC = %00000000 ' PortC TMR1 RC0 = INPUT TRISD = %00000000 TRISE = %00000111 'VARIABLES & DAC CONNECTIONS VREF PIN6 4921 TIED TO +5V SCLK VAR PORTD.0 'SPI CLOCK PIN3 4921 SDAT VAR PORTD.1 'SPI DATA PIN4 4921 CS_DAC VAR PORTD.2 'Chip select PIN2 4921 LOAD_DAC VAR PORTD.3 'PIN5 4921 WAVE_INDEX VAR WORD 'TABLE POINTER DAC_OUT VAR WORD '0-4095 OUTPUT 0 TO 5V, value returned from table MAIN: HIGH LOAD_DAC HIGH CS_DAC FOR WAVE_INDEX = 0 TO 255 'GOSUB COS_TABLE GOSUB SINE_TABLE 'PAUSEUS 500 'LOWER OUTPUT FREQ '---------------------- LOW CS_DAC SHIFTOUT SDAT,SCLK,1,[%0011,DAC_OUT\12] 'Set DAC out HIGH CS_DAC LOW LOAD_DAC @ NOP HIGH LOAD_DAC '---------------------- NEXT WAVE_INDEX GOTO MAIN SINE_TABLE: lookup2 WAVE_INDEX, [0,1,2,6,10,15,22,30,39,50,61,74,88,103,120,137,156,_ 176, 197,219,242,266,291,318,345,374,403,433,465,497,_ 531,565,600,636,673,710,749,788,828,869,910,952,995,_ 1039,1083,1127,1172,1218,1264,1311,1358,1406,1453,1502,1550,1599,_ 1648,1698,1747,1797,1847,1897,1948,1998,2048,2098,2148,2199,2249,_ 2299,2349,2398,2448,2497,2546,2594,2643,2690,2738,2785,2832,2878,_ 2924,2969,3013,3057,3101,3144,3186,3227,3268,3308,3347,3386,3423,_ 3460,3496,3531,3565,3599,3631,3663,3693,3722,3751,3778,3805,3830,_ 3854,3877,3899,3920,3940,3959,3976,3993,4008,4022,4035,4046,4057,_ 4066,4074,4081,4086,4090,4094,4095,4095,4095,4094,4090,4086,4081,_ 4074,4066,4057,4046,4035,4022,4008,3993,3976,3959,3940,3920,3899,_ 3877,3854,3830,3805,3778,3751,3722,3693,3663,3631,3599,3565,3531,_ 3496,3460,3423,3386,3347,3308,3268,3227,3186,3144,3101,3057,3013,_ 2969,2924,2878,2832,2785,2738,2690,2643,2594,2546,2497,2448,2398,_ 2349,2299,2249,2199,2148,2098,2048,1998,1948,1897,1847,1797,1747,_ 1698,1648,1599,1550,1502,1453,1406,1358,1311,1264,1218,1172,1127,_ 1083,1039,995,952,910,869,828,788,749,710,673,636,600,_ 565,531,497,465,433,403,374,345,318,291,266,242,219,_ 197,176,156,137,120,103,88,74,61,50,39,30,22,15,10,6,_ 2,1],DAC_OUT RETURN COS_TABLE: lookup2 WAVE_INDEX, [4095,4095,4094,4090,4086,4081,_ 4074,4066,4057,4046,4035,4022,4008,3993,3976,3959,3940,3920,3899,_ 3877,3854,3830,3805,3778,3751,3722,3693,3663,3631,3599,3565,3531,_ 3496,3460,3423,3386,3347,3308,3268,3227,3186,3144,3101,3057,3013,_ 2969,2924,2878,2832,2785,2738,2690,2643,2594,2546,2497,2448,2398,_ 2349,2299,2249,2199,2148,2098,2048,1998,1948,1897,1847,1797,1747,_ 1698,1648,1599,1550,1502,1453,1406,1358,1311,1264,1218,1172,1127,_ 1083,1039,995,952,910,869,828,788,749,710,673,636,600,_ 565,531,497,465,433,403,374,345,318,291,266,242,219,_ 197,176,156,137,120,103,88,74,61,50,39,30,22,15,10,6,_ 2,1,0,1,2,6,10,15,22,30,39,50,61,74,88,103,120,137,156,_ 176, 197,219,242,266,291,318,345,374,403,433,465,497,_ 531,565,600,636,673,710,749,788,828,869,910,952,995,_ 1039,1083,1127,1172,1218,1264,1311,1358,1406,1453,1502,1550,1599,_ 1648,1698,1747,1797,1847,1897,1948,1998,2048,2098,2148,2199,2249,_ 2299,2349,2398,2448,2497,2546,2594,2643,2690,2738,2785,2832,2878,_ 2924,2969,3013,3057,3101,3144,3186,3227,3268,3308,3347,3386,3423,_ 3460,3496,3531,3565,3599,3631,3663,3693,3722,3751,3778,3805,3830,_ 3854,3877,3899,3920,3940,3959,3976,3993,4008,4022,4035,4046,4057,_ 4066,4074,4081,4086,4090,4094,4095],DAC_OUT RETURN END
Mark_s
What speed are you looking for?
Mine was running at about 9 Hz on an 18F14K50. By setting Config1 to $F100 I now get around 70hZ which is what I was after.
aajgss
aajgss,
I was getting similar frequencies as you, at 20mhz and 40mhz clock settings. My lookup table has 256
values, so it takes long time to cycle. I going to try the MSSP tonight and see what is gained. I know a dspic running at 80mhz can output about 4khz with the same dac and MSSP. So I am trying for 1 to 2khz. Maybe a pipe dream? I'll post the code if it works.
regards
Mark_s
I'll be interested in how you go. I did try the MSSP and actually got slower. I know it was the code I had written, because its just logical it should be faster and was going to continue with it to see if I could find my error(s), but the change to the CONFIG1 gave me the frequency I wanted. If I could get it faster and use 2 degree steps instead of 4 degree steps it would be better.
regards
aajgss
Okay I hammered out a routine to use the MSSP module. It gave me
a 6x speed increase over shiftout. I'm just a hack so there maybe a
better way to do it.
Results:
Shiftout MSSP
10mhz 10hz 66hz
20mhz 21hz 117hz
40mhz 42hz 2 63hz
80mhz 83hz 526hz
The 80mhz is 20mhz crystal 4xpll, overclocking probably not reliable? but worked!
Code:'**************************************************************** '* Name : DAC_12BIT_MSSP * '* Author : MARK S * '* Date : 6/9/2011 '* SINE WAVE GENERATOR USING MCP4921 12BIT DAC * '* USES MSSP MODULE vs SHIFTOUT * '* PIC18F4680, PBP2.6 MPASM * '* * '**************************************************************** DEFINE OSC 20 'REGISTER SET INTCON = %00000000 INTCON2.7 = 0 'weak pullups portB ADCON1 =%00001111 'ALL DIGITAL CMCON =%00000111 'COMP OFF T3CON = 0 CCP1CON = 0 'ECCP OFF ECCP1AS = 0 ECCP1DEL = 0 SSPSTAT = %00000000 'TX IDLE LOW,SAMPLE MIDDLE SSPCON1 = %00100000 ' ENABLE MSSP,CLK IDLE LOW,FOSC/4 '----------------------------------------------------- 'PORTS TRISA = %00000000 ' PORTA ALL OUTPUT ' TRISB = %00000000 ' PORTB PORTB = %00000000 ' CLEAR PORTB TRISC = %00000000 ' PortC TRISD = %00000000 TRISE = %00000000 '---------------------------------------------------- 'DAC CONNECTIONS 'VREF PIN6 MCP4921 TIED TO +5V 'CLOCK PIN3 MCP4921 TO PORTC.3 "SCK" 'DATA PIN4 MCP4921 TO PORTC.5 "SDO" 'CS PIN2 MCP4921 TO PORTD.2 'LOAD PIN5 MCP4921 TO PORTD.3 CONNECT THIS TO GROUND TO SAVE A PORT PIN '-------------------------------------------------- 'VARIABLES CS_DAC VAR PORTD.2 LOAD_DAC VAR PORTD.3 'KEEP LOW WAVE_INDEX VAR WORD DAC_OUT VAR WORD DAC_OUT1 VAR WORD SSPIF VAR PIR1.3 ' SPI interrupt flag '---------------------------------------------------- 'START SSPBUF = 0 ' CLEAR SPI BUFFER SSPIF = 0 ' CLEAR SPI INTERUPT FLAG. LOW LOAD_DAC '=================================================================== MAIN: HIGH CS_DAC FOR WAVE_INDEX = 0 TO 255 GOSUB SINE_TABLE LOW CS_DAC DAC_OUT1 =$3000 | DAC_OUT ' Combine table value with dac reg control SSPBUF = DAC_OUT1.HIGHBYTE 'SEND HIGH While SSPIF = 0 ' WAIT FOR TX TO COMPLETE Wend SSPIF = 0 'RESET INT FLAG SSPBUF = DAC_OUT1.LOWBYTE 'SEND LOW While SSPIF = 0 ' WAIT FOR TX TO COMPLETE Wend SSPIF = 0 'RESET INT FLAG HIGH CS_DAC NEXT WAVE_INDEX GOTO MAIN SINE_TABLE: lookup2 WAVE_INDEX, [0,1,2,6,10,15,22,30,39,50,61,74,88,103,120,137,156,_ 176, 197,219,242,266,291,318,345,374,403,433,465,497,_ 531,565,600,636,673,710,749,788,828,869,910,952,995,_ 1039,1083,1127,1172,1218,1264,1311,1358,1406,1453,1502,1550,1599,_ 1648,1698,1747,1797,1847,1897,1948,1998,2048,2098,2148,2199,2249,_ 2299,2349,2398,2448,2497,2546,2594,2643,2690,2738,2785,2832,2878,_ 2924,2969,3013,3057,3101,3144,3186,3227,3268,3308,3347,3386,3423,_ 3460,3496,3531,3565,3599,3631,3663,3693,3722,3751,3778,3805,3830,_ 3854,3877,3899,3920,3940,3959,3976,3993,4008,4022,4035,4046,4057,_ 4066,4074,4081,4086,4090,4094,4095,4095,4095,4094,4090,4086,4081,_ 4074,4066,4057,4046,4035,4022,4008,3993,3976,3959,3940,3920,3899,_ 3877,3854,3830,3805,3778,3751,3722,3693,3663,3631,3599,3565,3531,_ 3496,3460,3423,3386,3347,3308,3268,3227,3186,3144,3101,3057,3013,_ 2969,2924,2878,2832,2785,2738,2690,2643,2594,2546,2497,2448,2398,_ 2349,2299,2249,2199,2148,2098,2048,1998,1948,1897,1847,1797,1747,_ 1698,1648,1599,1550,1502,1453,1406,1358,1311,1264,1218,1172,1127,_ 1083,1039,995,952,910,869,828,788,749,710,673,636,600,_ 565,531,497,465,433,403,374,345,318,291,266,242,219,_ 197,176,156,137,120,103,88,74,61,50,39,30,22,15,10,6,_ 2,1],DAC_OUT RETURN END
Last edited by mark_s; - 10th June 2011 at 16:27.
I don't know what the OP's application is but using a PIC and a serial DAC (MCP4921) to generate sine waves is extremely inefficient. It consumes a tremendous amount of CPU resources and gives very poor performance - limited frequency range and resolution. Using a DDS chip such as the AD8937 (which incidentally costs about the same as then MCP4921) allows you to generate sine (and triangle and square) waveforms from 0-16MHz with 0.06Hz (28-bit) resolution. For low frequency applications (such as VFDs) you can use a lower speed clock - with a 1MHz clock you get 0-1MHz and 0.004Hz resolution. It uses the same SPI interface as the MCP4921 and the slowest 4MHz PIC will still be able to generate up to a 16MHz sine wave.
Why pay for overpriced toys when you can have
professional grade tools for FREE!!!
Yes, it is AD9837. Sorry for the typo.
Why pay for overpriced toys when you can have
professional grade tools for FREE!!!
Very interesting chip....
Thanks and Regards;
Gadelhas
rmteo,
You are correct an spi dac is not suited for generating sine waves. My goal was to
learn how to use this dac, which I did. I have used the AD9835 and AD9850 which are lower
resolution versions of the AD9837, which you mentioned. The 28 bits of resolution is fantastic and
I may request a sample since Digikey and Mouser don't stock the AD9837 yet.
Regards
Thank you aajgss and mark_s. I should have been more specific in my original post, but I am not using the DAC to generate sinusoidal, triangular or square waveforms. All I am doing is outputing an analog voltage value that equates to a calculation performed by the MCU. So I don't think I need the complexity of a look-up table for generating an output analog waveform. Instead, I am just looking for example code to output an analog voltage by the DAC that will change in value relatively slowly every 20 to 100 msecs. Anyone have suggestion as to how to do this, or better yet example PICBASIC Pro code? Oh, and BTW, the DAC I am using is an MCP4921 not a MCP4291 (typo on my part).
Good stuff Mark_s
I tried your code and got a slightly faster speed than before. The difference being I was doing 360 Degrees in 90 steps where yours is 360 degrees in 510 steps so you code has sped it up by neary 6 times.
Thanks
aajgss
Has Anyone used AD9837 and got programmable pure sine wave above 10MHz?
Would the PIC16F178X with 16 bit PWM be of any help with this application?
Norm
jellis00, i am trying to get the same code for the mcp4921 to output 0-5v. Did you ever find the sample code to do this?
Bookmarks