DAC-Sinus über Audio auf STM32F4 anhören

#3780056
Lesenswert?

Hallo an Alle,

Ich habe ein Problem und bitte um Hilfe.

Ich generiere jeweils mit DAC über PIN04 und PIN05  zwei Sinussignale am 
STM32F407VG- Board , die mit einer Abtastfrequenz von 8 kHz abgetastet 
werden.

Ich kämpfe seit längerer Zeit darum, diese Signale mithilfe von I2S und 
I2C auf den Audio-Ausgang CS43l22 rauszuschreiben. Ich möchte mir 
einfach ganz normal diese 2 Sinuswellen (aufaddiert als Klang zweier 
Töne) anhören können.

Hier unten C-Code mit Codec c. dazu:

#include "stm32f4xx_tim.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_spi.h"
#include "stm32f4xx_i2c.h"
#include "main.h"

#include<stdio.h>
#include<stdlib.h>
#include<math.h>


#define PI 3.14159265

 int k = 0;
 float fsin_1 = 347.826087;
float fsin_2 =  615.3846154;
int r = 0;        //Variable r zum Erfassen der Signallänge vom Sensor
double sin_digital_1 = 0;    // digital generiertes Sinussignal von PA04
double sin_digital_2 = 0;    // digital generiertes Sinussignal von PA05
double Ts = 0.000125;   // die Abtastperiode

// Aktivierung von Ports und mit den dazugehörigen Timern


void rcc_konfigurieren(void){

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);

        //enables GPIO clock for PortD

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

  GPIO_Init(GPIOD, &GPIO_InitStructure);


  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);


   // Aktivierung von Alternate Function und von DAC
       RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE)

          }


           void gpio_konfigurieren(void) {

           GPIO_InitTypeDef GPIO_InitStructure;
                                                                                                                                                      /* 
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_AIN;
          GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
          GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
          GPIO_Init(GPIOA, &GPIO_InitStructure);

        // Timer4 für die Abtastperiode Ts

        GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_Init(GPIOB, &GPIO_InitStructure);

        GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_TIM4);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOD, &GPIO_InitStructure);
}




       void DAC_setup(void)
       {
       DAC_InitTypeDef DAC_InitStructure;

       RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
       RCC_APB2PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
      //  Der Kanal_1 für PA04   DAC_InitStructure.DAC_Trigger = 
DAC_Trigger_T6_TRGO; //DAC_Trigger_None;
       DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
       DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude =
       DAC_LFSRUnmask_Bits8_0;         // 8-Bit Format
       DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
       DAC_Init(DAC_Channel_1, &DAC_InitStructure);
       DAC_Cmd(DAC_Channel_1, ENABLE);

       DAC_SoftwareTriggerCmd(DAC_Channel_1, ENABLE);

      // Der Kanal_2 für PA05
       DAC_InitStructure.DAC_Trigger =  DAC_Trigger_T7_TRGO;
       DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
       DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude =
       DAC_LFSRUnmask_Bits8_0;
       DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
       DAC_Init(DAC_Channel_2, &DAC_InitStructure);

       DAC_Cmd(DAC_Channel_2, ENABLE);
        DAC_SoftwareTriggerCmd(DAC_Channel_2, ENABLE);

     }



        // Konfiguration der 4 kHz- Abtastfrequenz
         void modus_Ts_timer6 (void){

          TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
          RCC_APB1PeriphClockCmd(  RCC_APB1Periph_TIM6, ENABLE);
          TIM_Cmd(TIM6, DISABLE);

          TIM_TimeBaseStructure.TIM_Prescaler = 240;
          TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
          TIM_TimeBaseStructure.TIM_Period = 14;
          TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
          TIM_TimeBaseStructure.TIM_RepetitionCounter =0x0;
          TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
          TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);
          TIM_Cmd(TIM6, ENABLE);
           }

         // Trigger Timer
         void modus_Ts_timer7 (void){

          TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
           RCC_APB1PeriphClockCmd   (RCC_APB1Periph_TIM7, ENABLE);
           TIM_Cmd(TIM7, DISABLE);

          TIM_TimeBaseStructure.TIM_Prescaler = 240;
          TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
          TIM_TimeBaseStructure.TIM_Period = 14;
          TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
          TIM_TimeBaseStructure.TIM_RepetitionCounter =0x0;
          TIM_TimeBaseInit(TIM7, &TIM_TimeBaseStructure);
          TIM_SelectOutputTrigger(TIM7, TIM_TRGOSource_Update);
          TIM_Cmd(TIM7, ENABLE);

 }



     // TIM4 zum Zählen einzelner Abtastperioden mit Abtastfrequenz = 4 
kHz
   void timer4_konfigurieren (void)          {



     TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  //   TIM_OCInitTypeDef TIM_OCInitStructure;

     TIM_TimeBaseStructure.TIM_Prescaler =  240;
     TIM_TimeBaseStructure.TIM_Period =   14;
     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
     TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

    TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
     TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);


    // Das Ergebnis optional auf einen Pin rausschreiben
   /*  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
     TIM_OCInitStructure.TIM_Pulse = 25;
     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

     TIM_OC1Init(TIM4, &TIM_OCInitStructure);   */
     TIM_Cmd( TIM4, ENABLE);

}




          void TIM4_IRQHandler(void)
           {
              static  int  k1=0;
              static  int  k2=0;


            // Festlegung der Amplitude für den Sinus   */
            if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
             {

          // Generieren der digitalen Sinussignale

           sin_digital_1 =  floor (( 90 * sin(2*PI*fsin_1*k1*Ts)))+ 80;
           sin_digital_2 =  floor (( 90 * sin(2*PI*fsin_2*k2*Ts)))+ 80;

    // Ausschreiben der Abtastperioden in die beiden Register  -> PIN04 
und PIN05 von GPIOA

           DAC_SetChannel1Data(DAC_Align_8b_R, sin_digital_1);
           DAC_SetChannel2Data(DAC_Align_8b_R, sin_digital_2);

     // Hinaufzählen der Laufvariablen beim Generierungsvorgang
                     // für 347.8260
                      k1++;
                      if (k1>= 23) {
                      k1=0;
                              }
                  // für 615.3846
                      k2++;
                      if(k2>=13){
                      k2=0;

            }  // Pending Bit zurücksetzen

                  TIM_ClearITPendingBit(TIM4, TIM_IT_Update);

             }
             }
             }

          void nvic_konfigurieren(void)
        {
         NVIC_InitTypeDef NVIC_InitStructure;
         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);


         NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
         NVIC_Init(&NVIC_InitStructure);

    }

         int main(void)
         {


          SystemInit();
          rcc_konfigurieren();
          gpio_konfigurieren ();
          nvic_konfigurieren();
          DAC_setup ();


            modus_Ts_timer6 ();
            modus_Ts_timer7 ();
            timer4_konfigurieren();

            codec_init();
            codec_ctrl_init();

             I2S_Cmd(CODEC_I2S, ENABLE);

             while(1)
            {

             if (SPI_I2S_GetFlagStatus(CODEC_I2S, SPI_I2S_FLAG_TXE))
            {

     SPI_I2S_SendData(CODEC_I2S, sin_digital_1); //bloßes Reinschreiben
               funktioniert nicht!!!
        }
      }
    }


-----------------------------
Codec c  (Konfigurationen)

void codec_init()

{


  I2S_InitTypeDef I2S_InitType;

  I2C_InitTypeDef I2C_InitType;

  SPI_InitTypeDef SPI_InitType;
  GPIO_InitTypeDef PinInitStruct;
  GPIO_StructInit(&PinInitStruct);



  //Reset pin as GPIO
  PinInitStruct.GPIO_Pin = CODEC_RESET_PIN;
  PinInitStruct.GPIO_Mode = GPIO_Mode_OUT;
  PinInitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
  PinInitStruct.GPIO_OType = GPIO_OType_PP;
  PinInitStruct.GPIO_Speed = GPIO_Speed_50MHz;



  GPIO_Init(GPIOD, &PinInitStruct);

  // I2C pins
  PinInitStruct.GPIO_Mode = GPIO_Mode_AF;
  PinInitStruct.GPIO_OType = GPIO_OType_OD;
  PinInitStruct.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN;
  PinInitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
  PinInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &PinInitStruct);

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1);

  //enable I2S and I2C clocks
  //RCC_I2SCLKConfig(RCC_I2S2CLKSource_PLLI2S);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 | RCC_APB1Periph_SPI3, 
ENABLE);
  RCC_PLLI2SCmd(ENABLE);

  // I2S pins
  PinInitStruct.GPIO_OType = GPIO_OType_PP;
PinInitStruct.GPIO_Pin = I2S3_SCLK_PIN | I2S3_SD_PIN | I2S3_MCLK_PIN;
  GPIO_Init(GPIOC, &PinInitStruct);

  PinInitStruct.GPIO_Pin = I2S3_WS_PIN;
  GPIO_Init(GPIOB, &PinInitStruct);

  //prepare output ports for alternate function
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_SPI3);
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_SPI3);
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_SPI3);
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_SPI3);


  //keep Codec off for now
  GPIO_ResetBits(GPIOD, CODEC_RESET_PIN);


  // configure I2S port
  SPI_I2S_DeInit(CODEC_I2S);
  I2S_InitType.I2S_AudioFreq = I2S_AudioFreq_8k;
  I2S_InitType.I2S_MCLKOutput = I2S_MCLKOutput_Enable;
  I2S_InitType.I2S_DataFormat = I2S_DataFormat_16b;
  I2S_InitType.I2S_Mode = I2S_Mode_MasterTx;
  I2S_InitType.I2S_Standard = I2S_Standard_Phillips;
  I2S_InitType.I2S_CPOL = I2S_CPOL_Low;

  I2S_Init(CODEC_I2S, &I2S_InitType);
  //I2S_Cmd(CODEC_I2S, ENABLE);


   // configure I2C port
  I2C_DeInit(CODEC_I2C);
  I2C_InitType.I2C_ClockSpeed = 100000;
  I2C_InitType.I2C_Mode = I2C_Mode_I2C;
  I2C_InitType.I2C_OwnAddress1 = CORE_I2C_ADDRESS;
  I2C_InitType.I2C_Ack = I2C_Ack_Enable;
  I2C_InitType.I2C_AcknowledgedAddress = 
I2C_AcknowledgedAddress_7bit;
  I2C_InitType.I2C_DutyCycle = I2C_DutyCycle_2;

  I2C_Cmd(CODEC_I2C, ENABLE);
  I2C_Init(CODEC_I2C, &I2C_InitType);

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren