This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

DAC without DMA and TIMer

Hi , i'm tryiing to use a simplest sample for DAC in stm32 , so i choose the non-triggerd is the simplest way : Digital to Analog conversion can be non-triggered using DAC_Trigger_None and DAC_OUT1/DAC_OUT2 is available once writing to DHRx :

so seems i missed some thing knowinh that i declared the oclock in an other file :

< /* Includes ------------------------------------------------------------------*/

#include "stm32f2xx.h"

#include "stm32f2xx_gpio.h"
#include "stm32f2xx_dac.h"

/* Private define ------------------------------------------------------------*/
#define DAC_DHR12R2_ADDRESS 0x40007414
#define DAC_DHR8R1_ADDRESS 0x40007410

DAC_InitTypeDef DAC_InitStructure;

void DAC_Config(void)
{ GPIO_InitTypeDef GPIO_InitStruct;

/* GEPIO CONFIGURATION of DAC Pin */

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStruct);

/* GEPIO CONFIGURATION of input Pin for DHR */

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1 |GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_3| GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7 ;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStruct);

/* DAC channel1 Configuration */ DAC_InitStructure.DAC_Trigger = DAC_Trigger_None; DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; DAC_Init(DAC_Channel_2, &DAC_InitStructure);

/* Enable DAC Channel2 */ DAC_Cmd(DAC_Channel_2, ENABLE);

}

int main (void) { uint16_t DATA ;

while (1) { DATA = GPIOD ->IDR ; /* Set DAC channel2 DHR12RD register */ DAC_SetChannel2Data(DAC_Align_12b_R, DATA);

}

}

>

Parents
  • The code you presented still isn't complete, there is no way to know that critical steps have been done correctly. The GPIO pins are not initialized properly, ie not 0 thru 11, you have a bunch of pins missing and also define pin 13? Your comments suggest you have the bit orientation backward. The lowest order bit should be attached to PD0, and the highest order bit to PD11. Your mask of the IDR is wrong (11-bits) and you have an unnecessary shift. If you really have the bits on GPIOD wired backward you'll need to do a bit reversal, which is not the same as alignment.

    This has a better chance of functioning

    #include "stm32f2xx.h"
    
    int main(void)
    {
      DAC_InitTypeDef DAC_InitStructure;
      GPIO_InitTypeDef GPIO_InitStruct;
    
      /* GPIOA & D clock enable */
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOD, ENABLE);
    
      /* DAC Periph clock enable */
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
    
      /* GPIO CONFIGURATION of DAC Pins */
    
      GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_4 | GPIO_Pin_5;
      GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AN;
      GPIO_InitStruct.GPIO_PuPd  = GPIO_PuPd_NOPULL;
      GPIO_Init(GPIOA, &GPIO_InitStruct);
    
      /* GPIO CONFIGURATION of input Pin for DHR PD[0..11]
        PD0 Low order bit   V[20]
        PD11 High order bit V[31]
       */
    
      GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
                                 GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 |
                                 GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
      GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
      GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
      GPIO_Init(GPIOD, &GPIO_InitStruct);
    
      /* DAC channel2 Configuration */
      DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;
      DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
      DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
      DAC_Init(DAC_Channel_2, &DAC_InitStructure);
    
      /* Enable DAC Channel2 */
      DAC_Cmd(DAC_Channel_2, ENABLE);
    
      while (1)
        DAC_SetChannel2Data(DAC_Align_12b_R, GPIOD->IDR & 0xFFF); // Mask 12 bits
    
      return(0);
    }
    

Reply
  • The code you presented still isn't complete, there is no way to know that critical steps have been done correctly. The GPIO pins are not initialized properly, ie not 0 thru 11, you have a bunch of pins missing and also define pin 13? Your comments suggest you have the bit orientation backward. The lowest order bit should be attached to PD0, and the highest order bit to PD11. Your mask of the IDR is wrong (11-bits) and you have an unnecessary shift. If you really have the bits on GPIOD wired backward you'll need to do a bit reversal, which is not the same as alignment.

    This has a better chance of functioning

    #include "stm32f2xx.h"
    
    int main(void)
    {
      DAC_InitTypeDef DAC_InitStructure;
      GPIO_InitTypeDef GPIO_InitStruct;
    
      /* GPIOA & D clock enable */
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOD, ENABLE);
    
      /* DAC Periph clock enable */
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
    
      /* GPIO CONFIGURATION of DAC Pins */
    
      GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_4 | GPIO_Pin_5;
      GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AN;
      GPIO_InitStruct.GPIO_PuPd  = GPIO_PuPd_NOPULL;
      GPIO_Init(GPIOA, &GPIO_InitStruct);
    
      /* GPIO CONFIGURATION of input Pin for DHR PD[0..11]
        PD0 Low order bit   V[20]
        PD11 High order bit V[31]
       */
    
      GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
                                 GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 |
                                 GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
      GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
      GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
      GPIO_Init(GPIOD, &GPIO_InitStruct);
    
      /* DAC channel2 Configuration */
      DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;
      DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
      DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
      DAC_Init(DAC_Channel_2, &DAC_InitStructure);
    
      /* Enable DAC Channel2 */
      DAC_Cmd(DAC_Channel_2, ENABLE);
    
      while (1)
        DAC_SetChannel2Data(DAC_Align_12b_R, GPIOD->IDR & 0xFFF); // Mask 12 bits
    
      return(0);
    }
    

Children
  • thanks for your remarks ,
    I fixe the code but no wave generator :/ in oscilloscope
    my code aims to connect the out put of FPGA to input of my MCU ,
    in my card design i have to connect these pins to the GPIO D : that is why i used pin 13 and pin 14 , also not all these pin are available from FPGA such as GPIO_pin_2
    Can I do this ?

     GPIO_InitStruct.GPIO_Pin =  GPIO_Pin_0 |GPIO_Pin_1 |GPIO_Pin_3 |GPIO_Pin_4
                                |GPIO_Pin_5 |GPIO_Pin_6 |GPIO_Pin_8 |GPIO_Pin_9
                                |GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_13|GPIO_Pin_14;
    


    So i do masque like this :

     DAC_SetChannel2Data(DAC_Align_12b_R, GPIOD->IDR & 0xFFF0)
    

    i can use like this ie 16 bit ?

    I have another question you have can you explain me the difference between bit reversal and alignement

  • You can't mask the bits like that, a) the low order bit is at position zero, and b) you have gaps at bit position 2, 7 and 12?

    To mask the bits you're using it would need 0x6F7B, that's going to be a bit of a mess. You need to think carefully about how you're wiring this up, and explain it clearly.

    You will have to group the bits back together.

    Alignment suggests a right or left logical shift in the bits with respect to a desired datum.

    Reversal suggests you have the bits logically switched around, so for an 8-bit number if bit 0 is high it should represent 1, but reversed would be 128, and 2 would be 64, and so forth.

    There seems to be an issue with grasping binary representation, how bits appear within a word, and how that relates to data/patterns you want to represent.

  • yes alright , i have to collect the bit from input carrefully but the probleme i did not find how i place my bits readn from the GPIOD in order to make number of the sinwave between [0 4095]

    my data in the FPGA is a voltatge [32 bits] i want to test this voltatge but i must read only the high bit [0 12] V(0) V(1) V(2) ....V(11)
    So my idea is get the V(0) like an input to the stm32 ie V(0)-> GPIOD_Pin_0 and ....

    i configure port D such as input : the probleme the pins of port D are not in order
    After that i make a dac non triggerd just i must put data into the DHRx register and the Dac will be set ,

    the part which i didn't understand that how to collect these bits V(0) V(1) V(2) ....V(11) in the register DRH , knowing the dac convert data like these [0 4096]

    , i will focus in this section and i'm trying with the DMA

    in this code i try to modify the const sinus and replace it by my data which is the collect of bits GPIOD , but i have a lot of errors :/

      /* Includes ------------------------------------------------------------------*/
    #include "stm32f2xx.h"
    #include "stm32f2xx_conf.h"
    #include "stm32f2xx_gpio.h"
    #include "stm32f2xx_dac.h"
    
                                                                              /* Private typedef -----------------------------------------------------------*/
    /* Private define ------------------------------------------------------------*/
    #define DAC_DHR12R2_ADDRESS    0x40007414
    #define DAC_DHR8R1_ADDRESS     0x40007410
    /* Private variables ---------------------------------------------------------*/
    DAC_InitTypeDef  DAC_InitStructure;
    /*uint16_t DATA ;       */
    const uint16_t Sine12bit[32] = {
                          2047, 2447, 2831, 3185, 3498, 3750, 3939, 4056, 4095, 4056,
                          3939, 3750, 3495, 3185, 2831, 2447, 2047, 1647, 1263, 909,
                          599, 344, 155, 38, 0, 38, 155, 344, 599, 909, 1263, 1647};
    /* Private function prototypes -----------------------------------------------*/
    void TIM6_Config(void);
    void DAC_Ch2_SineWaveConfig(void);
    
    int main(void)
    {
    /* Preconfiguration before using DAC----------------------------------------*/
      GPIO_InitTypeDef GPIO_InitStructure;
    
      /* DMA1 clock and GPIOA clock enable (to be used with DAC) */
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 | RCC_AHB1Periph_GPIOA, ENABLE);
    
      /* DAC Periph clock enable */
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
    
      /* DAC channel 1 & 2 (DAC_OUT1 = PA.4)(DAC_OUT2 = PA.5) configuration */
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
      /* TIM6 Configuration ------------------------------------------------------*/
    
      TIM6_Config();
    
    /* GPIOD clock enable */
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
    
    /* GPIO CONFIGURATION of  input Pin for DHR
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 |GPIO_Pin_0|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|
                                 GPIO_Pin_6|GPIO_Pin_8 |GPIO_Pin_9 |GPIO_Pin_10 |GPIO_Pin_11|GPIO_Pin_13 ;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
    
      */
       while (1)
      {
    
      int Readset ;
        /* If the Key is pressed */
        if (Readset != 0)
        {
          DAC_DeInit();
    
                    while (1)
      {
       /* DATA = GPIOD ->IDR   ;
       DATA = DATA & 0x07FF ;
    
          if (SelectedWavesForm == 1)
          {
    
           Sine Wave generator -----------------------------------------------*/
            DAC_Ch2_SineWaveConfig();
    
          }
         /* else
          {
            The triangle wave and the noise wave has been selected
          }
    
          KeyPressed = RESET; */
        }
      }
      }
    void TIM6_Config(void)
    {
      TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;
      /* TIM6 Periph clock enable */
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
    
      /* Time base configuration */
      TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
      TIM_TimeBaseStructure.TIM_Period = 0xFF;
      TIM_TimeBaseStructure.TIM_Prescaler = 0;
      TIM_TimeBaseStructure.TIM_ClockDivision = 0;
      TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
      TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
    
      /* TIM6 TRGO selection */
      TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);
    
      /* TIM6 enable counter */
      TIM_Cmd(TIM6, ENABLE);
    }
    
    void DAC_Ch2_SineWaveConfig(void)
    {
      DMA_InitTypeDef DMA_InitStructure;
    
      /* DAC channel2 Configuration */
      DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;
      DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
      DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
      DAC_Init(DAC_Channel_2, &DAC_InitStructure);
    
      /* DMA1_Stream5 channel7 configuration **************************************/
      DMA_DeInit(DMA1_Stream5);
      DMA_InitStructure.DMA_Channel = DMA_Channel_7;
      DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)DAC_DHR12R2_ADDRESS;       // a modifier
      DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&Sine12bit;               // à modofier
      DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
      DMA_InitStructure.DMA_BufferSize = 32;
      DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
      DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
      DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
      DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
      DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
      DMA_InitStructure.DMA_Priority = DMA_Priority_High;
      DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
      DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
      DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
      DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
      DMA_Init(DMA1_Stream5, &DMA_InitStructure);
    
      /* Enable DMA1_Stream5 */
      DMA_Cmd(DMA1_Stream5, ENABLE);
    
      /* Enable DAC Channel2 */
      DAC_Cmd(DAC_Channel_2, ENABLE);
    
      /* Enable DMA for DAC Channel2 */
      DAC_DMACmd(DAC_Channel_2, ENABLE);
    }
    
     void assert_failed(uint8_t* file, uint32_t line)
    {
      /* User can add his own implementation to report the file name and line number,
         ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    
      /* Infinite loop */
      while (1)
      {
      }
    }
    
    
    /**
      * @}
      */
    
    /**
      * @}
      */
    
    /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
    
    

  • my data in the FPGA is a voltage [32 bits] i want to test this voltage but i must read only the high bit [0 12] V(0) V(1) V(2) ....V(11) So my idea is get the V(0) like an input to the stm32 ie V(0)-> GPIOD_Pin_0 and ....

    But think about this very carefully. GPIOD_Pin_0 is expecting the LOWest order bit, you are telling me V(0) is the HIGHest order bit, you understand why I think this is BACKWARD?

    You write 4095 (0x0FFF) to the DAC you expect the output to be approximately VREF (3V?), you change the LOW bit so you get 4094 (0x0FFE) you drop 1/4096th of VREF, so the output will still be practically VREF (3V)

  • So , how can i do , You think i'll put the V(16) to GPIOD_Pin_0 , V(17) to GPIOD_Pin_1 ....