Interfejs DCMI w STM32: jak dołączyć kamerę CCD do mikrokontrolerów STM32F2 i STM32F4
Główna pętla programu
W funkcji main(), po skonfigurowaniu wszystkich peryferii oraz wyświetlacza i kamery, wykonywana jest pętla while(), w której okresowo sprawdzane jest czy został dotknięty panel dotykowy i jeżeli tak to następuje przełączenie aktualnego ekran (wyświetlanej zawartości). Dostępnych jest 3 ekrany: informacyjny (wszelkie wiadomości tekstowe), podglądu obrazu z kamery oraz wykonanie zdjęcia (które może być zapisane na kartę SD – wymaganym jest dodanie odpowiedniego kodu obsługi).
int main(void){ __IO uint32_t i = 0; /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32fxxx_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32fxxx.c file */ /* Konfiguracja modulu USB */ USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_CDC_cb, &USR_cb); RCC_Config(); /* Wlaczenie sygnalow taktujacych peryferia oraz konfiguracja SysTick */ NVIC_Config(); /* Konfiguracja kontrolera NVIC */ GPIO_Config(); /* Konfiguracja wyprowadzen */ EXTI_Config(); /* Konfiguracja zewnetrznych zrodel przerwania */ DCMI_Config(); /* Konfiguracja modulu DCMI */ I2C_Config(); /* Konfiguracja kontrolera I2C1 */ LCD_Init(); // Inicjalizacja wyswietlacza LCD_Clear(BG_Color); // Czyszczenie ekranu LCD_SetBackColor(BG_Color); // Ustawienie koloru tla LCD_SetTextColor(White); // Ustawienie koloru tekstu LCD_SetFont(&Font8x8); // Ustawienie czcionki 8x8 pikseli Delay(10); // Wait 100ms MT9D111_WriteReg(PAGE_SELECT_REG, 0x0); // Select Page 0 - Sensor Core if(MT9D111_ReadReg(0x00) == 0x1519){ // Camera MT9D111 detected sprintf(camera_state_info, " MT9D111 not connected. "); } else{ // Camera MT9D111 not detected sprintf(camera_state_info, " MT9D111 connected. "); } // Wymagana sekwencja umozliwiajaca swobodne operowanie bezpośrednio // na rejestrach czujnika kamery MT9D111_WriteReg(PAGE_SELECT_REG,0x1); // Select Page 1 - IFP regVal = MT9D111_ReadReg(UC_BOOT_MODE_REG); MT9D111_WriteReg(UC_BOOT_MODE_REG, (regVal | 0x01)); // Reset microcontroller Delay(10); // Wait 100 ms MT9D111_Init(); // Inicjalizacja kamery current_screen = 0; update_screen_x = 1; while(1){ // Tutaj mozna umiescic dodatkowe funkcje wymagajace okresowego wykonania // niezaleznie od tego ktory ekran jest wyswietlany aktualnie i czy TP jest wcisniety // Sprawdz czy wcisnieto TP if( Is_TP_Pressed() == TP_PRESSED){ TP_status = 0; // Czysczenie flagi // Czekaj na odpuszczenie TP while( Is_TP_Released() != TP_RELEASED ); TP_status = 0; // Czysczenie flagi ++current_screen; // Wybor nastepnego ekranu if( current_screen > 2 ){ current_screen = 0; } } switch(current_screen){ // Ekran informacyjny case 0:{ if(update_screen_x & 0x1){ update_screen_x <<= 1; current_line = 1; // Czyszczenie ekranu LCD_Clear(BG_Color); LCD_SetTextColor(White); LCD_DisplayStringLine(LINE(current_line++), (uint8_t *) camera_state_info); LCD_SetTextColor(Green); LCD_DisplayStringLine(LINE(current_line++), " Touch to continue..."); } break; } // Podglad case 1:{ if(update_screen_x & 0x2){ update_screen_x <<= 1; // Ustawienie pozycji i wymiarow obszaru wyswietlacza dla obrazu z kamery LCD_SetDisplayWindow(239, 319, 240, 320); LCD_SetCursor(0,319); LCD_WriteRAM_Prepare(); // Prepare to write GRAM MT9D111_WriteReg(PAGE_SELECT_REG, 0x0); // Select Page 0 - Sensor Core MT9D111_WriteReg(SHUTTER_WIDTH_REG, 700); // Ustawienie wartosci przeslony DCMI_Cmd(DISABLE); // Wylacz DCMI DCMI->CR &= 0xFFFD; // Wybierz tryb podgladu DCMI_Cmd(ENABLE); // Wlacz DCMI DCMI_CaptureCmd(ENABLE); // Wlacz przyjmowanie danych obrazu } break; } // Wykonanie zdjecia case 2:{ if(update_screen_x & 0x4){ //update_screen_x <<= 1; update_screen_x = 1; DCMI_CaptureCmd(DISABLE); // Wylacz przyjmowanie danych obrazu DCMI_Cmd(DISABLE); // Wylacz DCMI // Ustawienie pozycji i wymiarow obszaru wyswietlacza dla obrazu z kamery LCD_SetDisplayWindow(239, 319, 240, 320); LCD_SetCursor(0,319); LCD_WriteRAM_Prepare(); // Prepare to write GRAM MT9D111_WriteReg(PAGE_SELECT_REG, 0x0); // Select Page 0 - Sensor Core MT9D111_WriteReg(SHUTTER_WIDTH_REG, 2000);// Ustawienie wartosci przeslony Delay(10); // Czekaj 100ms DCMI->CR |= DCMI_CaptureMode_SnapShot; // Wybierz tryb wykonania zdjecia DCMI_Cmd(ENABLE); // Wlacz DCMI DCMI_CaptureCmd(ENABLE); // Wlacz przyjmowanie danych obrazu while(DCMI->CR & 0x1); // Czekaj na zakonczenie odbioru // Tutaj mozna wykonac odczyt obrazu z pamieci RAM wyświetlacza // i zapisanie go na karte SD } break; } default:{break;} } Delay(10); // Czekaj 100ms } }
Aplikacja PC
Podczas realizacji projektu była tworzona prosta aplikacja (rysunek 10) w środowisku QtCreator, umożliwiająca łatwą i szybką konfigurację parametrów kamery. Pozwoliła ona na łatwiejsze zrozumienie zależności działania kamery od wartości zapisywanych do rejestrów i zmiennych sterowników funkcji.
Rys. 10. Prosta aplikacja konfigurująca kamerę
System operacyjny może nie rozpoznać właściwie podłączonego układu do portu USB komputera i wtedy należy ze strony pobrać plik o nazwie libusb-win32-bin-1.2.6.0 i z katalogu bin uruchomić program inf-wizard pozwalający dodać potrzebny sterownik (na liście powinien być element o nazwie STMicroelectronics Virtual COM Port).
Jan Szemiet