
/******************************************************************************
*@file  : app.c
*@brief : application
******************************************************************************/

#include "app.h" 

TIM_Base_InitTypeDef TIM_TimeBaseInitStruct;
volatile uint32_t gtimer_Update_Flag; 
uint16_t gindex = 0; 
DMA_InitTypeDef DMA_InitStruct = {0};
DMA_InitTypeDef DMA_InitStruct_DAC_Ch0 = {0};
DMA_InitTypeDef DMA_InitStruct_DAC_Ch1 = {0};
//正弦波单个周期的点数
#define POINT_NUM 250

/* DAC单通道sine波数据 */
uint16_t Singel_Sin_data_12bit[POINT_NUM] = {
    2099,2151,2202,2254,2305,2356,2406,2457,2507,2557,2607,2656,2705,2754,2802,
    2850,2897,2943,2989,3035,3079,3124,3167,3210,3252,3293,3334,3373,3412,3450,
    3487,3523,3558,3593,3626,3658,3690,3720,3749,3777,3804,3830,3855,3879,3901,
    3922,3943,3962,3979,3996,4011,4025,4038,4049,4060,4069,4076,4083,4088, 4092,
    4095,4095,4095,4095,4092,4088,4083,4076,4069,4060,4049,4038,4025,4011,3996,
    3979,3962,3943,3922,3901,3879,3855,3830,3804,3777,3749,3720,3690,3658,3626,
    3593,3558,3523,3487,3450,3412,3373,3334,3293,3252,3210,3167,3124,3079,3035,
    2989,2943,2897,2850,2802,2754,2705,2656,2607,2557,2507,2457,2406,2356,2305,
    2254,2202,2151,2099,2048,1997,1945,1894,1842,1791,1740,1690,1639,1589,1539,
    1489,1440,1391,1342,1294,1246,1199,1153,1107,1061,1017,972,929,886,844,803,
    762,723,684,646,609,573,538,503,470,438,406,376,347,319,292,266,241,217,195,
    174,153,134,117,100,85,71,58,47,36,27,20,13,8,4,1,0,0,1,4,8,13,20,27,36,47,
    58,71,85,100,117,134,153,174,195,217,241,266,292,319,347,376,406,438,470,503,
    538,573,609,646,684,723,762,803,844,886,929,972,1017,1061,1107,1153,1199,1246,
    1294,1342,1391,1440,1489,1539,1589,1639,1690,1740,1791,1842,1894,1945,1997,2048
};

/* DAC双通道sine波数据buffer */
uint32_t Dual_Sin_data_12bit[POINT_NUM];

/*DMA双数据模式 sine波数据buffer*/
uint32_t DAMDualData_Sine12bit[POINT_NUM / 2];
/******************************************************************************
* @brief : DAC output Sin initialization.
* @param : None.
* @return: None
******************************************************************************/
void DAC_Config_OutPut_Sinx()
{
    DAC_InitTypeDef sConfig;

    sConfig.DAC_Trigger = DAC_TRIGGER_SOFTWARE;
    sConfig.DAC_Trigger2 = DAC_TRIGGER_SOFTWARE;
    sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
    
    sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
    sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_BOTH;  
    sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;

    DAC_Init(DAC,DAC_CHANNEL_1, &sConfig);    
    DAC_Init(DAC,DAC_CHANNEL_2, &sConfig);  

}

/******************************************************************************
* @brief : DAC output noise initialization.
* @param : None.
* @return: None
******************************************************************************/
void DAC_Config_OutPut_Noise(void)
{
    DAC_InitTypeDef sConfig={0};
    
    sConfig.DAC_Trigger = DAC_TRIGGER_SOFTWARE;
    /* DAC_Trigger2 仅用来配置锯齿波的递增触发 */
    sConfig.DAC_Trigger2 = DAC_TRIGGER_SOFTWARE;
    
    sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
    sConfig.DAC_OutputBuffer =  DAC_OUTPUTBUFFER_DISABLE;
    sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_EXTERNAL;
    sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
    
    /* DAC_Init()一次只配置一个DAC通道 */
    /* DAC通道1配置使用软件触发 */
    DAC_Init(DAC,DAC_CHANNEL_1, &sConfig);   

    /* DAC通道2配置使用TIM6触发 */
    sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO;
    DAC_Init(DAC,DAC_CHANNEL_2, &sConfig); 
}
/******************************************************************************
* @brief : DAC output noise.
* @param : None.
* @return: None
******************************************************************************/
void DAC_OutPut_Noise()
{
    /* 设置DAC 输出的 基本电压 */
    DAC_SetDualChannelData(DAC,DAC_ALIGN_12B_R, 1000, 1000);
    
    /* 在DAC 通道1上叠加噪声 */
    DACEx_NoiseWaveGenerate(DAC, DAC_CHANNEL_1, DAC_LFSRUNMASK_BITS9_0); 
    
    /* 在DAC 通道2上叠加三角波 */
    DACEx_TriangleWaveGenerate(DAC, DAC_CHANNEL_2, DAC_TRIANGLEAMPLITUDE_2047);
    
    DAC_Cmd(DAC, DAC_CHANNEL_1,ENABLE);

    /* 启动DAC转换 */
    /* DAC通道2启动后， 后面由TIM6触发 */
    DAC_Cmd(DAC, DAC_CHANNEL_2,ENABLE); 
    
    while(1)
    {

        /* DAC通道1 需要软件来每次触发 */
        DAC_SoftwareTriggerCmd(DAC, DAC_CHANNEL_1,ENABLE);
        DelayMs(10);
    }
}
void DAC_Config_OutPut_Sawtooth(void)
{
    DAC_InitTypeDef sConfig={0};

    sConfig.DAC_Trigger = DAC_TRIGGER_SOFTWARE;
    sConfig.DAC_Trigger2 = DAC_TRIGGER_SOFTWARE;
    
    sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
    sConfig.DAC_OutputBuffer =  DAC_OUTPUTBUFFER_DISABLE;
    sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_EXTERNAL;
    sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
    
    /* DAC_Init()一次只配置一个DAC通道 */
    /* DAC通道1锯齿波 reset:软件触发,step:软件触发 */
    DAC_Init(DAC,DAC_CHANNEL_1, &sConfig); 

    /* DAC通道2锯齿波 reset:软件触发,step:TIM6触发 */
    sConfig.DAC_Trigger = DAC_TRIGGER_SOFTWARE;
    sConfig.DAC_Trigger2 = DAC_TRIGGER_T6_TRGO;
    DAC_Init(DAC,DAC_CHANNEL_2, &sConfig); 
}

void DAC_OutPut_Sawtooth()
{
    /* DAC通道1锯齿波为递增模式 */
    DACEx_SawtoothWaveGenerate(DAC, DAC_CHANNEL_1, DAC_SAWTOOTH_POLARITY_INCREMENT, 0, 4);//0.0625
    /* DAC通道2锯齿波为递减模式 */
    DACEx_SawtoothWaveGenerate(DAC, DAC_CHANNEL_2, DAC_SAWTOOTH_POLARITY_DECREMENT, 0xfff, 8);//0.0625
    
    DAC_Cmd(DAC, DAC_CHANNEL_1,ENABLE);

    /* 启动DAC转换 */
    /* DAC通道2启动后， 后面由TIM6触发 */
    DAC_Cmd(DAC, DAC_CHANNEL_2,ENABLE); 
    while(1)
    {
        /* DAC通道1锯齿波的递增配置为使用软件触发，因此需要软件来每次触发 */
        DACEx_SawtoothWaveDataStep(DAC, DAC_CHANNEL_1);  
        
        /* DAC通道1锯齿波的递增配置为使用TIM6触发 */
        

        /* DAC通道1和2的锯齿波的复位都配置为使用软件触发 */
        if(DAC_GetDataOutputValue(DAC, DAC_CHANNEL_1)==0xfff)  
        {
			DACEx_SawtoothWaveDataResetBySoftware(DAC, DAC_CHANNEL_1);  
        }        
        if(DAC_GetDataOutputValue(DAC, DAC_CHANNEL_2)==0x0)     
        {
			DACEx_SawtoothWaveDataResetBySoftware(DAC, DAC_CHANNEL_2);              
        } 
    }
}
/******************************************************************************
* @brief : DAC output voltage initialization.
* @param : None.
* @return: None
******************************************************************************/
void DAC_Config_OutPut_Voltage()
{

    DAC_InitTypeDef sConfig; 
    sConfig.DAC_Trigger = DAC_TRIGGER_SOFTWARE;
    sConfig.DAC_Trigger2 = DAC_TRIGGER_SOFTWARE;
    sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
    sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
    sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_EXTERNAL;  
    sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;

    DAC_Init(DAC,DAC_CHANNEL_1, &sConfig); 
    DAC_Init(DAC,DAC_CHANNEL_2, &sConfig); 

    /* 自动校准，可根据需要开启/关闭 */
    DACEx_SelfCalibrate(DAC, &sConfig,DAC_CHANNEL_1);
    DACEx_SelfCalibrate(DAC, &sConfig,DAC_CHANNEL_2);
    Delay_Simple(500000);
}
/******************************************************************************
* @brief : DAC output voltage.
* @param : voltage ：output voltage value.
* @return: None
******************************************************************************/
void DAC_OutPutVoltage(float voltage)
{
    if( voltage > 3.3)
    {
        return;
    }
    uint16_t data=((voltage / 3.3) * 4095);
    DAC_SetDualChannelData(DAC,DAC_ALIGN_12B_R,data,data);
    DAC_Cmd(DAC, DAC_CHANNEL_1,ENABLE);
    DAC_Cmd(DAC, DAC_CHANNEL_2,ENABLE); 
    DAC_SoftwareTriggerCmd(DAC, DAC_CHANNEL_1,ENABLE);
    DAC_SoftwareTriggerCmd(DAC, DAC_CHANNEL_2,ENABLE);
    while(1)
    {

    }
}
void DAC_GPIO_Init(void)
{
    __RCC_GPIOA_CLK_ENABLE();
        /* Initialization GPIO */
        /**DAC1 GPIO Configuration    
        PA4  ------> DAC_OUT1 
        PA5  ------> DAC_OUT2 
        */
    GPIO_InitTypeDef GPIO_handle;
    GPIO_handle.Drive = GPIO_DRIVE_LEVEL3;
    GPIO_handle.Mode = GPIO_MODE_ANALOG;
    GPIO_handle.Pin = GPIO_PIN_4|GPIO_PIN_5;
    GPIO_handle.Pull = GPIO_NOPULL;
    GPIO_Init(GPIOA,&GPIO_handle);

}
/******************************************************************************
* @brief : DAC Output config.
* @param : None.
* @return: None
******************************************************************************/
void DAC_Config_OutPut()
{
    DAC_InitTypeDef sConfig={0}; 

    sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO;
    sConfig.DAC_Trigger2 = DAC_TRIGGER_T8_TRGO; 
    sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
    sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
    sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_EXTERNAL;
    sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
    DAC_Init(DAC,DAC_CHANNEL_1, &sConfig);    
    DAC_Init(DAC,DAC_CHANNEL_2, &sConfig);  
    DAC_Cmd(DAC, DAC_CHANNEL_1,ENABLE);
    DAC_Cmd(DAC, DAC_CHANNEL_2,ENABLE); 

}
/******************************************************************************
* @brief : DMA config.
* @param : None.
* @return: None
******************************************************************************/

static void DAC_DMA_Config()
{
    uint32_t Idx=0;
    /* write Sinx data from   Singel_Sin_data_12bit to Dual_Sin_data_12bit */
    for (Idx = 0; Idx < POINT_NUM; Idx++)
    {
        Dual_Sin_data_12bit[Idx] = (Singel_Sin_data_12bit[Idx] << 16) + (Singel_Sin_data_12bit[Idx]);
    }
    __RCC_DMA1_CLK_ENABLE();
    /* DAC DMA Init */
    /* DAC_CH1 Init */

    DMA_InitStruct.Mode = DMA_MODE_CIRCULAR;
    DMA_InitStruct.DataFlow = DMA_DATAFLOW_M2P;
    DMA_InitStruct.ReqID = DMA1_REQ39_DAC1_CH1;
    DMA_InitStruct.SrcInc = DMA_SRCINC_ENABLE;
    DMA_InitStruct.DestInc = DMA_DESTINC_DISABLE;
    DMA_InitStruct.SrcWidth = DMA_SRCWIDTH_WORD;
    DMA_InitStruct.DestWidth = DMA_DESTWIDTH_WORD;
    DMA_InitStruct.DestAddr = (uint32_t)(&(DAC->DHR12RD));
    DMA_InitStruct.SrcAddr = (uint32_t)Dual_Sin_data_12bit;
    DMA_InitStruct.Size        = POINT_NUM;
    DMA_InitStruct.RawInt = DMA_CHCTRL_ITC;
    DMA_Init(DMA1_Channel0, &DMA_InitStruct);

    DMA_ClearFlag(DMA1_Channel0,DMA_FLAG_TC);
    DMA_ITConfig(DMA1_Channel0,DMA_IT_TC,ENABLE);
    
    NVIC_ClearPendingIRQ(DMA1_IRQn);
    NVIC_EnableIRQ(DMA1_IRQn);

} 
void DAC_Config_OutPut_DMADualData()
{
    DAC_InitTypeDef sConfig={0}; 
    
    sConfig.DAC_DMADoubleDataMode = ENABLE;
    sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO;
    sConfig.DAC_Trigger2 = DAC_TRIGGER_T8_TRGO; 
    sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
    sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
    sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_EXTERNAL;
    sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
    DAC_Init(DAC,DAC_CHANNEL_1, &sConfig);    
    DAC_Init(DAC,DAC_CHANNEL_2, &sConfig);  
    DAC_Cmd(DAC, DAC_CHANNEL_1,ENABLE);
    DAC_Cmd(DAC, DAC_CHANNEL_2,ENABLE); 
}
static void DAC_DMADualData_Config()
{

    uint32_t i = 0;
    uint32_t j = 0;
    /* write Sinx data from   Singel_Sin_data_12bit to Dual_Sin_data_12bit */
    for (i = 0, j = 0; j < POINT_NUM / 2; i += 2, j++)
    {
        DAMDualData_Sine12bit[j] = (Singel_Sin_data_12bit[i + 1] << 16) + (Singel_Sin_data_12bit[i]);
    }
    __RCC_DMA1_CLK_ENABLE();
    /* DAC DMA Init */
    /* DAC_CH1 Init */
    DMA_InitStruct_DAC_Ch0.Mode = DMA_MODE_CIRCULAR;
    DMA_InitStruct_DAC_Ch0.DataFlow = DMA_DATAFLOW_M2P;
    DMA_InitStruct_DAC_Ch0.ReqID = DMA1_REQ39_DAC1_CH1;
    DMA_InitStruct_DAC_Ch0.SrcInc = DMA_SRCINC_ENABLE;
    DMA_InitStruct_DAC_Ch0.DestInc = DMA_DESTINC_DISABLE;
    DMA_InitStruct_DAC_Ch0.SrcWidth = DMA_SRCWIDTH_WORD;
    DMA_InitStruct_DAC_Ch0.DestWidth = DMA_DESTWIDTH_WORD;
    DMA_InitStruct_DAC_Ch0.SrcAddr     = (uint32_t)DAMDualData_Sine12bit;
    DMA_InitStruct_DAC_Ch0.DestAddr    = (uint32_t)(&(DAC->DHR12R1));
    DMA_InitStruct_DAC_Ch0.Size        = POINT_NUM / 2;
    DMA_InitStruct_DAC_Ch0.RawInt = DMA_CHCTRL_ITC;
    DMA_Init(DMA1_Channel0, &DMA_InitStruct_DAC_Ch0);

    /* DAC_CH2 Init */
    DMA_InitStruct_DAC_Ch1.Mode =DMA_MODE_CIRCULAR;
    DMA_InitStruct_DAC_Ch1.DataFlow = DMA_DATAFLOW_M2P;
    DMA_InitStruct_DAC_Ch1.ReqID = DMA1_REQ40_DAC1_CH2;
    DMA_InitStruct_DAC_Ch1.SrcInc = DMA_SRCINC_ENABLE;
    DMA_InitStruct_DAC_Ch1.DestInc = DMA_DESTINC_DISABLE;
    DMA_InitStruct_DAC_Ch1.SrcWidth = DMA_SRCWIDTH_WORD;
    DMA_InitStruct_DAC_Ch1.DestWidth = DMA_DESTWIDTH_WORD;
    DMA_InitStruct_DAC_Ch1.SrcAddr     = (uint32_t)DAMDualData_Sine12bit;
    DMA_InitStruct_DAC_Ch1.DestAddr    = (uint32_t)(&(DAC->DHR12R2));
    DMA_InitStruct_DAC_Ch1.Size        = POINT_NUM / 2;
    DMA_InitStruct_DAC_Ch1.RawInt = DMA_CHCTRL_ITC;
    DMA_Init(DMA1_Channel1, &DMA_InitStruct_DAC_Ch1);
    

    NVIC_ClearPendingIRQ(DMA1_IRQn);
    NVIC_EnableIRQ(DMA1_IRQn);

}

#if 1
/******************************************************************************
* @brief : Timer6 initialization.
* @param : None.
* @return: None
******************************************************************************/
void DAC_TIM6_Init(void)  
{
   
	TIM_TimeBaseInitStruct.ClockDivision = TIM_CLOCKDIVISION_DIV1; 
	TIM_TimeBaseInitStruct.CounterMode = TIM_COUNTERMODE_UP; 
	TIM_TimeBaseInitStruct.RepetitionCounter = 0;  

    TIM_TimeBaseInitStruct.Prescaler = 240 - 1;  
	TIM_TimeBaseInitStruct.Period = 1;  
    __RCC_TIM6_RESET();   
    __RCC_TIM6_CLK_ENABLE();          
    NVIC_ClearPendingIRQ(TIM6_IRQn);   
    NVIC_EnableIRQ(TIM6_IRQn);       
	TIM_TimeBase_Init(TIM6,&TIM_TimeBaseInitStruct);    
    TIM_ITConfig(TIM6, TIMER_INT_EN_UPD, ENABLE);
	
	TIM_Cmd(TIM6,ENABLE);           
}
#endif
/******************************************************************************
* @brief : DAC Timer Trigger Configuration.
* @param : Timer: Timer selection.
* @param : Trgo: Master mode selection.
* @param : Prescaler: Timer prescaler.
* @param : Period: Timer period.
* @return: None
******************************************************************************/
void DAC_TIMx_TRGOx_Init(uint8_t Timer,uint8_t Trgo,uint16_t Prescaler,uint16_t Period)
{
    uint32_t timer_clock;
    TIM_Base_InitTypeDef TIM_TimeBaseInitStruct={0};

    TIM_TypeDef *TIMx;
    switch(Timer)	
    {
        case 2:
            __RCC_TIM2_CLK_ENABLE() ;
            TIMx = TIM2;		    
        break;
        case 3:
            __RCC_TIM3_CLK_ENABLE() ;
            TIMx = TIM3;	
        break;
        case 4:
            __RCC_TIM4_CLK_ENABLE() ;
            TIMx = TIM4;	
        break;
        case 6:
            __RCC_TIM6_CLK_ENABLE() ;
            TIMx = TIM6;	
        break;
        case 7:
            __RCC_TIM7_CLK_ENABLE() ;
            TIMx = TIM7;	
        break;
        case 8:
            __RCC_TIM8_CLK_ENABLE() ;
            TIMx = TIM8;	
        break;
        case 15:
            __RCC_TIM15_CLK_ENABLE() ;
            TIMx = TIM15;	
        break;
        default:
            printfS("Please select the correct timer");
            return;
    }
        
    TIM_TimeBaseInitStruct.ClockDivision = TIM_CLOCKDIVISION_DIV1; 
    TIM_TimeBaseInitStruct.CounterMode = TIM_COUNTERMODE_UP; 
    TIM_TimeBaseInitStruct.RepetitionCounter = 0;  
    TIM_TimeBaseInitStruct.Prescaler = Prescaler - 1;
    TIM_TimeBaseInitStruct.Period = Period - 1;  
 
    TIM_TimeBase_Init(TIMx,&TIM_TimeBaseInitStruct);  
//    switch(Trgo)
//    {
//        case 1:
//            sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
//        break;
//        case 2:
//            sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_UPDATE;
//        break;
//    }
//Trgo默认选择Trgo1，还需确认trgo2是否能触发dac
    TIM_SelectMasterSlaveMode(TIMx, TIM_MASTERSLAVEMODE_DISABLE); 
    TIM_SelectOutputTrigger(TIMx, TIM_TRGO_UPDATE);  
    TIM_Cmd(TIMx,ENABLE);   
} 
/******************************************************************************
* @brief : TIM6 interrupt callback function.
* @param : htim : pointer to a TIM_HandleTypeDef structure that contains
*                      the configuration information for Timer module.
* @return: None
******************************************************************************/
void TIM_Updeate_Event_Callback(void)
{
    gtimer_Update_Flag = 1;   
}

void APP_DAC_Demo(DAC_TEST_MODE_t fe_Mode)
{
    DAC_GPIO_Init();
    __RCC_DAC1_CLK_ENABLE();
    switch (fe_Mode)
    {
        /* 输出噪音 */
        case DAC_Output_Noise: 
        {
            printfS("DAC Output Noise wave\r\n\r\n");
            DAC_Config_OutPut_Noise();
            DAC_TIMx_TRGOx_Init(6, 1, 300, 2);
            DAC_OutPut_Noise();
        }
        break;
        case DAC_Output_SAWTOOTH: 
        {
            printfS("DAC Output Swatooth wave\r\n\r\n");
            DAC_Config_OutPut_Sawtooth();
            /* 使用TIM6来触发DAC通道2的step触发 */
            DAC_TIMx_TRGOx_Init(6, 1, 300, 2);
            DAC_OutPut_Sawtooth();
        }
        break;
        /* 输出电压 */
        case DAC_OutPut_Voltage: 
        {
            printfS("DAC Output Voltage\r\n\r\n");
            DAC_Config_OutPut_Voltage();
            DAC_OutPutVoltage(2.5);
        }
        break;
  
        /* TIM6 update中断，软件设置DAC值来输出正弦波 */
        case DAC_OutPut_Sinx:
        {
            printfS("DAC Output SINE Wave by software dynamically setting DAC output Value\r\n\r\n");
            DAC_Config_OutPut_Sinx(); 
            DAC_TIM6_Init();
            gtimer_Update_Flag = 0;
            while(1) 
            {
                if(gtimer_Update_Flag) 
                {
                    gtimer_Update_Flag = 0;
                    DAC_SetDualChannelData(DAC,DAC_ALIGN_12B_R,Singel_Sin_data_12bit[gindex],Singel_Sin_data_12bit[gindex]);
                    DAC_Cmd(DAC, DAC_CHANNEL_1,ENABLE);
                    DAC_Cmd(DAC, DAC_CHANNEL_2,ENABLE); 
                    DAC_SoftwareTriggerCmd(DAC, DAC_CHANNEL_1,ENABLE);
                    DAC_SoftwareTriggerCmd(DAC, DAC_CHANNEL_2,ENABLE);
                    gindex++;
                    //若Sin表已到达结尾，重新指向表头
                    if( gindex >=  POINT_NUM)			
                    {
                        gindex=0;								
                    }                      
                }
            }
        }
        break;   
       
        /* DAC双通道 DMA方式输出正弦波 */
        /* 一个32bit数据对应DAC 两个通道，分别放入DAC的两个通道的DOR */
        /* 一个32bit数据（两个12bit数据，DHRXXD），DAC两个通道同时使用 */
        case DAC_DMA_Output_Sinx:
        {
            printfS("DAC Output SINE Wave by DMA transferring data to both channels(DAC_DHR8RD)\r\n\r\n");
            /* DAC 通道1选择 TIM6 作为触发输入*/
            DAC_Config_OutPut(); 
            DAC_TIMx_TRGOx_Init(6, 1, 240,10);
            DAC_DMA_Config() ;
            
            DAC_DMACmd(DAC, DAC_CHANNEL_1,ENABLE);
            DMA_Cmd(DMA1_Channel0,ENABLE);

            while(1)
            {

            }        
        }
        break;

        /* DMA双数据模式输出正弦波 */
        /* 一次DAM请求搬运一个32bit数据（两个12bit的DAC数据），依次通过外部trigger放入某一个DAC通道的DOR */
        /* 一个32bit数据（两个12bit数据，DHRXX1或DHRXX2），依次给DAC一个通道使用 */
        case DAC_DMADUALDATA_Output_Sinx:
        {
            printfS("DAC Output SINE Wave by DMA transferring dual-12bit-data(one word) to one channel each time(DAC_DHR12Rx)\r\n\r\n");
            DAC_Config_OutPut_DMADualData(); 
            DAC_DMADualData_Config();
            DAC_TIMx_TRGOx_Init(6, 1, 300, 10);

            DAC_DMACmd(DAC, DAC_CHANNEL_1,ENABLE);
            DAC_DMACmd(DAC, DAC_CHANNEL_2,ENABLE);
            
            DMA_Cmd(DMA1_Channel0, ENABLE);
            DMA_Cmd(DMA1_Channel1, ENABLE);
            
        }
            break;

        default: break; 
    }

}

