Forum: Mikrocontroller und Digitale Elektronik DAC-Sinus über Audio auf STM32F4 anhören


von Kik N. (electroprince)


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);

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.