Stm32f103C8 External Dac

Working libraries, libraries being ported and related hardware
User avatar
Vassilis
Posts: 335
Joined: Thu May 21, 2015 6:42 am
Location: Thessaloniki, Greece
Contact:

Re: Stm32f103C8 External Dac

Post by Vassilis » Mon Jan 15, 2018 3:49 pm

The R2R DAC requires an Operational Amplifier (OP_AMP) to get some mΑ to the output. For example, you can not drive an LED with the R2R dac as-is. You need to use an OP-AMP such as LMV358.

If I were you, I would use an SPI DAC such as MCP4921 (single DAC) or MCP4922 (double DAC) that can provide 25mA output as-is ;)

dannyf
Posts: 228
Joined: Wed May 11, 2016 4:29 pm

Re: Stm32f103C8 External Dac

Post by dannyf » Mon Jan 15, 2018 5:18 pm

You may set the bits individually.
Just think about the values the DAC outputs while those pins are being set / reset.

you will need a mechanism to latch the output.

User avatar
Pito
Posts: 1734
Joined: Sat Mar 26, 2016 3:26 pm
Location: Rapa Nui

Re: Stm32f103C8 External Dac

Post by Pito » Mon Jan 15, 2018 6:00 pm

He may apply an algorithm, where the bits between the DAC samples change such the turmoil at the output will be minimal :)
Pukao Hats Cleaning Services Ltd.

stevestrong
Posts: 2051
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany
Contact:

Re: Stm32f103C8 External Dac

Post by stevestrong » Mon Jan 15, 2018 6:39 pm

What is the final goal?
Can't be solved by using a filtered PWM output?

dannyf
Posts: 228
Joined: Wed May 11, 2016 4:29 pm

Re: Stm32f103C8 External Dac

Post by dannyf » Mon Jan 15, 2018 11:18 pm

He may apply an algorithm
I don't know how that can be addressed via software. a latch, including a latch-equipped shift register, would be my way to go for glitch-free output. Otherwise, a capacitor can help reduce the glitches, with performance issues of its own however.

stm32user
Posts: 13
Joined: Wed Nov 25, 2015 3:30 pm

Re: Stm32f103C8 External Dac

Post by stm32user » Tue Jan 16, 2018 3:09 pm

Code: Select all

uint8_t DPINS[] = {PA0, PB0, PA1, PB0, PB12, PB13, PB14, PB15};   // random pin   

void setup(){

for (uint8_t i = 0; i <= sizeof(DPINS) - 1; i++)
pinMode(DPINS[i], OUTPUT);
}



num = sine[i];  // sine table value

for (byte i=0; i<= sizeof(DPINS) - 1; i++) {   
    byte state = bitRead(num, i);
    digitalWrite(DPINS[i], state);   
}


I could not create a wave :(
r2r circuit is working
Image

User avatar
Vassilis
Posts: 335
Joined: Thu May 21, 2015 6:42 am
Location: Thessaloniki, Greece
Contact:

Re: Stm32f103C8 External Dac

Post by Vassilis » Tue Jan 16, 2018 5:33 pm

try that code

Code: Select all


uint8_t DPINS[] = {PA0, PB0, PA1, PB1, PB12, PB13, PB14, PB15};   // random pin   
uint8_t num;

uint8_t  sine[256] = {
  0x80, 0x83, 0x86, 0x89, 0x8C, 0x90, 0x93, 0x96,
  0x99, 0x9C, 0x9F, 0xA2, 0xA5, 0xA8, 0xAB, 0xAE,
  0xB1, 0xB3, 0xB6, 0xB9, 0xBC, 0xBF, 0xC1, 0xC4,
  0xC7, 0xC9, 0xCC, 0xCE, 0xD1, 0xD3, 0xD5, 0xD8,
  0xDA, 0xDC, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, 0xE8,
  0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4,
  0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC,
  0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD,
  0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6,
  0xF5, 0xF4, 0xF3, 0xF1, 0xF0, 0xEF, 0xED, 0xEB,
  0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC,
  0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9,
  0xC7, 0xC4, 0xC1, 0xBF, 0xBC, 0xB9, 0xB6, 0xB3,
  0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C,
  0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83,
  0x80, 0x7D, 0x7A, 0x77, 0x74, 0x70, 0x6D, 0x6A,
  0x67, 0x64, 0x61, 0x5E, 0x5B, 0x58, 0x55, 0x52,
  0x4F, 0x4D, 0x4A, 0x47, 0x44, 0x41, 0x3F, 0x3C,
  0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2B, 0x28,
  0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x18,
  0x16, 0x15, 0x13, 0x11, 0x10, 0x0F, 0x0D, 0x0C,
  0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04,
  0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
  0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03,
  0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A,
  0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15,
  0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24,
  0x26, 0x28, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37,
  0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D,
  0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x64,
  0x67, 0x6A, 0x6D, 0x70, 0x74, 0x77, 0x7A, 0x7D
};

void setup(){
  for (uint8_t i = 0; i <= sizeof(DPINS) - 1; i++)
    pinMode(DPINS[i], OUTPUT);
}


void loop() {
  for(int m=0;m<255;m++){
    num = sine[m];  // sine table value
    for (byte i=0; i <= sizeof(DPINS)-1; i++) {   
        byte state = bitRead(num, i);
        digitalWrite(DPINS[i], state);   
    }
  }
}
You had included the PB0 pin twice. I changed it to PB1

EDIT:
The method of using pins in different ports for DAC is not recomended because it is producing spikes to the waveform every time you change the status of each output pin. You need to change the pin status all-at-once.
dac.jpg
dac.jpg (94.58 KiB) Viewed 171 times

User avatar
Pito
Posts: 1734
Joined: Sat Mar 26, 2016 3:26 pm
Location: Rapa Nui

Re: Stm32f103C8 External Dac

Post by Pito » Tue Jan 16, 2018 10:47 pm

Try to order the changing the DACvalue bits from the highest bit to the lowest (as I did in my code above).
Like in your code:

Code: Select all

    for (byte i=7; i >=0; i--) {   
        byte state = bitRead(num, i);
        digitalWrite(DPINS[i], state);   
    }
I would recommend to you to use my code above as it is much faster.
Also you may add a capacitor from R2R output to GND (for example 10nF - the capacitor value depends on the R2R values and the sinus freq, however) to filter out the noise.
Pukao Hats Cleaning Services Ltd.

dannyf
Posts: 228
Joined: Wed May 11, 2016 4:29 pm

Re: Stm32f103C8 External Dac

Post by dannyf » Wed Jan 17, 2018 1:50 pm

If you want speed, don't use digitalWrite, unroll the loop and use a pointer to index the array.

User avatar
Pito
Posts: 1734
Joined: Sat Mar 26, 2016 3:26 pm
Location: Rapa Nui

Re: Stm32f103C8 External Dac

Post by Pito » Wed Jan 17, 2018 2:19 pm

The fastest way would be to generate a set of DAC "commands" like

Code: Select all

..
sample_delay();
// *********************** Output the Sample N. 345 ************************
//Set A2, A12, A13 (HIGH)
GPIOA->regs->BSRR = 0b0011000000000100;
//Clear A3, A11, A15 (LOW)
GPIOA->regs->BRR =  0b1000100000001000;
//Set B1, B12, B15 (HIGH)
GPIOB->regs->BSRR = 0b1001000000000010;
//Clear B3, B11, B13 (LOW)
GPIOB->regs->BRR =  0b0010100000001000;
// *************************************************************************
sample_delay();
..
running them unrolled in a "signal_period" loop, thus the single R2R DAC's value change will take 4 clocks only (provided you use 2 Ports only).
Last edited by Pito on Wed Jan 17, 2018 2:51 pm, edited 13 times in total.
Pukao Hats Cleaning Services Ltd.

Post Reply