STM32H7B0 HAL库中关于DMA的注意事项以及DCMI调试遇到的问题及解决方法

article/2025/9/20 15:28:24

先总结总结问题

问题1:MX_DCMI_Init();放到  MX_DMA_Init();后

问题2:DMA缓存缓存要放到SRAM中__align(32) uint32_t buffer[65535] __attribute((at(0X24040000)));

问题3:IO复用问题,DCMI数据口可以复用到其他IO口,要注意配置

问题4:摄像头时钟配置,不能过快,也不能过慢,过快采集不过来,过慢JPEG会传一半停止

问题5:上位机字节序,JPG由FF D8开头,FF D9结尾

解决上面5个问题,STM32H7 DCMI就可以轻松使用

由于需要用到摄像头,用IO驱动的话会比较慢,这里使用的STM32H7B0中的DCMI接口,由于DMA用的比较少,在这里卡了3天,期间各种测试,从硬件到软件,接用IO读OV2640,可以读到数据,确定硬件没有问题,DCMI的DMA一直进错误中断Transfer Error Interrupt management

网上说是内存地址问题,DMA不能访问直接访问DTCM,也改成SRAM了,也会进入错误中断

DMA1等都不能访问DTCM

最终发现把    MX_DCMI_Init();放到  MX_DMA_Init();即可正常传输数据

 Several peripheral DMA handle pointers point to the same DMA handle.
     Be aware that there is only one channel to perform all the requested DMAs.干扰项,删掉就行不用管,我开始还以为这里需要配置什么东西,就保留最上边一行 

删完就像这样就可以

 

缓存放到SRAM放到中

__align(32) uint32_t buffer[65535] __attribute((at(0X24040000)));

开启缓存对于DCMI没有影响,开不开都可以正常运行

static void CPU_CACHE_Enable(void)
{
    SCB_EnableICache();//使能I-Cache
  SCB_EnableDCache();//使能D-Cache   
    SCB->CACR|=1<<2;   //强制D-Cache透写,如不开启,实际使用中可能遇到各种问题    
}

启动采集代码

void StartOV2640()
{int i =0;__HAL_DCMI_ENABLE_IT(&hdcmi, DCMI_IER_FRAME_IE);                                               	//使用帧中断memset(buffer, 0, 65535);                                        					//把接收BUF清空HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_SNAPSHOT, (uint32_t)buffer, 65535); 	//启动拍照
}void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
{int i =0;HAL_DCMI_Suspend(hdcmi); // 拍照完成,挂起 DCMIHAL_DCMI_Stop(hdcmi);    // 拍照完成,停止 DMA传输int pictureLength = 65535;while (pictureLength > 0)     //循环计算出接收的JPEG的大小{if (buffer[pictureLength - 1] != 0x00000000){break;}pictureLength--;}jpeglen = pictureLength * 4;getPicture = 1;
}

配置IO也要注意一下D0,D1,D3可以复用到其他IO,一定不要弄错,配置完要对着IO检查一遍,频率使用也很重要,我这里用到的频率如下

单片机主频280M

摄像头主频8M

摄像头分频配置

SCCB_WR_Reg(0XFF,0X00);

SCCB_WR_Reg(0XD3,0XF);

SCCB_WR_Reg(0XFF,0X01);

SCCB_WR_Reg(0X11,0X7);

 

开启中断

DMA配置,不要修改

 NVIC给个优先级

摄像头时钟,这个可以自由发挥,和摄像头分频配置一起可以有多重组合

样张

上位机软件用C#写的,关键部分代码

private const int count = 200 * 1024;
private byte[] buffer = new byte[count];
private int offset = 0;
private int length = 0;
private bool isData = false;
public void DataCallBack(Object sender, SerialDataReceivedEventArgs e)
{try{if (isData==false){var data = _serialPort.ReadLine();if (!string.IsNullOrEmpty(data) && data.Length > 0){if(data.IndexOf("jpeg data size:")>=0){var lengthStr = data.Split(':');if(lengthStr != null && lengthStr.Length>1){length = int.Parse(lengthStr[1]);if (length > count){}else{isData = true;}}Console.WriteLine(data);}else{Console.WriteLine(data);}}}else{int thisLength = _serialPort.Read(buffer, offset, length - offset);offset = offset + thisLength;if(offset >= length){Console.WriteLine($"接收完一张图片,offset:{offset},length:{length}");string path = Directory.GetCurrentDirectory();DirectoryCheak(path + "\\out\\");bool ispictrue = false;if (false)//bmp{//bmpif (false){//RGB888System.Drawing.Bitmap formBitmap = new System.Drawing.Bitmap(96, 96);for (int i = 0; i < 96; i++){for (int j = 0; j < 96; j++){formBitmap.SetPixel(i, j, System.Drawing.Color.FromArgb(buffer[i * j + j], buffer[i * j + j + 1], buffer[i * j + j + 2]));}}formBitmap.Save(path + "\\out\\" + DateTime.Now.ToString("yyyyMMdd-HHmmss.fff") + ".bmp");}else{//RGB565List<UInt16> data = new List<UInt16>();for (int i = 0; i < length; i += 2){UInt16 thisData = (UInt16)((buffer[i] << 8) | buffer[i + 1]); ;data.Add(thisData);}System.Drawing.Bitmap formBitmap = new System.Drawing.Bitmap(96, 96);for (int i = 0; i < 96; i++){for (int j = 0; j < 96; j++){byte red = (byte)((data[i * j + j] >> 11) << 3); //5位 移动3位byte green = (byte)(((data[i * j + j] << 5) >> 10) << 2); //6位 移动2位byte blue = (byte)(((data[i * j + j] << 11) >> 11) << 3); //5位 移动3位 formBitmap.SetPixel(i, j, System.Drawing.Color.FromArgb(red, green, blue));}}formBitmap.Save(path + "\\out\\" + DateTime.Now.ToString("yyyyMMdd-HHmmss.fff") + ".bmp");}}else{List<byte> data = new List<byte>();for (int i = 1; i < length; i++){//Console.WriteLine($"i:{i},length:{length}");if (ispictrue == true){data.Add(buffer[i]);}else if ((buffer[i - 1] == 0xFF) && (buffer[i] == 0xd8)){ispictrue = true;data.Add(buffer[i - 1]);data.Add(buffer[i]);}//if((buffer[i - 1] == 0xFF) && (buffer[i] == 0xd9))//{//    data.Add(buffer[i - 1]);//    data.Add(buffer[i]);//    ispictrue = false;//    break;//}}WriteFileUsingBinaryWriter(path + "\\out\\", DateTime.Now.ToString("yyyyMMdd-HHmmss.fff") + ".jpg", data.ToArray(), data.Count());}offset = 0;length = 0;isData = false;}}}catch (Exception ex){Console.WriteLine("串口解析出错" + ex.ToString());}
}public void WriteFileUsingBinaryWriter(string path,string fileName,byte[] data,int length)
{var outputStream = File.Create(path + fileName);using (var writer = new BinaryWriter(outputStream)){writer.Write(data, 0, length);}
}/// <summary>
/// 效验文件夹,没有就创建
/// </summary>
private void DirectoryCheak(string path)
{if (false == System.IO.Directory.Exists(path)){System.IO.Directory.CreateDirectory(path);}
}private void OpenSerialPort_Click(object sender, RoutedEventArgs e)
{try{_serialPort = new SerialPort();_serialPort.PortName = SerialPort.Text;_serialPort.BaudRate = int.Parse(SerialBaudRate.Text);_serialPort.Parity = Parity.None;_serialPort.DataBits = 8;_serialPort.StopBits = StopBits.One;_serialPort.ReadTimeout = 10000;//单位毫秒_serialPort.WriteTimeout = 10000;//单位毫秒//设置串口字节接收缓冲值,通常为1//获得接收后,触发事件处理_serialPort.ReceivedBytesThreshold = 1;_serialPort.DataReceived += new SerialDataReceivedEventHandler(DataCallBack);_serialPort.Open();//Console.WriteLine(serialPort.IsOpen.ToString());OpenSerialPort.IsEnabled = false;CloseSerialPort.IsEnabled = true;}catch (Exception ex){MessageBox.Show("串口打开失败" + ex.ToString());//System.Environment.Exit(0);//退出应用程序}
}private void CloseSerialPort_Click(object sender, RoutedEventArgs e)
{try{if (_serialPort.IsOpen == true){_serialPort.Close();OpenSerialPort.IsEnabled = true;CloseSerialPort.IsEnabled = false;}}catch (Exception ex){MessageBox.Show("串口关闭失败" + ex.ToString());System.Environment.Exit(0);//退出应用程序}
}

单片机关键部分代码

/* USER CODE BEGIN Header */
/********************************************************************************* @file    dcmi.c* @brief   This file provides code for the configuration*          of the DCMI instances.******************************************************************************* @attention** Copyright (c) 2022 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "dcmi.h"/* USER CODE BEGIN 0 */
#include <string.h>
#include <stdio.h>__align(32) uint32_t buffer[65535] __attribute((at(0X24040000)));unsigned char getPicture = 0;
unsigned int jpeglen = 0;
//unsigned int recvOk = 0;/* USER CODE END 0 */DCMI_HandleTypeDef hdcmi;
DMA_HandleTypeDef hdma_dcmi_pssi;/* DCMI init function */
void MX_DCMI_Init(void)
{/* USER CODE BEGIN DCMI_Init 0 *//* USER CODE END DCMI_Init 0 *//* USER CODE BEGIN DCMI_Init 1 *//* USER CODE END DCMI_Init 1 */hdcmi.Instance = DCMI;hdcmi.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;hdcmi.Init.PCKPolarity = DCMI_PCKPOLARITY_RISING;hdcmi.Init.VSPolarity = DCMI_VSPOLARITY_LOW;hdcmi.Init.HSPolarity = DCMI_HSPOLARITY_LOW;hdcmi.Init.CaptureRate = DCMI_CR_ALL_FRAME;hdcmi.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;hdcmi.Init.JPEGMode = DCMI_JPEG_ENABLE;hdcmi.Init.ByteSelectMode = DCMI_BSM_ALL;hdcmi.Init.ByteSelectStart = DCMI_OEBS_ODD;hdcmi.Init.LineSelectMode = DCMI_LSM_ALL;hdcmi.Init.LineSelectStart = DCMI_OELS_ODD;if (HAL_DCMI_Init(&hdcmi) != HAL_OK){Error_Handler();}/* USER CODE BEGIN DCMI_Init 2 *///printf("MX_DCMI_Init ok\r\n");/* USER CODE END DCMI_Init 2 */}void HAL_DCMI_MspInit(DCMI_HandleTypeDef* dcmiHandle)
{GPIO_InitTypeDef GPIO_InitStruct = {0};if(dcmiHandle->Instance==DCMI){/* USER CODE BEGIN DCMI_MspInit 0 *///printf("if(dcmiHandle->Instance==DCMI)\r\n");/* USER CODE END DCMI_MspInit 0 *//* DCMI clock enable */__HAL_RCC_DCMI_CLK_ENABLE();__HAL_RCC_GPIOE_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_GPIOD_CLK_ENABLE();/**DCMI GPIO ConfigurationPE4     ------> DCMI_D4PE5     ------> DCMI_D6PE6     ------> DCMI_D7PA4     ------> DCMI_HSYNCPA6     ------> DCMI_PIXCLKPB13     ------> DCMI_D2PA9     ------> DCMI_D0PA10     ------> DCMI_D1PD3     ------> DCMI_D5PB7     ------> DCMI_VSYNCPE1     ------> DCMI_D3*/GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_1;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_6|GPIO_PIN_9|GPIO_PIN_10;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_7;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_3;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);/* DCMI DMA Init *//* DCMI_PSSI Init */hdma_dcmi_pssi.Instance = DMA1_Stream0;hdma_dcmi_pssi.Init.Request = DMA_REQUEST_DCMI_PSSI;hdma_dcmi_pssi.Init.Direction = DMA_PERIPH_TO_MEMORY;hdma_dcmi_pssi.Init.PeriphInc = DMA_PINC_DISABLE;hdma_dcmi_pssi.Init.MemInc = DMA_MINC_ENABLE;hdma_dcmi_pssi.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;hdma_dcmi_pssi.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;hdma_dcmi_pssi.Init.Mode = DMA_NORMAL;hdma_dcmi_pssi.Init.Priority = DMA_PRIORITY_VERY_HIGH;hdma_dcmi_pssi.Init.FIFOMode = DMA_FIFOMODE_ENABLE;hdma_dcmi_pssi.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;hdma_dcmi_pssi.Init.MemBurst = DMA_MBURST_SINGLE;hdma_dcmi_pssi.Init.PeriphBurst = DMA_PBURST_SINGLE;if (HAL_DMA_Init(&hdma_dcmi_pssi) != HAL_OK){Error_Handler();}/* Several peripheral DMA handle pointers point to the same DMA handle.Be aware that there is only one channel to perform all the requested DMAs. */__HAL_LINKDMA(dcmiHandle,DMA_Handle,hdma_dcmi_pssi);/* DCMI interrupt Init */HAL_NVIC_SetPriority(DCMI_PSSI_IRQn, 2, 0);HAL_NVIC_EnableIRQ(DCMI_PSSI_IRQn);/* USER CODE BEGIN DCMI_MspInit 1 */HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,GPIO_PIN_SET);HAL_Delay(100);HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,GPIO_PIN_RESET);//printf("HAL_DCMI_MspInit ok\r\n");/* USER CODE END DCMI_MspInit 1 */}
}void HAL_DCMI_MspDeInit(DCMI_HandleTypeDef* dcmiHandle)
{if(dcmiHandle->Instance==DCMI){/* USER CODE BEGIN DCMI_MspDeInit 0 *//* USER CODE END DCMI_MspDeInit 0 *//* Peripheral clock disable */__HAL_RCC_DCMI_CLK_DISABLE();/**DCMI GPIO ConfigurationPE4     ------> DCMI_D4PE5     ------> DCMI_D6PE6     ------> DCMI_D7PA4     ------> DCMI_HSYNCPA6     ------> DCMI_PIXCLKPB13     ------> DCMI_D2PA9     ------> DCMI_D0PA10     ------> DCMI_D1PD3     ------> DCMI_D5PB7     ------> DCMI_VSYNCPE1     ------> DCMI_D3*/HAL_GPIO_DeInit(GPIOE, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_1);HAL_GPIO_DeInit(GPIOA, GPIO_PIN_4|GPIO_PIN_6|GPIO_PIN_9|GPIO_PIN_10);HAL_GPIO_DeInit(GPIOB, GPIO_PIN_13|GPIO_PIN_7);HAL_GPIO_DeInit(GPIOD, GPIO_PIN_3);/* DCMI DMA DeInit */HAL_DMA_DeInit(dcmiHandle->DMA_Handle);/* DCMI interrupt Deinit */HAL_NVIC_DisableIRQ(DCMI_PSSI_IRQn);/* USER CODE BEGIN DCMI_MspDeInit 1 */HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,GPIO_PIN_SET);HAL_Delay(100);HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,GPIO_PIN_RESET);printf("HAL_DCMI_MspDeInit ok\r\n");/* USER CODE END DCMI_MspDeInit 1 */}
}/* USER CODE BEGIN 1 */void StartOV2640()
{int i =0;__HAL_DCMI_ENABLE_IT(&hdcmi, DCMI_IER_FRAME_IE);                                               	//使用帧中断memset(buffer, 0, 65535);                                        					//把接收BUF清空HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_SNAPSHOT, (uint32_t)buffer, 65535); 	//启动拍照
}void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
{int i =0;HAL_DCMI_Suspend(hdcmi); // 拍照完成,挂起 DCMIHAL_DCMI_Stop(hdcmi);    // 拍照完成,停止 DMA传输int pictureLength = 65535;while (pictureLength > 0)     //循环计算出接收的JPEG的大小{if (buffer[pictureLength - 1] != 0x00000000){break;}pictureLength--;}jpeglen = pictureLength * 4;getPicture = 1;
}
/* USER CODE END 1 */

单片机代码

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2022 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "dcmi.h"
#include "dma.h"
#include "rtc.h"
#include "usart.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include "ov2640.h"
#include "ov5640.h"
#include <string.h>
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */#define OV2640_JPEG_WIDTH	 1600	//JPEG拍照的宽度	
#define OV2640_JPEG_HEIGHT 1200		//JPEG拍照的高度#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
PUTCHAR_PROTOTYPE
{USART1->TDR = ch;while(!(USART1->ISR& USART_ISR_TXE_TXFNF_Msk)) {;}return ch;
}static void CPU_CACHE_Enable(void)
{SCB_EnableICache();//使能I-CacheSCB_EnableDCache();//使能D-Cache   SCB->CACR|=1<<2;   //强制D-Cache透写,如不开启,实际使用中可能遇到各种问题	
}void Send(uint8_t *pData)
{uint32_t i = 0;printf("jpeg data size:%d\r\n",jpeglen);//串口打印JPEG文件大小	HAL_Delay(1000);		for(i = 0;i < jpeglen;i++){//printf("%02x\t",pData[i]);printf("%c",pData[i]);}HAL_Delay(1000);		printf("\r\n");
}/* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 */uint32_t i = 0;uint32_t index = 1;//CPU_CACHE_Enable();/* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit */HAL_Delay(5000);//__enable_irq();/* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_RTC_Init();MX_USART1_UART_Init();MX_USART2_UART_Init();MX_DMA_Init();MX_ADC1_Init();MX_USART3_UART_Init();/* USER CODE BEGIN 2 */HAL_Delay(100);MX_DCMI_Init();HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);HAL_Delay(1000);//	HAL_DCMI_DeInit(&hdcmi);
//  PY_DCMI_Full_Init();/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){printf("OV2640 初始化!cam:%d\r\n",index);while(OV2640_Init(index))			{printf("OV2640 错误!cam:%d\r\n",index);}printf("OV2640 成功!cam:%d\r\n",index);HAL_Delay(1000);if(1){OV2640_JPEG_Mode();	//切换为JPEG模式 printf("切换为JPEG模式 !\r\n");OV2640_OutSize_Set(OV2640_JPEG_WIDTH,OV2640_JPEG_HEIGHT); printf("设置图像大小 !\r\n");SCCB_WR_Reg(0XFF,0X00);SCCB_WR_Reg(0XD3,0X10);SCCB_WR_Reg(0XFF,0X01);SCCB_WR_Reg(0X11,0X8); }if(0){OV2640_RGB565_Mode();			//RGB565模式printf("RGB565模式 !\r\n");OV2640_OutSize_Set(OV2640_JPEG_WIDTH,OV2640_JPEG_HEIGHT); printf("设置图像大小 !\r\n");SCCB_WR_Reg(0XFF,0X00);		SCCB_WR_Reg(0XD3,0X12);	//设置PCLK分频SCCB_WR_Reg(0XFF,0X01);SCCB_WR_Reg(0X11,0X1);	//设置CLK分频	}printf("开始工作\r\n");HAL_Delay(100);//Get_Photo();//DCMI_Start();StartOV2640();HAL_Delay(1000);		while(1){if(getPicture==1){Send((uint8_t *)buffer);break;}else{//printf("adc start\r\n");//GetValue();//printf("adc end\r\n");HAL_Delay(10);HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,GPIO_PIN_SET);HAL_Delay(10);HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,GPIO_PIN_RESET);}	//printf("jpeg haven't finished\r\n");		}	if(index>3){index = 1;}else{index++;}/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Supply configuration update enable*/HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);/** Configure the main internal regulator output voltage*/__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}/** Macro to configure the PLL clock source*/__HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSI);/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;RCC_OscInitStruct.LSIState = RCC_LSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;RCC_OscInitStruct.PLL.PLLM = 4;RCC_OscInitStruct.PLL.PLLN = 35;RCC_OscInitStruct.PLL.PLLP = 2;RCC_OscInitStruct.PLL.PLLQ = 2;RCC_OscInitStruct.PLL.PLLR = 2;RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;RCC_OscInitStruct.PLL.PLLFRACN = 0;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2|RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1;RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK){Error_Handler();}HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI, RCC_MCODIV_8);
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug */printf("Error_Handler\r\n");/* User can add his own implementation to report the HAL error return state */__disable_irq();HAL_Delay(1000);		while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */


http://chatgpt.dhexx.cn/article/Ol1uleG5.shtml

相关文章

STM32——DCMI接口与OV2640原理与配置

一、OV2640简介 1、什么是OV2640&#xff1f; OV2640是OmniVision公司生产的一颗1/4寸的CMOS UXGA&#xff08;1632*1232&#xff09;图像传感器。该传感器体积小、工作电压低&#xff0c;提供单片UXGA摄像头和影像处理器的所有功能。通过SCCB总线控制&#xff0c;可以输出整…

DCMI接口之OV2640摄像头

一、OV2640简介 OV2640是OmniVision公司生产的一颗1/4寸的CMOS UXGA&#xff08;1632 * 1232&#xff09;图像传感器。该传感器体积小、工作电压低&#xff0c;提供单片UXGA摄像头和影像处理器的所有功能。通过SCCB 总线控制&#xff0c;可以输出整帧、子采样、缩放和取窗口等…

OV2640 DCMI

OV2640 简介&#xff1a; 1/4寸CMOSUXGA (1632 * 1232)图像传感器。体积小、工作电压低,提供单片UXGA摄像头和影像处理器的所有功能。通过SCCB总线控制&#xff0c;可以输出整帧、子采样、缩放和取窗口等方式的各种分辨率8/10位影像数据。&#xff08;此处一般选8位&#xff0…

STM32F429之DCMI 数字相机接口

嵌入式系列文章 参考&#xff1a;《STM32F429_DM00031020_ENV19.pdf》 本文目的&#xff1a;翻译STM32F429的PRM&#xff0c;深入理解DCMI接口的工作原理&#xff0c;最后将DCMI工作原理转换成驱动代码。 DCMI&#xff1a;Digital camera interface&#xff0c;数字摄像头接口 …

DCMI接口

目录 DCMI数字摄像头接口 DCMI引脚 摄像头引脚 操作过程与通信方式 硬件连接图 写操作 读操作 图像输出 数据格式 rawRGB YUV RGB JPEG 代码实现过程简述 学习过程的问题 YUV是亮度和色度的格式&#xff0c;为什么UV中取Cb蓝和Cr红作为色度&#xff1f; 提问MIPI、DVP、DCMI是什…

stm32f4的数字摄像头接口(DCMI)使用

DCMI简介 STM32F4的DCMI接口包括如下信号 1&#xff0c;数据据输入&#xff08;D[0:13]&#xff09;&#xff0c;接摄像头的数据输出。 2&#xff0c;水平同步&#xff08;行同步&#xff09;输入&#xff08;HSYNC&#xff09;&#xff0c;接摄像头的HSYNC/HREF信号&#xff…

Java开发技术

1、基础技术 数据结构与算法 逻辑结构&#xff1a;数据对象中的数据元素之间的逻辑关系 1.集合结构&#xff1a;集合结构中的数据元素除了同属一个集合外&#xff0c;没有其他关系。 2.线性结构&#xff1a;线性结构中的数据元素之间是一对一的关系。 3.树形结构&#xff1a;树…

JAVA 中的代码生成包 CGLIB (Code Generation Library)

JAVA 中的代码生成包 CGLIB &#xff08;Code Generation Library&#xff09; CGLIB 是一个功能强大&#xff0c;高性能的代码生成包。它为没有实现接口的类提供代理&#xff0c;为 JDK 的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理&#xff0c;但当要代…

Java开发实战讲解!java开发CPU最低要求

前言 本人是底层 211 本科,刚毕业,⽆科研经历,但是有些项⽬经历。 在国内监控行业某头部企业做过一段时间的实习。 想着投下字节,可以积累⼀下⾯试经验和为金九银十面招做准备。投了简历之后,过了一段时 间,HR 就打电话跟我约时间, 说明一下&#xff0c;我投的是北京 office。…

Java面试题技术类一

前端技术导航大全 1、面向对象编程的三大特性是什么? 2、String 和StringBuffer的区别 3、说出ArrayList,Vector, LinkedList的存储性能和特性 4、Collection 和 Collections的区别 5、HashMap和Hashtable的区别 6、final, finally, finalize的区别 7、Overload和Overri…

Java专项练习(三)

JAVA选择题 401、下列类定义代码&#xff0c;当用来声明对象car&#xff0c;并用Car carnew Car();实例化后&#xff0c;可以通过car对象直接赋值的字段是&#xff08;&#xff09;402、以下哪个不是Collection的子接口&#xff1f;403、下列说法正确的是( )404、下面的程序将来…

Java学习汇总

6/28日已更新&#xff0c;错误已修改~~~有错误的地方&#xff0c;欢迎大家留言&#xff01; 目录 一、Java基础篇 1.接口和抽象类的区别 2.重载和重写的区别 3.和equals的区别 4.异常处理机制 5.HashMap原理 6.想要线程安全的HashMap怎么办&#xff1f; 7.ConcurrentHa…

java面经整理

面试问题 一、Java基础1.jdk1.7到jdk1.8HashMap发生了什么变化&#xff08;底层&#xff09;&#xff1f;2.jdk1.7到jdk1.8虚拟机发生了什么变化3.String、StringBuilder、StringBuffer4.ArrayList和LinkedList有什么区别&#xff1f;5.ConcurrentHashMap的扩容机制6.接口和抽象…

获得阿里Java开发P7岗“农村穷苦”小伙就得安于现状?

前言 相信大家看到这个标题其实就已经可以联想到我大概是个什么样的情况了&#xff0c;很多人都在生活中或者是网络上甚至是家庭中都大致听过这样的话&#xff0c;“你这样的出生&#xff0c;达到现在这样的生活已经很不错了&#xff0c;还是别为了不切实际的梦想去冒险了&…

Java基础 常见数据结构与算法 项目总结

Java基础 1 Java基础必知必会 1.1 Java语言有哪些特点&#xff1f; 面向对象&#xff08;封装&#xff0c;继承&#xff0c;多态&#xff09;&#xff1b;平台无关性&#xff0c;平台无关性的具体表现在于&#xff0c;Java 是“一次编写&#xff0c;到处运行&#xff08;Wri…

Java面试知识点概览(持续更新)

Java 基础 说说自定义注解的场景及实现 利用自定义注解,结合SpringAOP可以完成权限控制、日志记录、统一异常处理、数字签名、数据加解密等功能。 实现场景&#xff08;API接口数据加解密&#xff09; 1&#xff09;自定义一个注解&#xff0c;在需要加解密的方法上添加该注…

java开发工程师面试总结

面试中常被问到的问题 介绍jvmjvm内存模型程序计数器虚拟机栈本地方法栈方法区堆 垃圾回收判断对象是否存活引用计数算法可达性分析算法 垃圾收集算法复制算法标记清除算法&#xff0c;标记整理算法 垃圾收集器新生代收集器SerialParNewParallel Scavenge 老年代收集器Serial O…

Java面试经验总结

目录 Java面试知识点基础常识前端基础知识Java基础知识1、**并行与并发**2、**线程与进程**3、**HashMap和HashTable区别**4、**new对象创建过程原理&#xff08;在JVM&#xff09;,从执行的角度(其他角度待续)**4、**Volatile和Synchronized**5、**线程创建的几种方法**6、**垃…

java怎么写api接口,绝对干货

正文 下文中截图来源于朋友一个pdf版本的面经,把所以知识点的答案整理了下来,耗费他至少1个月时间,在本文最后部分把这个pdf分享给大家,觉得有用的麻烦点赞关注走一波,谢谢!!!面经中有他的知识点的答案,如下图示例,非常详细(文末有领取方式)!!! 1.数据结构与算…

Java开发校招面经

面试 当前面经欠缺&#xff1a;docker&#xff0c;k8s容器&#xff0c;spark&#xff0c;flink&#xff0c;hbase&#xff0c;hive&#xff0c;java网络编程&#xff08;netty&#xff09; 一&#xff0c;JAVA 重写和重载 重写&#xff1a;方法签名要完全相同&#xff08;方…