loreal1970 0 28 апреля, 2015 Опубликовано 28 апреля, 2015 (изменено) · Жалоба Ребята помогите! Не могу воспроизвести wav с карточки. Хочу сказать фразу по нажатию кнопки. Карта читается. Проблема то ли с ЦАП-ом, то ли выводом данных. В общем лыжи наглухо в асфальте. Вот инит ЦАПа: void Init_Sound(void) { DAC_InitTypeDef DAC_InitStructure; DMA_InitTypeDef DMA_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC | RCC_APB1Periph_TIM6, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseStructure.TIM_Period = 72-1; // TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update); DMA_DeInit(DMA2_Channel3); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&DAC->DHR8R1; DMA_InitStructure.DMA_MemoryBaseAddr = (u32) &WAVBuffer[0]; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize =512; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA2_Channel3, &DMA_InitStructure); DMA_Cmd(DMA2_Channel3, ENABLE); DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = 0; DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO; DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable; DAC_Init(DAC_Channel_1, &DAC_InitStructure); DAC_Cmd(DAC_Channel_1, ENABLE); DAC_DMACmd(DAC_Channel_1, ENABLE); TIM_Cmd(TIM6, DISABLE); } Дальше в основном цикле. if(Kn_a==1) // Kn_a находится в прерывании { Init_Sound(); load_header(); // Здесь читаются заголовки WAV и настраивается таймер sound(); Kn_a=0; } А вот с функцией sound(); наверное проблемы. void sound(void) { while(1) { TIM_Cmd(TIM6, ENABLE); while(!(DMA2->ISR & DMA_ISR_HTIF3)) {} f_read (&fsrc, &WAVBuffer[0], 256, &rb); DAC_SetChannel1Data(DAC_Align_8b_R, WAVBuffer[0]); if(rb < 256) {TIM_Cmd(TIM6, DISABLE); break;} while(!(DMA2->ISR & DMA_ISR_TCIF3)) {} f_read (&fsrc, &WAVBuffer[256], 256, &rb); DAC_SetChannel1Data(DAC_Align_8b_R, WAVBuffer[256]); if(rb < 256) {TIM_Cmd(TIM6, DISABLE); break;} } } В динамике треск и писк. В общем мозги кипят. Прошу помощи, кто знает. Нужно проиграть мелодию с карточки. Изменено 29 апреля, 2015 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 231 29 апреля, 2015 Опубликовано 29 апреля, 2015 · Жалоба Вначале научитесь хотя-бы простой тональный сигнал на ЦАП выводить без всяких WAV. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
loreal1970 0 29 апреля, 2015 Опубликовано 29 апреля, 2015 · Жалоба Совет, конечно, хороший. Я с этого начинал. Вывел на динамик синус из таблицы. Дело в другом. Карта читается - я из нее вывожу картинку на ТФТ. Сегодня записал на карту синус и попробовал вывести. И не получилось. Вот посмотрите правильно или нет? f_lseek(&fsrc, 44); // переходим на данные while(1) { f_read (&fsrc, &WAVBuffer[0], 256, &rb); // загружаем первую часть буфера if(rb < 256) { break;} while(!(DMA2->ISR & DMA_ISR_HTIF3)) {} // ждем флаг DMA2->IFCR |= DMA_ISR_HTIF3; // сбросить флаг f_read (&fsrc, &WAVBuffer[256], 256, &rb); // загружаем вторую часть буфера if(rb < 256) { break;} while(!(DMA2->ISR & DMA_ISR_TCIF3)) {} // ждем флаг DMA2->IFCR |= DMA_ISR_HTIF3; //сбросить флаг } Если что то не так, или все не так, не надо сразу лицом в грязь. Просто подскажите как правильно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 48 29 апреля, 2015 Опубликовано 29 апреля, 2015 · Жалоба Сегодня записал на карту синус и попробовал вывести. И не получилось. Я делал не так, закольцовывал дма буфер, с автоперезагрузкой, ставил флаг сработки на половине буфера и начале, дма в режиме прерывания, а в программе ждал сработки флагов, чтоб заполнить высвободившуюся часть буфера и т.д. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
loreal1970 0 29 апреля, 2015 Опубликовано 29 апреля, 2015 · Жалоба Благодарю mantech ! А можно по подробнее с настройками? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 48 29 апреля, 2015 Опубликовано 29 апреля, 2015 · Жалоба А можно по подробнее с настройками? Завтра гляну, если не забыл, где там все было Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
loreal1970 0 30 апреля, 2015 Опубликовано 30 апреля, 2015 · Жалоба В общем записал на карту синус (сформированный в программе Audacity 1кгц, 8 бит) Начинаю читать, на экране осциллографа какой то кривой прямоугольник валит. Вот настройка с выводом. Что не так? Прошу помощи. void Init_Sound(void) { /* const uint16_t sinus_12bit[180]={ 2048, 2119, 2191, 2262, 2333, 2404, 2474, 2543, 2613, 2681, 2748, 2815, 2881, 2946, 3009, 3072, 3133, 3193, 3252, 3309, 3364, 3418, 3471, 3521, 3570, 3617, 3662, 3705, 3746, 3785, 3822, 3856, 3889, 3919, 3947, 3972, 3996, 4017, 4035, 4051, 4065, 4076, 4085, 4091, 4095, 4095, 4095, 4091, 4085, 4076, 4065, 4051, 4035, 4017, 3996, 3972, 3947, 3919, 3889, 3856, 3822, 3785, 3746, 3705, 3662, 3617, 3570, 3521, 3471, 3418, 3364, 3309, 3252, 3193, 3133, 3072, 3009, 2946, 2881, 2815, 2748, 2681, 2613, 2543, 2474, 2404, 2333, 2262, 2191, 2119, 2048, 1977, 1905, 1834, 1763, 1692, 1622, 1553, 1483, 1415, 1348, 1281, 1215, 1150, 1087, 1024, 963, 903, 844, 787, 732, 678, 625, 575, 526, 479, 434, 391, 350, 311, 274, 240, 207, 177, 149, 124, 100, 79, 61, 45, 31, 20, 11, 5, 1, 0, 1, 5, 11, 20, 31, 45, 61, 79, 100, 124, 149, 177, 207, 240, 274, 311, 350, 391, 434, 479, 526, 575, 625, 678, 732, 787, 844, 903, 963, 1024, 1087, 1150, 1215, 1281, 1348, 1415, 1483, 1553, 1622, 1692, 1763, 1834, 1905, 1977 };*/ DAC_InitTypeDef DAC_InitStructure; DMA_InitTypeDef DMA_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC | RCC_APB1Periph_TIM2, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseStructure.TIM_Period = (72000000/8000)-1; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); DMA_DeInit(DMA2_Channel3); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&DAC->DHR8R1; // (uint32_t) & DAC->DHR12R1 DMA_InitStructure.DMA_MemoryBaseAddr = (u32) &WAVBuffer[0]; // sinus_12bit DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = 512; // (sizeof(sinus_12bit) / sizeof(sinus_12bit[0])) DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // DMA_PeripheralDataSize_HalfWord DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // DMA_MemoryDataSize_HalfWord DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA2_Channel3, &DMA_InitStructure); DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO; DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; // DAC_OutputBuffer_Disable; DAC_Init(DAC_Channel_1, &DAC_InitStructure); DAC_DMACmd(DAC_Channel_1, ENABLE); DAC_Cmd(DAC_Channel_1, ENABLE); DMA_Cmd(DMA2_Channel3, ENABLE); TIM_Cmd(TIM2, ENABLE); //TIM_Cmd(TIM2, DISABLE); } void sound(void) { disk_initialize(0); f_mount(0,&fs); f_open( &fsrc, "200.wav", FA_READ ); f_read (&fsrc, &WAVBuffer, 512, &rb); f_lseek(&fsrc, 44); while(1) { while(!(DMA2->ISR & DMA_ISR_HTIF3)) {} f_read (&fsrc, &WAVBuffer[0], 256, &rb); DMA2->IFCR |= DMA_ISR_HTIF3; if(rb < 256) {TIM_Cmd(TIM2, DISABLE); break;} while(!(DMA2->ISR & DMA_ISR_TCIF3)) {} f_read (&fsrc, &WAVBuffer[256], 256, &rb); DMA2->IFCR |= DMA_ISR_HTIF3; if(rb < 256) {TIM_Cmd(TIM2, DISABLE); break;} } } Сама задача static void Task_AudioOUT (void *p_arg) { (void)p_arg; OSTimeDlyHMSM(0, 0, 2, 250); Status = SD_Init(); Status = SD_GetCardInfo(&SDCardInfo); Status = SD_SelectDeselect((uint32_t) (SDCardInfo.RCA << 16)); Status = SD_EnableWideBusOperation(SDIO_BusWide_4b); Status = SD_SetDeviceMode(SD_DMA_MODE); while(1) { if(Kn_a==1) // Флаг кнопки меняется в прерывании { Init_Sound(); sound(); Kn_a=0; } OSTimeDlyHMSM(0, 0, 1, 250); } } С массива, который в функции Init_Sound(), синус на осциллографе хороший. Как начинаю с карты читать записанный синус, лезет какой то бред. Может подскажите , добрые люди, где запятая не там стоит Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 30 апреля, 2015 Опубликовано 30 апреля, 2015 · Жалоба Так в wav-файле же не просто отсчёты для синуса, там ещё какой-то заголовок наверное? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
loreal1970 0 30 апреля, 2015 Опубликовано 30 апреля, 2015 (изменено) · Жалоба Хорошо. Вот так я читаю заголовок. Изменений никаких. В посте выше я просто переместил указатель на 44 байта. static DWORD load_header (void) /* 0:Invalid format, 1:I/O error, >1:Number of samples */ { DWORD ChunkID, SamplingRate, sz, Length; char str[20]; //------------------------------------------------ f_mount(0,&fs); f_open( &fsrc, "200.wav", FA_READ ); //------------------------------------------------ GUI_SetColor(GUI_WHITE); //RED GUI_SetFont(&GUI_Font24_1); GUI_DispStringAt(">", 0, 50); if (f_read(&fsrc, Buff, 12, &rb)) return 1; /* Load file header (12 bytes) */ if (rb != 12 || LD_DWORD(Buff+8) != FCC('W','A','V','E')) return 0; GUI_DispNextLine(); GUI_DispString("WAV File found:"); while(1) { f_read(&fsrc, Buff, 8, &rb); /* Get Chunk ID and size */ if (rb != 8) return 0; ChunkID = LD_DWORD(&Buff[0]); sz = LD_DWORD(&Buff[4]); /* Chunk size */ //------------------------------ sprintf(str, "%ld", sz); GUI_DispNextLine(); GUI_DispString(str); //------------------------------ switch (ChunkID) { /* FCC */ case fmt_chunk: /* 'fmt ' chunk */ if (sz > 100 || sz < 16) return 0; /* Check chunk size */ f_read(&fsrc, Buff, sz, &rb); /* Get content */ if (rb != sz) return 0; if (Buff[0] != 1) return 0; /* Check coding type (PCM=1) */ NumChannels = Buff[2]; /* Get channel flag */ if (NumChannels != 1 && NumChannels != 2) /* Check channels (1/2) */ return 0; if(NumChannels == 1) {GUI_DispNextLine(); GUI_DispString("Mono");} else if(NumChannels == 2) {GUI_DispNextLine(); GUI_DispString("Stereo");} BitsPerSample = Buff[14]; /* Resolution flag */ if (BitsPerSample != 8 && BitsPerSample != 16) /* Check resolution (8/16) */ return 0; if(BitsPerSample == 8) {GUI_DispNextLine(); GUI_DispString("8-bits");} else if(BitsPerSample == 16) {GUI_DispNextLine(); GUI_DispString("16-bits");} SamplingRate = LD_DWORD(Buff+4); // set_sampling_rate( SamplingRate ); /* Sampling freq */ sprintf(str, "%ldHz", SamplingRate); GUI_DispNextLine(); GUI_DispString(str); break; case data_chunk: /* 'data' chunk (start to play) */ Length = sz / (SamplingRate * NumChannels * (BitsPerSample>>3) ); // length in seconds sprintf(str, "%ld:%2ld min", (Length/60), (Length%60)); GUI_DispNextLine(); GUI_DispString(str); return sz; case LIST_chunk: /* 'LIST' chunk (skip) */ case fact_chunk: /* 'fact' chunk (skip) */ f_lseek(&fsrc, (fsrc.fptr + sz)); break; default : /* Unknown chunk (error) */ return 0; } } //return 0; } и дальше void sound(void) { f_read (&fsrc, &WAVBuffer[0], 512, &rb); while(1) { while(!(DMA2->ISR & DMA_ISR_HTIF3)) {} f_read (&fsrc, &WAVBuffer[0], 256, &rb); DMA2->IFCR |= DMA_ISR_HTIF3; if(rb < 256) {TIM_Cmd(TIM2, DISABLE); break;} while(!(DMA2->ISR & DMA_ISR_TCIF3)) {} f_read (&fsrc, &WAVBuffer[256], 256, &rb); DMA2->IFCR |= DMA_ISR_HTIF3; if(rb < 256) {TIM_Cmd(TIM2, DISABLE); break;} } } Исправил while(1) { while(!(DMA2->ISR & DMA_ISR_HTIF3)) {} f_read (&fsrc, &WAVBuffer[0], 256, &rb); DMA2->IFCR |= DMA_ISR_HTIF3; if(rb < 256) {TIM_Cmd(TIM2, DISABLE); break;} while(!(DMA2->ISR & DMA_ISR_TCIF3)) {} f_read (&fsrc, &WAVBuffer[256], 256, &rb); DMA2->IFCR |= DMA_ISR_TCIF3; // if(rb < 256) {TIM_Cmd(TIM2, DISABLE); break;} } Все равно на экране беспорядочные значения Изменено 30 апреля, 2015 пользователем loreal1970 [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 30 апреля, 2015 Опубликовано 30 апреля, 2015 · Жалоба Хорошо. Вот так я читаю заголовок. Изменений никаких. В посте выше я просто переместил указатель на 44 байта. Ок. Значит, вы уверены, что у вас считываются именно отсчёты синуса? Тогда следующее замечание: зачем вы изменили размер периферии? (DMA_PeripheralDataSize_HalfWord на DMA_PeripheralDataSize_Byte) Ведь размер регистра ЦАП не изменяется. А, понял. Регистр поменялся тоже. Ну тогда не знаю... Попробуйте записать в файл прямо тот же синус, который работает, многократно. И считайте его. Чтобы исключить ошибки обработки wav. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
loreal1970 0 30 апреля, 2015 Опубликовано 30 апреля, 2015 · Жалоба Так секундочку. Я чего то не понимаю. В заголовке у меня получается Сигнал моно, 16-бит, 8000Гц, размер и время. Ребят! Может поделитесь рабочим примером чтения WAV с карты. Что то совсем не получается. В общем заголовок на экран вывожу. А сами данные не получается вывести. Плиз. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 30 апреля, 2015 Опубликовано 30 апреля, 2015 · Жалоба Так секундочку. Я чего то не понимаю. В заголовке у меня получается Сигнал моно, 16-бит, 8000Гц, размер и время. Ребят! Может поделитесь рабочим примером чтения WAV с карты. Что то совсем не получается. В общем заголовок на экран вывожу. А сами данные не получается вывести. Плиз. Добавляйте к считанному с wav +0x8000 и сдвигайте на 4, чтоб получить 12 бит. И непонятно как вы "разруливаете" ситуацию с тем, что данные в wav 16-битные? В функциях чтения у вас 256 это байт? А в DAC вы пишете байтами. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
controller_m30 1 2 мая, 2015 Опубликовано 2 мая, 2015 (изменено) · Жалоба Пусть функция загрузки данных в DAC - укладывает выходные данные и в память тоже. Много не надо, первых 20-30 байт (или слов?) достаточно. Затем сравните первые 20-30 семплов из WAV файла, с тем что отправилось в DAC. Вот например кусочек на 18 семплов из Audacity в формате "WAV signed 16 bit PCM", и те-же данные как их видно в WINHEXе. На второй картинке график в Excel построенный по тем-же 16 битным значениям (с прибавлением + 0x8000, как предлагает adnega). Проверьте у себя, как работает функция преобразования данных для DAC. Или выложите здесь для сравнения, что читаете из WAV файла и что пишете в DAC. Изменено 2 мая, 2015 пользователем controller_m30 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MiklPolikov 0 2 мая, 2015 Опубликовано 2 мая, 2015 · Жалоба Заголовок незачем читать, ели точно известно, в каком формате записан файл. Но работая с 16и битным файлом, Вы не знаете, правильно ли задали смещение при чтении: быть может в выборку ЦАП у Вас попадает 1й байт из одного 16и битного значения и 2ой байт из следующго 16и битного значения, и поэтому на выходе ЦАП непонятная белиберда. Что бы исключить эту ошибку, запишите файл в 8и битном формате. И читайте его побайтно, побайтно отправляйте в ЦАП. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
loreal1970 0 2 мая, 2015 Опубликовано 2 мая, 2015 · Жалоба Да ребята. Вы правы. WAV у меня 16 битный. А преобразование неправильное. Я так понимаю? 1. Заводим буфер на (к примеру 1024 байт) 2. Настраиваем таймер на частоту выборки семплов. 3. В прерывании таймера читаем половину буфера (по счетчику), сдвигаем каждое uint16_t слово на >>4 (приводим к 12 битам) 4. Выкладываем в DAC (настроенный на 12 битный режим) 5. Далее вторая половинка буфера. Такой вариант (с некоторыми изменениями приемлем), но в DMA есть хороший режим, т.е. прерывание на половине и конце буфера. Осталось теперь соединить это в кучу. Вроди бы просто. Но что то перемкнуло и не могу сдвинуться с места. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться