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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.