zheka 1 15 апреля, 2015 Опубликовано 15 апреля, 2015 (изменено) · Жалоба А то сейчас можно подумать, что DataOut[] локальная переменная, для которой просто не хватает стека. Ах тыж ёшкин кот... точно!!! Она у меня и правда локальная. Сделал глобальной, выставил 640 байт - все пашет. Спасибо! P.S. Ушел к знакомому шаману за специальным бубном, который потребуется чтобы прикрутить DCMI..... Изменено 15 апреля, 2015 пользователем zheka Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 18 апреля, 2015 Опубликовано 18 апреля, 2015 (изменено) · Жалоба Продолжаю пляски с бубном Прикрутил камеру. НА текущий момент читатся и пишутся регистры, камера, судя по осциллограммам работает. О том, что нормально работает камера и са DCMI свидетельствует то, что помещенный в окно отладчика Watch регистр DCMI->DR мпостоянно изеняется, приченм, если камеру закрыть, там нули, а если посветить - то чем ярче, тем больше выпозают числа. А вот с DMA какие-то проблемы - выделенный по дкадр буфер все время пуст. ДЛя проверки даже предварително заполнял его заданным значениями - они отображаются, но не меняются. Вот инициализация: static void Camera_HW_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; DCMI_InitTypeDef DCMI_InitStructure; DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; __IO uint32_t Timeout = TIMEOUT_MAX; RCC_AHB1PeriphClockCmd(SCCB_Clock, ENABLE); // Configure SIO_C and SIO_D as OUT (for SCCB/I2C) GPIO_InitStructure.GPIO_Pin = SIO_C_Pin | SIO_D_Pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // PullUp is include on module GPIO_Init(SCCB_Port, &GPIO_InitStructure); // Configure MCO0(PA8) as clock out for Camera Module (XCLK pin) OV7670_XCLK_Conf(); // Configures the DCMI GPIOs to interface with the OV7670 camera module // Enable DCMI GPIOs clocks RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOE, ENABLE); // Connect DCMI pins to AF13 // PORTA GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_DCMI); // HSYNC GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_DCMI); // PCLK GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_DCMI); // D0 GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_DCMI); // D1 // PORTB GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_DCMI); // D5 GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_DCMI); // VSYNC GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_DCMI); // D6 GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_DCMI); // D7 - // PORTC GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_DCMI); // D4 // PORTE GPIO_PinAFConfig(GPIOE, GPIO_PinSource0, GPIO_AF_DCMI); // D2 GPIO_PinAFConfig(GPIOE, GPIO_PinSource1, GPIO_AF_DCMI); // D3 // DCMI GPIO configuration // D0..D1(PA9/10), HSYNC(PA4), PCLK(PA6) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_6 | GPIO_Pin_9 | GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOA, &GPIO_InitStructure); // D5..D7(PB6/8/9), VSYNC(PB7) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOB, &GPIO_InitStructure); // D4(PC11) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOC, &GPIO_InitStructure); // D2..D3(PE0/1) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOE, &GPIO_InitStructure); //--------------------------------------------------------------------------------------- // GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_DCMI); //d0 // GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_DCMI); //d1 // GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_DCMI); //d2 //--------------------------------------------------------------------------------------- // Configures the DCMI to interface with the OV7670 camera module // Enable DCMI clock RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI, ENABLE); // Reinitialize DCMI_DeInit(); // DCMI configuration DCMI_InitStructure.DCMI_CaptureMode = DCMI_CaptureMode_Continuous; DCMI_InitStructure.DCMI_SynchroMode = DCMI_SynchroMode_Hardware; DCMI_InitStructure.DCMI_PCKPolarity = DCMI_PCKPolarity_Rising; DCMI_InitStructure.DCMI_VSPolarity = DCMI_VSPolarity_High; DCMI_InitStructure.DCMI_HSPolarity = DCMI_HSPolarity_Low; DCMI_InitStructure.DCMI_CaptureRate = DCMI_CaptureRate_All_Frame; DCMI_InitStructure.DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b; DCMI_Init(&DCMI_InitStructure); // Configures the DMA2 to transfer Data from DCMI // Enable DMA2 clock RCC_AHB1PeriphClockCmd(DMA_Camera_STREAM_CLOCK, ENABLE); // DMA2 Stream1 Configuration DMA_DeInit(DMA_CameraToRAM_Stream); // Check if the DMA Stream is disabled before enabling it. // Note that this step is useful when the same Stream is used multiple times: // enabled, then disabled then re-enabled... In this case, the DMA Stream disable // will be effective only at the end of the ongoing data transfer and it will // not be possible to re-configure it before making sure that the Enable bit // has been cleared by hardware. If the Stream is used only once, this step might // be bypassed. while (DMA_GetCmdStatus(DMA_CameraToRAM_Stream) != DISABLE) { } DMA_InitStructure.DMA_Channel = DMA_Camera_Channel; DMA_InitStructure.DMA_PeripheralBaseAddr = DCMI_DR_ADDRESS; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&RAM_Buffer; //DMA_InitStructure.DMA_Memory0BaseAddr = 0x60020000; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = BuffSize; // DMA_InitStructure.DMA_BufferSize = 1; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA_CameraToRAM_Stream, &DMA_InitStructure); // Enable DMA Stream Transfer Complete interrupt DMA_ITConfig(DMA_CameraToRAM_Stream, DMA_IT_TC , ENABLE); // Check if the DMA Stream has been effectively enabled. // The DMA Stream Enable bit is cleared immediately by hardware if there is an // error in the configuration parameters and the transfer is no started (ie. when // wrong FIFO threshold is configured ...) Timeout = TIMEOUT_MAX; while ((DMA_GetCmdStatus(DMA_CameraToRAM_Stream) != ENABLE) && (Timeout-- > 0)) { } // Check if a timeout condition occurred if (Timeout == 0) { // Manage the error: to simplify the code enter an infinite loop while (1) { // Dopísa program } } // // Enable the DMA Stream IRQ Channel NVIC_InitStructure.NVIC_IRQChannel = DMA_Camera_STREAM_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } Буфер объявлен так __IO uint16_t RAM_Buffer[BuffSize]; Ну и вот что у меня в прерываниях void DMA_Camera_STREAM_IRQHANDLER(void) { uint16_t i; // Test on DMA Stream Transfer Complete interrupt if(DMA_GetITStatus(DMA_CameraToRAM_Stream, DMA_Camera_IT_TCIF)) { // LCD_REG = 0x0022; //for(i = 0; i < BuffSize; i++) // LCD_RAM = RAM_Buffer[i]; // Clear DMA Stream Transfer Complete interrupt pending bit DMA_ClearITPendingBit(DMA_CameraToRAM_Stream, DMA_Camera_IT_TCIF); } } void DCMI_IRQHandler(void) { uint16_t i; if(DCMI_GetITStatus(DCMI_IT_FRAME)) { // LCD_REG = 0x0022; //for(i = 0; i < BuffSize; i++) // LCD_RAM = RAM_Buffer[i]; //for(i = 0; i < 28800; i++) // LCD_RAM = 0x0000; DCMI_ClearITPendingBit(DCMI_IT_FRAME); } } Оба прерывания вызываются, все ОК, Но буфер пуст... У меня вопрос - а нужен ли мне собственно DMA? МОжно ли как-то без него заполнять буфер длиной 640 байт а по прерыванию новой строки отправлять этот буфер по USB? ДОБАВЛЮ: Если это // DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; заменить на это DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; ну то есть включить DMA_MemoryInc, то в буфере оказываются данные, но в дальнейшем не изменяются. И прерывание DMA_Stream не вызывается... Изменено 18 апреля, 2015 пользователем zheka Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 19 апреля, 2015 Опубликовано 19 апреля, 2015 · Жалоба Таак... У меня каша в голове пока что.... Вот смотрите, мне нужно следующее - чтобы DMA заполнял данными из DCMI буфер длиной в одну строку (1280 байт при RGB565), чтобы первый байт строки был первым байтом буфера. Далее - по окончанию передачи строки (не знаю, как лучше ее ловить, по прерываниям из DCMI или в DMA есть какое прерывание, означающее что вся строка передана, в этот момент я собираюсь забирать из буфера данные и отправлять их по USB (это уже настроено). Вот мои последние настройки DMA и DCMI DCMI_InitStructure.DCMI_CaptureMode = DCMI_CaptureMode_Continuous; DCMI_InitStructure.DCMI_SynchroMode = DCMI_SynchroMode_Hardware; DCMI_InitStructure.DCMI_PCKPolarity = DCMI_PCKPolarity_Rising; DCMI_InitStructure.DCMI_VSPolarity = DCMI_VSPolarity_High; DCMI_InitStructure.DCMI_HSPolarity = DCMI_HSPolarity_Low; DCMI_InitStructure.DCMI_CaptureRate = DCMI_CaptureRate_All_Frame; DCMI_InitStructure.DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b; DCMI_Init(&DCMI_InitStructure); // Configures the DMA2 to transfer Data from DCMI // Enable DMA2 clock RCC_AHB1PeriphClockCmd(DMA_Camera_STREAM_CLOCK, ENABLE); // DMA2 Stream1 Configuration DMA_DeInit(DMA_CameraToRAM_Stream); // Check if the DMA Stream is disabled before enabling it. // Note that this step is useful when the same Stream is used multiple times: // enabled, then disabled then re-enabled... In this case, the DMA Stream disable // will be effective only at the end of the ongoing data transfer and it will // not be possible to re-configure it before making sure that the Enable bit // has been cleared by hardware. If the Stream is used only once, this step might // be bypassed. while (DMA_GetCmdStatus(DMA_CameraToRAM_Stream) != DISABLE) { } DMA_InitStructure.DMA_Channel = DMA_Camera_Channel; DMA_InitStructure.DMA_PeripheralBaseAddr = DCMI_DR_ADDRESS; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&RAM_Buffer; //DMA_InitStructure.DMA_Memory0BaseAddr = 0x60020000; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = BuffSize; // DMA_InitStructure.DMA_BufferSize = 1; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA_CameraToRAM_Stream, &DMA_InitStructure); // Enable DMA Stream Transfer Complete interrupt DMA_ITConfig(DMA_CameraToRAM_Stream, DMA_IT_TC , ENABLE); // Check if the DMA Stream has been effectively enabled. // The DMA Stream Enable bit is cleared immediately by hardware if there is an // error in the configuration parameters and the transfer is no started (ie. when // wrong FIFO threshold is configured ...) Timeout = TIMEOUT_MAX; while ((DMA_GetCmdStatus(DMA_CameraToRAM_Stream) != ENABLE) && (Timeout-- > 0)) { } // Check if a timeout condition occurred if (Timeout == 0) { // Manage the error: to simplify the code enter an infinite loop while (1) { // Dopísa program } } // // Enable the DMA Stream IRQ Channel NVIC_InitStructure.NVIC_IRQChannel = DMA_Camera_STREAM_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); Что нужно поменять? Особенно волнует, как настраивать вот эти строки DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; И почему в источнике слово, а в конечной точке - полслова? DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 19 апреля, 2015 Опубликовано 19 апреля, 2015 · Жалоба В ДМА настраиваю ширину входного и выходного канала оно может 32 битные числа по 8 бит в UART перекладывать или собирать 16 битный SPI d 32 битные int. Также в ДМА настраивают писать в один адрес или автоматически сдвигать. Если вы кладете данные в UART, например, то адрес приемника один, и ДМА делают без автоинкремента. А если вы кладете данные в память, то надо чтобы каждые новые данные клались в новый адрес, и тогда нужен автоинкремент. Теперь смотрите ширину входных - выходных ваших данных и постоянство адресов и настраивайте ДМА. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 20 апреля, 2015 Опубликовано 20 апреля, 2015 · Жалоба Вы мне объясните еще две вещи - как в DCMI настроить частоту PIX_CLK и почему D0-D7 настраиваются как выходы? Ведь в камеру если что и пишется, то по i2c, но никак не по шине данных.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 22 апреля, 2015 Опубликовано 22 апреля, 2015 · Жалоба Вот черт же, где правда? Стр.41 даташита https://www.fer.unizg.hr/_download/repository/OV7670new.pdf Vertical Frame (Row) Start VSTRT [7:0], VREF[2:0] То есть старшие 8 бит - в регистре VSTRT, младшие 3 бита - в регистре VREF Дальше лезем в описание регистра VREF: bit [3:2] - VREF end low 2 bits Где правда? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 22 апреля, 2015 Опубликовано 22 апреля, 2015 (изменено) · Жалоба Оказывается есть аппаратная функция захвата ОБЛАСТИ в контроллере DCMI typedef struct { uint16_t DCMI_VerticalStartLine; /*!< Specifies the Vertical start line count from which the image capture will start. This parameter can be a value between 0x00 and 0x1FFF */ uint16_t DCMI_HorizontalOffsetCount; /*!< Specifies the number of pixel clocks to count before starting a capture. This parameter can be a value between 0x00 and 0x3FFF */ uint16_t DCMI_VerticalLineCount; /*!< Specifies the number of lines to be captured from the starting point. This parameter can be a value between 0x00 and 0x3FFF */ uint16_t DCMI_CaptureCount; /*!< Specifies the number of pixel clocks to be captured from the starting point on the same line. This parameter can be a value between 0x00 and 0x3FFF */ } DCMI_CROPInitTypeDef; и позволяет вводить "человеческие" значения. Таким образом, у меня один вопрос к специалистам - те значения, что в камере по умолчанию - они все-таки какие координаты окна и разрешение дают? Надеюсь 0,0,640,480? Изменено 22 апреля, 2015 пользователем zheka Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 22 апреля, 2015 Опубликовано 22 апреля, 2015 · Жалоба Какой-то шайтан... Как не настраиваю, DCMI все равно выдает 480 строк: DCMI_DeInit(); // DCMI configuration DCMI_InitStructure.DCMI_CaptureMode = DCMI_CaptureMode_Continuous; DCMI_InitStructure.DCMI_SynchroMode = DCMI_SynchroMode_Hardware; DCMI_InitStructure.DCMI_PCKPolarity = DCMI_PCKPolarity_Rising; DCMI_InitStructure.DCMI_VSPolarity = DCMI_VSPolarity_High; DCMI_InitStructure.DCMI_HSPolarity = DCMI_HSPolarity_Low; DCMI_InitStructure.DCMI_CaptureRate = DCMI_CaptureRate_All_Frame; DCMI_InitStructure.DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b; DCMI_Init(&DCMI_InitStructure); DCMI_CROPInitStructure.DCMI_HorizontalOffsetCount=0; DCMI_CROPInitStructure.DCMI_CaptureCount=320*2; DCMI_CROPInitStructure.DCMI_VerticalStartLine=0; DCMI_CROPInitStructure.DCMI_VerticalLineCount=240; DCMI_CROPConfig(&DCMI_CROPInitStructure); DCMI_CROPCmd(ENABLE); DCMI_ITConfig(DCMI_IT_VSYNC, ENABLE); DCMI_ITConfig(DCMI_IT_LINE, ENABLE); DCMI_ITConfig(DCMI_IT_FRAME, ENABLE); DCMI_ITConfig(DCMI_IT_OVF, ENABLE); DCMI_ITConfig(DCMI_IT_ERR, ENABLE); А вот обработчик прерываний void DCMI_IRQHandler(void) { uint16_t i; if(DCMI_GetITStatus(DCMI_IT_FRAME)) { DCMI_ClearITPendingBit(DCMI_IT_FRAME); lines=current_line; current_line=0; } if(DCMI_GetITStatus(DCMI_IT_VSYNC)) { DCMI_ClearITPendingBit(DCMI_IT_VSYNC); } if(DCMI_GetITStatus(DCMI_IT_ERR)) { DCMI_ClearITPendingBit(DCMI_IT_ERR); } if(DCMI_GetITStatus(DCMI_IT_LINE)) { current_line++; DCMI_ClearITPendingBit(DCMI_IT_LINE); } } В дебаггере у меня lines. Как только ловится кадр, в Lines помещается значение насчитанных строк. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 26 апреля, 2015 Опубликовано 26 апреля, 2015 (изменено) · Жалоба Камера поддается, но не сдается. Куски картинки в искаженном цвете я уже вижу. Но как-то неправильно DCMI и DMA у меня кооперируются. Интерфейс DCMI имеет регистр DCMI->DR, содержащий 32 бита, то есть в режиме RGB565 в него кладется 4 байта - информация о 2-х пикселях. Я настроил камеры на выдачу фрагмента размерами 200х200 пикселей, то есть размер буфера у меня 80 000 байт, длина строки 400 байт. Я заполняю буфер через DMA, а потом пакетами по 400 байт пересылаю картинку на компьютер. В итоге картинка получается странная - складывается ощущение, что строка все же имеет длину 200 байт и запись в картинку получается следующего формата 1 строка 2 строка 3 строка 4 строка 5 строка 6 строка Плюс почему-то нижняя часть картинки оказывается вверху и наоборот. А верхняя половина буфера пуста. Собственно с передаче картинки на комп и ее расшифровкой проблем нет - заполнял буфер искусственно, получал правильную картинку. ПРоблемы с записью в DMA. Вот код extern __IO uint8_t RAM_Buffer[80000]; uint8_t *pRAM_Buffer; .................................................. DCMI_InitStructure.DCMI_CaptureMode = DCMI_CaptureMode_Continuous; DCMI_InitStructure.DCMI_SynchroMode = DCMI_SynchroMode_Hardware; DCMI_InitStructure.DCMI_PCKPolarity = DCMI_PCKPolarity_Rising; DCMI_InitStructure.DCMI_VSPolarity = DCMI_VSPolarity_High; DCMI_InitStructure.DCMI_HSPolarity = DCMI_HSPolarity_Low; DCMI_InitStructure.DCMI_CaptureRate = DCMI_CaptureRate_All_Frame; DCMI_InitStructure.DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b; DCMI_Init(&DCMI_InitStructure); DCMI_ITConfig(DCMI_IT_VSYNC, ENABLE); DCMI_ITConfig(DCMI_IT_LINE, ENABLE); DCMI_ITConfig(DCMI_IT_FRAME, ENABLE); DCMI_ITConfig(DCMI_IT_ERR, ENABLE); // Enable DCMI Capture mode // Configures the DMA2 to transfer Data from DCMI // Enable DMA2 clock RCC_AHB1PeriphClockCmd(DMA_Camera_STREAM_CLOCK, ENABLE); // DMA2 Stream1 Configuration DMA_DeInit(DMA_CameraToRAM_Stream); while (DMA_GetCmdStatus(DMA_CameraToRAM_Stream) != DISABLE) { } DMA_InitStructure.DMA_Channel = DMA_Camera_Channel; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&DCMI->DR); DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&RAM_Buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = BuffSize; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA_CameraToRAM_Stream, &DMA_InitStructure); // Enable DMA Stream Transfer Complete interrupt DMA_ITConfig(DMA_CameraToRAM_Stream, DMA_IT_TC, ENABLE); .......................... // Передача двухсот строк pRAM_Buffer=RAM_Buffer; for (j=0;j<200;j++) { USBD_CDC_ACM_WriteData(0,pRAM_Buffer+400*j,400); delay_us(1000); } Картинку прикладываю. Камера лежит на столе и в ее объектив попадает мое ухо)) Вот картинка Изменено 26 апреля, 2015 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 27 апреля, 2015 Опубликовано 27 апреля, 2015 · Жалоба А как мы можем быть уверены что у вас не такое ухо:)? есть подозрение что вы один и тот же кусок по кругу передаете... число точек в строке правильное? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 27 апреля, 2015 Опубликовано 27 апреля, 2015 · Жалоба Как выяснилось, у меня размер буфера в DMA был равен размеру массива данных в абсолютных цифрах. Вот только массив у меня 8-битный, а в DMA надо было пересчитывать на 32 бита, то есть делить на 4. Хреновая цветность - не настроена гамма, плюс по какой-то причине мой софт декодирует полученные данные как RGB555, хотя явно указано - 16 битный формат. Временно настроил камеру на RGB555 - вроде бы все ОК. Навел камеру на телек, что за спиной. Смотрю в окне своей программы "Лунтика" и наслаждаюсь. Как оказывается для счастья мало надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 27 апреля, 2015 Опубликовано 27 апреля, 2015 · Жалоба не настроена гамма Я долго страдал от зеленых лиц... sccb_wr_reg(REG_COM7, 0x80); /* reset to default values */ //sccb_wr_reg(REG_CLKRC, 0x80); sccb_wr_reg(REG_COM11, 0x0A); sccb_wr_reg(REG_COM7, 0x04); /* output format: rgb */ sccb_wr_reg(REG_RGB444, 0x00); /* disable RGB444 */ sccb_wr_reg(REG_COM15, 0xD0); /* set RGB565 */ //sccb_wr_reg(0x0C, 0x00); // COLOR SETTING sccb_wr_reg(0x4f, 0x80); sccb_wr_reg(0x50, 0x80); sccb_wr_reg(0x51, 0x00); sccb_wr_reg(0x52, 0x22); sccb_wr_reg(0x53, 0x5e); sccb_wr_reg(0x54, 0x80); sccb_wr_reg(0x56, 0x40); sccb_wr_reg(0x58, 0x9e); sccb_wr_reg(0x59, 0x88); sccb_wr_reg(0x5a, 0x88); sccb_wr_reg(0x5b, 0x44); sccb_wr_reg(0x5c, 0x67); sccb_wr_reg(0x5d, 0x49); sccb_wr_reg(0x5e, 0x0e); sccb_wr_reg(0x69, 0x00); sccb_wr_reg(0x6a, 0x40); sccb_wr_reg(0x6b, 0x0a); sccb_wr_reg(0x6c, 0x0a); sccb_wr_reg(0x6d, 0x55); sccb_wr_reg(0x6e, 0x11); sccb_wr_reg(0x6f, 0x9f); sccb_wr_reg(0xb0, 0x84); sccb_wr_reg(0x11, 0x81); Надеюсь этот код добавит вам счастья. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 27 апреля, 2015 Опубликовано 27 апреля, 2015 · Жалоба adnega, а в комп чем передаете? Какова скорость? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 27 апреля, 2015 Опубликовано 27 апреля, 2015 · Жалоба adnega, а в комп чем передаете? Какова скорость? Я на экране, подключенном к МК, отображаю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться