STM32F4Discovery: conecte la cámara a través de la interfaz DCMI. Portal de información de seguridad STM32F4Discovery: conecte la cámara a través de la interfaz DCMI

  • Tutorial

STM32F4Discovery: conecte la cámara a través de la interfaz DCMI

Érase una vez la conexión de una cámara de un teléfono móvil a un microcontrolador STM32F407VGT6(que tiene lugar en el tablero STM32F4Descubrimiento), Ni siquiera pensé en el hecho de que este controlador tiene una interfaz de hardware especial para este asunto. Tal vez no leí la hoja de datos con atención, pero siempre pensé que la interfaz DCMI disponible solo para chips en paquetes UFBGA176 Y LQFP desde 144 pies. Sin embargo, no hace mucho descubrí el detalle sonoro: 100 patas STM32F407 También tiene DCMI a bordo.
Siendo un gran admirador de estudiar y lanzar conjuntamente varios hardware móviles (en particular, pantallas LCD y cámaras) con MK, simplemente no pude pasar por alto tal descubrimiento y decidí llenar este vacío en el estudio de los periféricos STM32. En realidad, este material está dedicado a describir la implementación de la idea que ha surgido.

Sólo un poco de teoría.

En primer lugar, hay que imaginarse de qué estamos hablando, o mejor dicho, qué es una cámara CMOS y para qué se utiliza.
Este tipo de cámara genera información del sensor en formato digital: RGB, YCbCr y también en formato comprimido: JPEG. Las diferentes cámaras tienen sus propios matices en cuanto a capacidades, consideraré un caso muy específico de una cámara de baja resolución (VGA, 640x480), que saqué de mi teléfono en la antigüedad " Siemens C72"(sensor PixelPlus PO2030N). Esta cámara es la más adecuada para el estudio por su facilidad de manejo y por pertenecer a un tipo más o menos común. Hace mucho tiempo le hice una pequeña placa (para mayor facilidad de conexión), con un estabilizador de 2,8 V y resistencias pull-up en el bus. I2C. Aquí está (el cable de la cámara y el conector están ocultos debajo de la carcasa).

Además de los matices en el campo del formato de datos, las cámaras también pueden diferir en el número de pines de sincronización. La mayoría (en mi opinión) de los sensores tienen pines especiales de sincronización horizontal y vertical; pero hay cámaras que solo tienen una salida de luz estroboscópica de píxeles y le informan sobre el comienzo de una nueva línea/cuadro mediante códigos de transmisión especiales (por ejemplo, 0x00 o 0xFF). La cámara que tengo tiene pines de sincronización externos.
Se puede estimar una representación esquemática aproximada de la cámara en forma de bloque.

En su mayor parte, las cámaras CMOS se controlan a través de una interfaz I2C(aunque he visto dispositivos controlados por UART). A través de I2C se configuran diversos parámetros, como: resolución, gama de colores, formato de datos de salida, etc.
Conclusión EXTCLK– sincronización de cámara, que debe proporcionarse externamente. DCLK– una señal estroboscópica, a lo largo de cuyo borde ascendente o descendente se registran datos en el bus de datos de la cámara (por ejemplo, un byte de datos de un píxel de la matriz, o un byte de datos de “medio píxel” si la cámara funciona en el modo RGB565). HSYNC– señal de sincronización horizontal que indica el comienzo de una nueva línea, y VSYNC– una señal de sincronización cuyo nivel activo indica el comienzo de una nueva trama. Conclusiones D0..D7– bus de datos; Como regla general, para este tipo de cámaras es de ocho bits.
Ahora hablemos más sobre las señales de sincronización.

Los gráficos muestran que la cámara está configurada para la actividad de la señal. DCLK sólo durante la fase activa HSYNC(es decir, es esta fase la que nos interesa; la señal del reloj durante el período de "avance de línea" no nos interesa). Si la cámara está configurada con una resolución de 320x240, durante cada pulso HSYNC 320 pulsos encajan DCLK, y durante el periodo VSYNC – 240 HSYNC.
Cuando hacemos zoom, vemos lo que está sucediendo en el bus de datos.

En un flanco ascendente (en este caso), se elimina un byte del bus de datos, que puede enviarse directamente a la pantalla para su visualización o "doblarse" en un búfer para su procesamiento posterior.

En teoría todo está más o menos claro, ahora en cuanto a la interfaz. DCMI microcontrolador STM32.

Interfaz DCMI es capaz de trabajar con un bus de datos de hasta 14 bits de ancho, admite sincronización tanto de hardware como de software, así como formatos de datos: YCbCr, RGB y JPEG.
Además, DCMI contiene un buffer FIFO, tiene la capacidad de configurar interrupciones (incluso al llenar el registro de datos) y configurar la operación a través de DMA.

Interrumpe desde DCMI se puede llamar cuando ocurren las siguientes condiciones: fin de línea, fin de trama, desbordamiento del búfer de recepción, error de sincronización detectado (con sincronización interna).
Me quedé algo perplejo por la falta de una salida de reloj de cámara especial. No sé por qué los desarrolladores de Microelectrónica SGS Se abandonó, pero para mí sería muy conveniente tener, por ejemplo, una fuente de reloj personalizable.
Personalmente, utilicé un temporizador-contador de uso general encendido en modo PWM para generar una onda cuadrada con una frecuencia de 4 MHz. Por supuesto, no se pueden obtener FPS altos con un reloj así, pero haré una reserva de inmediato: la pantalla que estoy usando no está conectada a FMC Por lo tanto, la función más larga de toda la cadena es la función de salida LCD, por lo que a mayor frecuencia falla la salida de la imagen a la pantalla. Por lo tanto, antes de descargar, apago el temporizador y, después, lo vuelvo a encender.
módulo de hardware DCMI contiene, además del registro de datos, diez registros de control/estado. Esto es: registro de control ( DCMI_CR), registro de estado ( DCMI_SR), registro de estado de interrupción ( DCMI_RIS), registro de habilitación de interrupción ( DCMI_IER), registro de máscara de interrupción ( DCMI_MIS), registro de reinicio de bandera de interrupción ( DCMI_ICR), registro de código de reloj interno ( DCMI_ESCR), registro de reinicio de máscara de código de reloj interno ( DCMI_ESUR), registro de valores iniciales al capturar parte del fotograma ( DCMI_CWSTRT) y el registro del tamaño del fragmento de fotograma en el modo CropWindow ( DCMI_CWSIZE). Y, por supuesto, el registro de datos... DCMI_DR.
En este caso, los registros relacionados con la captura de parte del fotograma y la sincronización interna no nos interesan. También decidí dejar las interrupciones por ahora, por lo que vale la pena considerar con más detalle solo el registro de control. DCMI_CR y registro de estado DCMI_SR.

El registro de control nos brinda la oportunidad de personalizar completamente el formato de interacción con la cámara: tamaño del bus de datos, niveles de línea activa HSYNC Y VSYNC, etc.

En orden. Poco PERMITIR– Huelga decir que la interfaz está puesta en funcionamiento. Campo electroerosión (modo de datos extendidos) – tamaño del bus de datos; Mi cámara tiene un bus de ocho bits, por lo que este campo debería estar configurado en "00". Campo FCRC (control de velocidad de captura de fotogramas) permite ajustar ligeramente el FPC: 00 – se capturan todos los fotogramas entrantes, 01 – cada segundo fotograma, 10 – cada cuarto. bits VSPOL Y HSPOL– niveles activos de líneas de sincronización verticales y horizontales. Los niveles activos se ignoran y no se capturan datos durante los períodos activos; esto debe tenerse en cuenta. PCKPOL– bit del nivel activo de la luz estroboscópica de píxeles – en qué borde de la señal leer datos del bus: frontal o posterior. ESS– bit para seleccionar el método de sincronización: externa o interna. JPEG– elección del formato de datos entrantes: comprimidos o no. CULTIVO– bit de selección de captura de fragmento de trama ( ventana de recorte). Si este bit se establece en uno, la interfaz capturará datos en una ventana definida por los valores en los registros. DCMI_CWSTRT Y DCMI_CWSIZE.

Entonces, configurémoslo.
Como estoy acostumbrado a usar la biblioteca de periféricos estándar de ST (aunque en las primeras iteraciones de trabajo con nuevos periféricos nunca la uso hasta que modifico los registros manualmente), configuré los ajustes usando la biblioteca.

Void DCMIInitialRoutine(void) ( DCMI_InitTypeDef DCMI_CamType; DCMI_DeInit(); DCMI_CamType.DCMI_CaptureMode = DCMI_CaptureMode_Continuous; DCMI_CamType.DCMI_CaptureRate = DCMI_CaptureRate_All_Frame; DCMI_CamType.DCMI_ExtendedDataMode = DCMI_ExtendedData Mode_8b; _SynchroMode = DCMI_SynchroMode_Hardware; DCMI_CamType(HABILITADO);
En realidad, para mis necesidades era posible no tocar ni un bit en la caja registradora. DCMI_CR– por defecto se restablecen – excepto los bits CAPTURA Y PERMITIR.
La interfaz está configurada y lista para usar. Después de enviar una señal de reloj a la cámara, la interfaz comenzará a recibir los datos que necesitamos procesar.
Para empezar, me propuse la tarea más sencilla: mostrar la imagen en la pantalla para que el procesamiento de datos sea mínimo.
El registro de estado nos ayudará a leer oportunamente los datos del búfer de recepción. DCMI_SR.

Hay una cantidad muy escasa de bits disponibles para lectura: solo tres. bits HSYNC Y VSYNC señalar el estado de las líneas correspondientes: fase activa o avance de línea; lo más interesante es el bit FNE. Nos dice que llenemos el buffer con datos. O por no llenarlo.
Comprobación del estado de la broca en un bucle fijo FNE V DCMI_SR, aprendemos sobre la llegada de datos al búfer receptor de treinta y dos bits. En mi caso los datos estarán ubicados así:

Al configurar el bit FNE en el registro de estado DCMI_SR el búfer de recepción contendrá cuatro bytes, datos de dos píxeles adyacentes: Byte0 Y Byte1 – 16 bits de píxeles norte, A Byte2 Y Byte3 – 16 bits de píxeles n+1. Todo lo que tengo que hacer es combinarlos y enviarlos al display. Así es como se ve el bucle principal:
while (1) ( while ((DCMI_GetFlagStatus(DCMI_FLAG_FNE)) == RESET); //Esperando el buffer TIM_Cmd(TIM3, DISABLE); //Deshabilitar el reloj CAM cam_grab = (DCMI->DR); //Leyendo el buffer SendDataByte_LCD (cam_grab); cam_grab = (DCMI->DR)>>16; //Leyendo la segunda parte del búfer SendDataByte_LCD (cam_grab);
Es decir, estoy esperando que se establezca el bit. FNE en el registro de estado DCMI_SR y luego subo 16 bits de datos a la pantalla en dos pasos.
Llegados a este punto me gustaría llegar a una conclusión lógica, pero no fue así.
Después de actualizar el firmware y reiniciar el MK, vi en la pantalla... no, vi mi propia física muy familiar, pero en tonos negros y azules. Los colores rojo y verde estaban completamente ausentes.
Después de un breve enfrentamiento con el depurador, se descubrió lo siguiente: el registro de datos de la interfaz contenía solo 16 bits de datos por píxel, con los 8 bits inferiores ubicados en su lugar. Byte0 (ver figura arriba), y los ancianos están en su lugar Byte2 . Espacios Byte1 Y Byte3 estaban vacíos. Hasta ahora no he entendido de dónde viene esta discrepancia entre la documentación y la realidad, y quizás me ponga en contacto con STM.
Como resultado, logramos obtener una imagen de la cámara usando la interfaz. DCMI, aunque no sin algunas dificultades. En la figura muestro una foto del display en el que se mostraba la imagen del tablero de demostración. STM32F3Descubrimiento desde mi cámara.

Esto es lo que veremos en las conclusiones: EXTCLK, PIXCK, HSYNC Y VSYNC, si conecta un analizador lógico.

Todo luce exactamente como se esperaba: 240 pulsos HSYNC cabe dentro de la duración de uno VSYNC, 320 PIXCK- en uno HSYNC. Durante la fase activa HSYNC la cámara no produce señales PIXCK– exactamente la forma en que fue creada.
En general, la interfaz me decepcionó un poco. La ausencia de una pata de sincronización de cámara "estándar", la ausencia de funciones integradas más o menos interesantes (¿qué pasa con un codificador JPEG de hardware?), e incluso bailar con una pandereta alrededor de un medio cocido FIFO
Organizar el trabajo de la cámara durante las interrupciones. PIXCK, HSYNC Y VSYNC No tuve tantos problemas como al trabajar con la cámara usando hardware. DCMI.
Sin embargo, en un futuro próximo intentaré capturar un fotograma y comprimirlo en JPEG e intente escribir una imagen en la tarjeta SD.
PD. Por si acaso, te doy un enlace al proyecto para " Código::Bloques"- de repente le resultará útil a alguien.

Érase una vez la conexión de una cámara de un teléfono móvil a un microcontrolador STM32F407VGT6(que tiene lugar en el tablero STM32F4Descubrimiento), Ni siquiera pensé en el hecho de que este controlador tiene una interfaz de hardware especial para este asunto. Tal vez no leí la hoja de datos con atención, pero siempre pensé que la interfaz DCMI disponible solo para chips en paquetes UFBGA176 Y LQFP desde 144 pies. Sin embargo, no hace mucho descubrí el detalle sonoro: 100 patas STM32F407 También tiene DCMI a bordo.
Siendo un gran admirador de estudiar y lanzar conjuntamente varios hardware móviles (en particular, pantallas LCD y cámaras) con MK, simplemente no pude pasar por alto tal descubrimiento y decidí llenar este vacío en el estudio de los periféricos STM32. En realidad, este material está dedicado a describir la implementación de la idea que ha surgido.

Sólo un poco de teoría.

En primer lugar, hay que imaginarse de qué estamos hablando, o mejor dicho, qué es una cámara CMOS y para qué se utiliza.
Este tipo de cámara genera información del sensor en formato digital: RGB, YCbCr y también en formato comprimido: JPEG. Las diferentes cámaras tienen sus propios matices en cuanto a capacidades, consideraré un caso muy específico de una cámara de baja resolución (VGA, 640x480), que saqué de mi teléfono en la antigüedad " Siemens C72"(sensor PixelPlus PO2030N). Esta cámara es la más adecuada para el estudio por su facilidad de manejo y por pertenecer a un tipo más o menos común. Hace mucho tiempo le hice una pequeña placa (para mayor facilidad de conexión), con un estabilizador de 2,8 V y resistencias pull-up en el bus. I2C. Aquí está (el cable de la cámara y el conector están ocultos debajo de la carcasa).


Además de los matices en el campo del formato de datos, las cámaras también pueden diferir en el número de pines de sincronización. La mayoría (en mi opinión) de los sensores tienen pines especiales de sincronización horizontal y vertical; pero hay cámaras que solo tienen una salida de luz estroboscópica de píxeles y le informan sobre el comienzo de una nueva línea/cuadro mediante códigos de transmisión especiales (por ejemplo, 0x00 o 0xFF). La cámara que tengo tiene pines de sincronización externos.
Se puede estimar una representación esquemática aproximada de la cámara en forma de bloque.


En su mayor parte, las cámaras CMOS se controlan a través de una interfaz I2C(aunque he visto dispositivos controlados por UART). A través de I2C se configuran diversos parámetros, como: resolución, gama de colores, formato de datos de salida, etc.
Conclusión EXTCLK– sincronización de cámara, que debe proporcionarse externamente. DCLK– una señal estroboscópica, a lo largo de cuyo borde ascendente o descendente se registran datos en el bus de datos de la cámara (por ejemplo, un byte de datos de un píxel de la matriz, o un byte de datos de “medio píxel” si la cámara funciona en el modo RGB565). HSYNC– señal de sincronización horizontal que indica el comienzo de una nueva línea, y VSYNC– una señal de sincronización cuyo nivel activo indica el comienzo de una nueva trama. Conclusiones D0..D7– bus de datos; Como regla general, para este tipo de cámaras es de ocho bits.
Ahora hablemos más sobre las señales de sincronización.


Los gráficos muestran que la cámara está configurada para la actividad de la señal. DCLK sólo durante la fase activa HSYNC(es decir, es esta fase la que nos interesa; la señal del reloj durante el período de "avance de línea" no nos interesa). Si la cámara está configurada con una resolución de 320x240, durante cada pulso HSYNC 320 pulsos encajan DCLK, y durante el periodo VSYNC – 240 HSYNC.
Cuando hacemos zoom, vemos lo que está sucediendo en el bus de datos.


En un flanco ascendente (en este caso), se elimina un byte del bus de datos, que puede enviarse directamente a la pantalla para su visualización o "doblarse" en un búfer para su procesamiento posterior.
En teoría todo está más o menos claro, ahora en cuanto a la interfaz. DCMI microcontrolador STM32.
Interfaz DCMI es capaz de trabajar con un bus de datos de hasta 14 bits de ancho, admite sincronización tanto de hardware como de software, así como formatos de datos: YCbCr, RGB y JPEG.
Además, DCMI contiene un buffer FIFO, tiene la capacidad de configurar interrupciones (incluso al llenar el registro de datos) y configurar la operación a través de DMA.


Interrumpe desde DCMI se puede llamar cuando ocurren las siguientes condiciones: fin de línea, fin de trama, desbordamiento del búfer de recepción, error de sincronización detectado (con sincronización interna).
Me quedé algo perplejo por la falta de una salida de reloj de cámara especial. No sé por qué los desarrolladores de Microelectrónica SGS Se abandonó, pero para mí sería muy conveniente tener, por ejemplo, una fuente de reloj personalizable.
Personalmente, utilicé un temporizador-contador de uso general encendido en modo PWM para generar una onda cuadrada con una frecuencia de 4 MHz. Por supuesto, no se pueden obtener FPS altos con un reloj así, pero haré una reserva de inmediato: la pantalla que estoy usando no está conectada a FMC Por lo tanto, la función más larga de toda la cadena es la función de salida LCD, por lo que a mayor frecuencia falla la salida de la imagen a la pantalla. Por lo tanto, antes de descargar, apago el temporizador y, después, lo vuelvo a encender.
módulo de hardware DCMI contiene, además del registro de datos, diez registros de control/estado. Esto es: registro de control ( DCMI_CR), registro de estado ( DCMI_SR), registro de estado de interrupción ( DCMI_RIS), registro de habilitación de interrupción ( DCMI_IER), registro de máscara de interrupción ( DCMI_MIS), registro de reinicio de bandera de interrupción ( DCMI_ICR), registro de código de reloj interno ( DCMI_ESCR), registro de reinicio de máscara de código de reloj interno ( DCMI_ESUR), registro de valores iniciales al capturar parte del fotograma ( DCMI_CWSTRT) y el registro del tamaño del fragmento de fotograma en el modo CropWindow ( DCMI_CWSIZE). Y, por supuesto, el registro de datos... DCMI_DR.
En este caso, los registros relacionados con la captura de parte del fotograma y la sincronización interna no nos interesan. También decidí dejar las interrupciones por ahora, por lo que vale la pena considerar con más detalle solo el registro de control. DCMI_CR y registro de estado DCMI_SR.

El registro de control nos brinda la oportunidad de personalizar completamente el formato de interacción con la cámara: tamaño del bus de datos, niveles de línea activa HSYNC Y VSYNC, etc.


En orden. Poco PERMITIR– Huelga decir que la interfaz está puesta en funcionamiento. Campo electroerosión (modo de datos extendidos) – tamaño del bus de datos; Mi cámara tiene un bus de ocho bits, por lo que este campo debería estar configurado en "00". Campo FCRC (control de velocidad de captura de fotogramas) permite ajustar ligeramente el FPC: 00 – se capturan todos los fotogramas entrantes, 01 – cada segundo fotograma, 10 – cada cuarto. bits VSPOL Y HSPOL– niveles activos de líneas de sincronización verticales y horizontales. Los niveles activos se ignoran y no se capturan datos durante los períodos activos; esto debe tenerse en cuenta. PCKPOL– bit del nivel activo de la luz estroboscópica de píxeles – en qué borde de la señal leer datos del bus: frontal o posterior. ESS– bit para seleccionar el método de sincronización: externa o interna. JPEG– elección del formato de datos entrantes: comprimidos o no. CULTIVO– bit de selección de captura de fragmento de trama ( ventana de recorte). Si este bit se establece en uno, la interfaz capturará datos en una ventana definida por los valores en los registros. DCMI_CWSTRT Y DCMI_CWSIZE.
Entonces, configurémoslo. Como estoy acostumbrado a usar la biblioteca de periféricos estándar de ST (aunque en las primeras iteraciones de trabajo con nuevos periféricos nunca la uso hasta que modifico los registros manualmente), configuré los ajustes usando la biblioteca.

Void DCMIInitialRoutine(void) ( DCMI_InitTypeDef DCMI_CamType; DCMI_DeInit(); DCMI_CamType.DCMI_CaptureMode = DCMI_CaptureMode_Continuous; DCMI_CamType.DCMI_CaptureRate = DCMI_CaptureRate_All_Frame; DCMI_CamType.DCMI_ExtendedDataMode = DCMI_ExtendedData Mode_8b; _SynchroMode = DCMI_SynchroMode_Hardware; DCMI_CamType(HABILITADO);

En realidad, para mis necesidades era posible no tocar ni un bit en la caja registradora. DCMI_CR– por defecto se restablecen – excepto los bits CAPTURA Y PERMITIR.
La interfaz está configurada y lista para usar. Después de enviar una señal de reloj a la cámara, la interfaz comenzará a recibir los datos que necesitamos procesar.
Para empezar, me propuse la tarea más sencilla: mostrar la imagen en la pantalla para que el procesamiento de datos sea mínimo.
El registro de estado nos ayudará a leer oportunamente los datos del búfer de recepción. DCMI_SR.

Hay una cantidad muy escasa de bits disponibles para lectura: solo tres. bits HSYNC Y VSYNC señalar el estado de las líneas correspondientes: fase activa o avance de línea; lo más interesante es el bit FNE. Nos dice que llenemos el buffer con datos. O por no llenarlo.
Comprobación del estado de la broca en un bucle fijo FNE V DCMI_SR, aprendemos sobre la llegada de datos al búfer receptor de treinta y dos bits. En mi caso los datos estarán ubicados así:

Al configurar el bit FNE en el registro de estado DCMI_SR el búfer de recepción contendrá cuatro bytes, datos de dos píxeles adyacentes: Byte0 Y Byte1 – 16 bits de píxeles norte, A Byte2 Y Byte3 – 16 bits de píxeles n+1. Todo lo que tengo que hacer es combinarlos y enviarlos al display. Así es como se ve el bucle principal:

Mientras (1) ( while ((DCMI_GetFlagStatus(DCMI_FLAG_FNE)) == RESET); //Esperando el búfer TIM_Cmd(TIM3, DISABLE); //Deshabilitar el reloj CAM cam_grab = (DCMI->DR); //Leyendo el búfer SendDataByte_LCD (cam_grab); cam_grab = (DCMI->DR)>>16; //Leyendo la segunda parte del búfer SendDataByte_LCD (cam_grab);

Es decir, estoy esperando que se establezca el bit. FNE en el registro de estado DCMI_SR y luego subo 16 bits de datos a la pantalla en dos pasos.
Llegados a este punto me gustaría llegar a una conclusión lógica, pero no fue así.
Después de actualizar el firmware y reiniciar el MK, vi en la pantalla... no, vi mi propia física muy familiar, pero en tonos negros y azules. Los colores rojo y verde estaban completamente ausentes.
Después de un breve enfrentamiento con el depurador, se descubrió lo siguiente: el registro de datos de la interfaz contenía solo 16 bits de datos por píxel, con los 8 bits inferiores ubicados en su lugar. Byte0 (ver figura arriba), y los ancianos están en su lugar Byte2 . Espacios Byte1 Y Byte3 estaban vacíos. Hasta ahora no he entendido de dónde viene esta discrepancia entre la documentación y la realidad, y quizás me ponga en contacto con STM.
Como resultado, logramos obtener una imagen de la cámara usando la interfaz. DCMI, aunque no sin algunas dificultades. En la figura muestro una foto del display en el que se mostraba la imagen del tablero de demostración. STM32F3Descubrimiento desde mi cámara.


Esto es lo que veremos en las conclusiones: EXTCLK, PIXCK, HSYNC Y VSYNC, si conecta un analizador lógico.


Todo luce exactamente como se esperaba: 240 pulsos HSYNC cabe dentro de la duración de uno VSYNC, 320 PIXCK- en uno HSYNC. Durante la fase activa HSYNC la cámara no produce señales PIXCK– exactamente la forma en que fue creada.
En general, la interfaz me decepcionó un poco. La ausencia de una pata de sincronización de cámara "estándar", la ausencia de funciones integradas más o menos interesantes (¿qué pasa con un codificador JPEG de hardware?), e incluso bailar con una pandereta alrededor de un medio cocido FIFO
Organizar el trabajo de la cámara durante las interrupciones. PIXCK, HSYNC Y VSYNC No tuve tantos problemas como al trabajar con la cámara usando hardware. DCMI.
Sin embargo, en un futuro próximo intentaré capturar un fotograma y comprimirlo en JPEG e intente escribir una imagen en la tarjeta SD.
PD. Por si acaso, te doy un enlace al proyecto para " Código::Bloques"- de repente le resultará útil a alguien.

O filmar en cámara lenta es filmar a una frecuencia inferior a la frecuencia estándar de disparo y proyección de 24 fotogramas por segundo.

Después de comenzar a estudiar los microcontroladores STM32 y escribir "HelloWorld" con el LED parpadeando, me di cuenta de que para comprender mejor el funcionamiento del STM32 necesitaba implementar algo más complejo usando más periféricos de microcontroladores. Así surgió la idea de crear una cámara Time-lapse.

La cámara que desarrollé tomará fotografías aproximadamente una vez cada 5 segundos y las guardará en la tarjeta SD en formato jpeg. A continuación, deben combinarse en la computadora en un archivo de video.

Para crear la cámara utilicé los siguientes componentes:

La tarjeta se conecta mediante dos funciones:
1. Usando la función inicializar_disco la tarjeta se inicializa.
2. A continuación necesitas montarlo. montaje_f.

Luego de completar exitosamente estos pasos, podrás realizar diversas operaciones con la tarjeta, como por ejemplo:
1. f_abierto– abrir un archivo,
2. f_cerrar– cerrar el expediente;
3. f_mkdir– crear un directorio;
4. f_chdir– selección de directorio;
5. f_escribir– escribir en un archivo;
6. f_read– lectura del archivo.

Describí cómo trabajar con la cámara y la tarjeta SD, ahora veamos cómo funciona el programa en su conjunto:
1. Inicialice la tarjeta SD;
2. Inicialice el módulo de la cámara;
3. Abra el archivo time.txt (el archivo debe contener una línea del formato 01.01.2014_12:00 ), que almacena el tiempo para contar el temporizador RTC;
4. Lea la hora y fecha del archivo y configure el RTC;
5. Cierre el archivo time.txt;
6. Cree un directorio para almacenar fotos "LinkSpritePhoto";
7. Cuando presione el botón PA0 en el tablero, tome una foto y guárdela en la tarjeta (mientras se toma la foto, el LED azul está encendido);
8. Si alguna de las funciones no se realiza, caemos en un bucle sin fin y parpadeamos el LED verde.

Para ejecutar la cámara en modo continuo, debe descomentar las siguientes líneas en main.c:

//EnabledButtonStart = 101; // Para ejecutar en un bucle, descomente esta línea //Delay(300); // Retraso para ejecutar en bucle
Y comenta esta línea:

Inicio de botón habilitado = 0; // Para ejecutar en un bucle, comenta esta línea
Luego, cuando la enciendas, la cámara comenzará a tomar fotografías de forma continua.

En general, he recopilado una descripción de cómo funciona esta cámara y ahora puedo mostrar el resultado del trabajo.

  • Tutorial

STM32F4Discovery: conecte la cámara a través de la interfaz DCMI

Érase una vez la conexión de una cámara de un teléfono móvil a un microcontrolador STM32F407VGT6(que tiene lugar en el tablero STM32F4Descubrimiento), Ni siquiera pensé en el hecho de que este controlador tiene una interfaz de hardware especial para este asunto. Tal vez no leí la hoja de datos con atención, pero siempre pensé que la interfaz DCMI disponible solo para chips en paquetes UFBGA176 Y LQFP desde 144 pies. Sin embargo, no hace mucho descubrí el detalle sonoro: 100 patas STM32F407 También tiene DCMI a bordo.
Siendo un gran admirador de estudiar y lanzar conjuntamente varios hardware móviles (en particular, pantallas LCD y cámaras) con MK, simplemente no pude pasar por alto tal descubrimiento y decidí llenar este vacío en el estudio de los periféricos STM32. En realidad, este material está dedicado a describir la implementación de la idea que ha surgido.

Sólo un poco de teoría.

En primer lugar, hay que imaginarse de qué estamos hablando, o mejor dicho, qué es una cámara CMOS y para qué se utiliza.
Este tipo de cámara genera información del sensor en formato digital: RGB, YCbCr y también en formato comprimido: JPEG. Las diferentes cámaras tienen sus propios matices en cuanto a capacidades, consideraré un caso muy específico de una cámara de baja resolución (VGA, 640x480), que saqué de mi teléfono en la antigüedad " Siemens C72"(sensor PixelPlus PO2030N). Esta cámara es la más adecuada para el estudio por su facilidad de manejo y por pertenecer a un tipo más o menos común. Hace mucho tiempo le hice una pequeña placa (para mayor facilidad de conexión), con un estabilizador de 2,8 V y resistencias pull-up en el bus. I2C. Aquí está (el cable de la cámara y el conector están ocultos debajo de la carcasa).

Además de los matices en el campo del formato de datos, las cámaras también pueden diferir en el número de pines de sincronización. La mayoría (en mi opinión) de los sensores tienen pines especiales de sincronización horizontal y vertical; pero hay cámaras que solo tienen una salida de luz estroboscópica de píxeles y le informan sobre el comienzo de una nueva línea/cuadro mediante códigos de transmisión especiales (por ejemplo, 0x00 o 0xFF). La cámara que tengo tiene pines de sincronización externos.
Se puede estimar una representación esquemática aproximada de la cámara en forma de bloque.

En su mayor parte, las cámaras CMOS se controlan a través de una interfaz I2C(aunque he visto dispositivos controlados por UART). A través de I2C se configuran diversos parámetros, como: resolución, gama de colores, formato de datos de salida, etc.
Conclusión EXTCLK– sincronización de cámara, que debe proporcionarse externamente. DCLK– una señal estroboscópica, a lo largo de cuyo borde ascendente o descendente se registran datos en el bus de datos de la cámara (por ejemplo, un byte de datos de un píxel de la matriz, o un byte de datos de “medio píxel” si la cámara funciona en el modo RGB565). HSYNC– señal de sincronización horizontal que indica el comienzo de una nueva línea, y VSYNC– una señal de sincronización cuyo nivel activo indica el comienzo de una nueva trama. Conclusiones D0..D7– bus de datos; Como regla general, para este tipo de cámaras es de ocho bits.
Ahora hablemos más sobre las señales de sincronización.

Los gráficos muestran que la cámara está configurada para la actividad de la señal. DCLK sólo durante la fase activa HSYNC(es decir, es esta fase la que nos interesa; la señal del reloj durante el período de "avance de línea" no nos interesa). Si la cámara está configurada con una resolución de 320x240, durante cada pulso HSYNC 320 pulsos encajan DCLK, y durante el periodo VSYNC – 240 HSYNC.
Cuando hacemos zoom, vemos lo que está sucediendo en el bus de datos.

En un flanco ascendente (en este caso), se elimina un byte del bus de datos, que puede enviarse directamente a la pantalla para su visualización o "doblarse" en un búfer para su procesamiento posterior.

En teoría todo está más o menos claro, ahora en cuanto a la interfaz. DCMI microcontrolador STM32.

Interfaz DCMI es capaz de trabajar con un bus de datos de hasta 14 bits de ancho, admite sincronización tanto de hardware como de software, así como formatos de datos: YCbCr, RGB y JPEG.
Además, DCMI contiene un buffer FIFO, tiene la capacidad de configurar interrupciones (incluso al llenar el registro de datos) y configurar la operación a través de DMA.

Interrumpe desde DCMI se puede llamar cuando ocurren las siguientes condiciones: fin de línea, fin de trama, desbordamiento del búfer de recepción, error de sincronización detectado (con sincronización interna).
Me quedé algo perplejo por la falta de una salida de reloj de cámara especial. No sé por qué los desarrolladores de Microelectrónica SGS Se abandonó, pero para mí sería muy conveniente tener, por ejemplo, una fuente de reloj personalizable.
Personalmente, utilicé un temporizador-contador de uso general encendido en modo PWM para generar una onda cuadrada con una frecuencia de 4 MHz. Por supuesto, no se pueden obtener FPS altos con un reloj así, pero haré una reserva de inmediato: la pantalla que estoy usando no está conectada a FMC Por lo tanto, la función más larga de toda la cadena es la función de salida LCD, por lo que a mayor frecuencia falla la salida de la imagen a la pantalla. Por lo tanto, antes de descargar, apago el temporizador y, después, lo vuelvo a encender.
módulo de hardware DCMI contiene, además del registro de datos, diez registros de control/estado. Esto es: registro de control ( DCMI_CR), registro de estado ( DCMI_SR), registro de estado de interrupción ( DCMI_RIS), registro de habilitación de interrupción ( DCMI_IER), registro de máscara de interrupción ( DCMI_MIS), registro de reinicio de bandera de interrupción ( DCMI_ICR), registro de código de reloj interno ( DCMI_ESCR), registro de reinicio de máscara de código de reloj interno ( DCMI_ESUR), registro de valores iniciales al capturar parte del fotograma ( DCMI_CWSTRT) y el registro del tamaño del fragmento de fotograma en el modo CropWindow ( DCMI_CWSIZE). Y, por supuesto, el registro de datos... DCMI_DR.
En este caso, los registros relacionados con la captura de parte del fotograma y la sincronización interna no nos interesan. También decidí dejar las interrupciones por ahora, por lo que vale la pena considerar con más detalle solo el registro de control. DCMI_CR y registro de estado DCMI_SR.

El registro de control nos brinda la oportunidad de personalizar completamente el formato de interacción con la cámara: tamaño del bus de datos, niveles de línea activa HSYNC Y VSYNC, etc.

En orden. Poco PERMITIR– Huelga decir que la interfaz está puesta en funcionamiento. Campo electroerosión (modo de datos extendidos) – tamaño del bus de datos; Mi cámara tiene un bus de ocho bits, por lo que este campo debería estar configurado en "00". Campo FCRC (control de velocidad de captura de fotogramas) permite ajustar ligeramente el FPC: 00 – se capturan todos los fotogramas entrantes, 01 – cada segundo fotograma, 10 – cada cuarto. bits VSPOL Y HSPOL– niveles activos de líneas de sincronización verticales y horizontales. Los niveles activos se ignoran y no se capturan datos durante los períodos activos; esto debe tenerse en cuenta. PCKPOL– bit del nivel activo de la luz estroboscópica de píxeles – en qué borde de la señal leer datos del bus: frontal o posterior. ESS– bit para seleccionar el método de sincronización: externa o interna. JPEG– elección del formato de datos entrantes: comprimidos o no. CULTIVO– bit de selección de captura de fragmento de trama ( ventana de recorte). Si este bit se establece en uno, la interfaz capturará datos en una ventana definida por los valores en los registros. DCMI_CWSTRT Y DCMI_CWSIZE.

Entonces, configurémoslo.
Como estoy acostumbrado a usar la biblioteca de periféricos estándar de ST (aunque en las primeras iteraciones de trabajo con nuevos periféricos nunca la uso hasta que modifico los registros manualmente), configuré los ajustes usando la biblioteca.

Void DCMIInitialRoutine(void) ( DCMI_InitTypeDef DCMI_CamType; DCMI_DeInit(); DCMI_CamType.DCMI_CaptureMode = DCMI_CaptureMode_Continuous; DCMI_CamType.DCMI_CaptureRate = DCMI_CaptureRate_All_Frame; DCMI_CamType.DCMI_ExtendedDataMode = DCMI_ExtendedData Mode_8b; _SynchroMode = DCMI_SynchroMode_Hardware; DCMI_CamType(HABILITADO);
En realidad, para mis necesidades era posible no tocar ni un bit en la caja registradora. DCMI_CR– por defecto se restablecen – excepto los bits CAPTURA Y PERMITIR.
La interfaz está configurada y lista para usar. Después de enviar una señal de reloj a la cámara, la interfaz comenzará a recibir los datos que necesitamos procesar.
Para empezar, me propuse la tarea más sencilla: mostrar la imagen en la pantalla para que el procesamiento de datos sea mínimo.
El registro de estado nos ayudará a leer oportunamente los datos del búfer de recepción. DCMI_SR.

Hay una cantidad muy escasa de bits disponibles para lectura: solo tres. bits HSYNC Y VSYNC señalar el estado de las líneas correspondientes: fase activa o avance de línea; lo más interesante es el bit FNE. Nos dice que llenemos el buffer con datos. O por no llenarlo.
Comprobación del estado de la broca en un bucle fijo FNE V DCMI_SR, aprendemos sobre la llegada de datos al búfer receptor de treinta y dos bits. En mi caso los datos estarán ubicados así:

Al configurar el bit FNE en el registro de estado DCMI_SR el búfer de recepción contendrá cuatro bytes, datos de dos píxeles adyacentes: Byte0 Y Byte1 – 16 bits de píxeles norte, A Byte2 Y Byte3 – 16 bits de píxeles n+1. Todo lo que tengo que hacer es combinarlos y enviarlos al display. Así es como se ve el bucle principal:
while (1) ( while ((DCMI_GetFlagStatus(DCMI_FLAG_FNE)) == RESET); //Esperando el buffer TIM_Cmd(TIM3, DISABLE); //Deshabilitar el reloj CAM cam_grab = (DCMI->DR); //Leyendo el buffer SendDataByte_LCD (cam_grab); cam_grab = (DCMI->DR)>>16; //Leyendo la segunda parte del búfer SendDataByte_LCD (cam_grab);
Es decir, estoy esperando que se establezca el bit. FNE en el registro de estado DCMI_SR y luego subo 16 bits de datos a la pantalla en dos pasos.
Llegados a este punto me gustaría llegar a una conclusión lógica, pero no fue así.
Después de actualizar el firmware y reiniciar el MK, vi en la pantalla... no, vi mi propia física muy familiar, pero en tonos negros y azules. Los colores rojo y verde estaban completamente ausentes.
Después de un breve enfrentamiento con el depurador, se descubrió lo siguiente: el registro de datos de la interfaz contenía solo 16 bits de datos por píxel, con los 8 bits inferiores ubicados en su lugar. Byte0 (ver figura arriba), y los ancianos están en su lugar Byte2 . Espacios Byte1 Y Byte3 estaban vacíos. Hasta ahora no he entendido de dónde viene esta discrepancia entre la documentación y la realidad, y quizás me ponga en contacto con STM.
Como resultado, logramos obtener una imagen de la cámara usando la interfaz. DCMI, aunque no sin algunas dificultades. En la figura muestro una foto del display en el que se mostraba la imagen del tablero de demostración. STM32F3Descubrimiento desde mi cámara.

Esto es lo que veremos en las conclusiones: EXTCLK, PIXCK, HSYNC Y VSYNC, si conecta un analizador lógico.

Todo luce exactamente como se esperaba: 240 pulsos HSYNC cabe dentro de la duración de uno VSYNC, 320 PIXCK- en uno HSYNC. Durante la fase activa HSYNC la cámara no produce señales PIXCK– exactamente la forma en que fue creada.
En general, la interfaz me decepcionó un poco. La ausencia de una pata de sincronización de cámara "estándar", la ausencia de funciones integradas más o menos interesantes (¿qué pasa con un codificador JPEG de hardware?), e incluso bailar con una pandereta alrededor de un medio cocido FIFO
Organizar el trabajo de la cámara durante las interrupciones. PIXCK, HSYNC Y VSYNC No tuve tantos problemas como al trabajar con la cámara usando hardware. DCMI.
Sin embargo, en un futuro próximo intentaré capturar un fotograma y comprimirlo en JPEG e intente escribir una imagen en la tarjeta SD.
PD. Por si acaso, te doy un enlace al proyecto para " Código::Bloques"- de repente le resultará útil a alguien.

La tarjeta se conecta mediante dos funciones:
1. Usando la función inicializar_disco la tarjeta se inicializa.
2. A continuación necesitas montarlo. montaje_f.

Luego de completar exitosamente estos pasos, podrás realizar diversas operaciones con la tarjeta, como por ejemplo:
1. f_abierto– abrir un archivo,
2. f_cerrar– cerrar el expediente;
3. f_mkdir– crear un directorio;
4. f_chdir– selección de directorio;
5. f_escribir– escribir en un archivo;
6. f_read– lectura del archivo.

Describí cómo trabajar con la cámara y la tarjeta SD, ahora veamos cómo funciona el programa en su conjunto:
1. Inicialice la tarjeta SD;
2. Inicialice el módulo de la cámara;
3. Abra el archivo time.txt (el archivo debe contener una línea del formato 01.01.2014_12:00 ), que almacena el tiempo para contar el temporizador RTC;
4. Lea la hora y fecha del archivo y configure el RTC;
5. Cierre el archivo time.txt;
6. Cree un directorio para almacenar fotos "LinkSpritePhoto";
7. Cuando presione el botón PA0 en el tablero, tome una foto y guárdela en la tarjeta (mientras se toma la foto, el LED azul está encendido);
8. Si alguna de las funciones no se realiza, caemos en un bucle sin fin y parpadeamos el LED verde.

Para ejecutar la cámara en modo continuo, debe descomentar las siguientes líneas en main.c:

//EnabledButtonStart = 101; // Para ejecutar en un bucle, descomente esta línea //Delay(300); // Retraso para ejecutar en bucle
Y comenta esta línea:

Inicio de botón habilitado = 0; // Para ejecutar en un bucle, comenta esta línea
Luego, cuando la enciendas, la cámara comenzará a tomar fotografías de forma continua.

En general, he recopilado una descripción de cómo funciona esta cámara y ahora puedo mostrar el resultado del trabajo.




Arriba