[STM32F4] 【FreeRTOS+摄像头】在FreeRTOS使用DCMI采集JPEG教程

[复制链接]
9734|92
 楼主| colin2135 发表于 2019-1-8 22:00 | 显示全部楼层 |阅读模式
本帖最后由 colin2135 于 2019-1-8 22:00 编辑

FreeRTOS使用DCMI采集JPEG教程
话不多说,先上代码,地址: FreeRTOS_OV2640.zip (858.26 KB, 下载次数: 399)

在很久很久之前,分享过一次使用STM32F446+OV2640采集JPEG的例子,大家的反响挺不错的。链接在这:https://bbs.21ic.com/icview-1156856-1-1.html

说来惭愧,stm32开发好多年了,一直处于裸奔开发,最近才开始学FreeRTOS,所以把上面的例程移植到了FreeRTOS下面。

主要硬件:
  • NUCLEO-F446RE
  • OV2640

用到了的外设:
  • 硬件的I2C
  • MCO1,输出16M  XCLK给OV2640
  • DCMI   数字图像接口
  • UART  用来和上位机通信
开发软件:TrueSTUDIO 9.1.0

选择好上面的外设后,通过STM32CubeMX生成。



图1 外设配置图

4.png

图2 升级1:画了一块底板

IMG_20171127_211829.jpg

图3 升级2:加上WIFI模块



代码逻辑:

  • 代码开始,先初始化串口和DCMI。
  • 新建2个线程:串口线程、拍照线程;新建2个信号量:开始拍照、拍照完成
  • 串口线程:等待上位机发送拍照信号,收到后释放开始拍照信号量。
  • 拍照线程:等待释放拍照信号量,收到后,触发DCMI函数接收JPEG图像。
  • 当收到DCMI的帧完成中断,释放拍照完成信号量,上传JPEG图像到上位机。

关键代码:
信号量:
  1. osSemaphoreId sem_TakePhoto;//收到开始拍照信号量
  2. osSemaphoreId sem_GetPhoto;//接收拍照完成信号量
串口线程:
  1. void StartUartTask(void const * argument)
  2. {

  3.   /* USER CODE BEGIN 5 */
  4.   /* Infinite loop */
  5.         HAL_UART_Receive_IT(UartHandle, RxTemp, 2);
  6.   for(;;)
  7.   {
  8.     //osDelay(1);
  9.           if (osSemaphoreWait(osSemaphore , osWaitForever) == osOK)
  10.                 {
  11.                   //HAL_UART_Transmit(UartHandle,RxTemp,1,0XFFFFF);
  12.                   if(RxTemp[0] == 'a' && RxTemp[1] == 'a')
  13.                   {
  14.                           //启用拍照,释放拍照的信号量
  15.                           ov2640_realseTakePhotoSem();
  16.                   }
  17.                   memset(RxTemp,0,2);
  18.                         HAL_UART_Receive_IT(UartHandle,RxTemp, 2);
  19.                 }

  20.   }
  21.   /* USER CODE END 5 */
  22. }
拍照线程:
  1. void StartOV2640Task(void const * argument)//拍照的线程
  2. {
  3.         for(;;)
  4.         {
  5.                 if (osSemaphoreWait(sem_TakePhoto , osWaitForever) == osOK)//等待串口释放拍照信号量
  6.                 {
  7.                         __HAL_DCMI_ENABLE_IT(DCMI_hdcmi, DCMI_IT_FRAME);//使用帧中断
  8.                         memset((void *)JpegBuffer,0,sizeof(JpegBuffer));//把接收BUF清空
  9.                         HAL_DCMI_Start_DMA(DCMI_hdcmi, DCMI_MODE_SNAPSHOT,(uint32_t)JpegBuffer, pictureBufferLength);//启动拍照
  10.                         if(osSemaphoreWait(sem_GetPhoto , osWaitForever) == osOK)//等待DCMI释放一帧图像信号量
  11.                         {
  12.                                 HAL_DCMI_Suspend(DCMI_hdcmi);//拍照完成,挂起DCMI
  13.                                 HAL_DCMI_Stop(DCMI_hdcmi);//拍照完成,停止DMA传输
  14.                                 int pictureLength =pictureBufferLength;
  15.                                 while(pictureLength > 0)//循环计算出接收的JPEG的大小
  16.                                 {
  17.                                         if(JpegBuffer[pictureLength-1] != 0x00000000)
  18.                                         {
  19.                                                 break;
  20.                                         }
  21.                                         pictureLength--;
  22.                                 }
  23.                                 pictureLength*=4;//buf是uint32_t,下面发送是uint8_t,所以长度要*4
  24.                                 Uart_Send((uint8_t*)JpegBuffer, pictureLength);
  25.                         }
  26.                 }
  27.         }
  28. }
上位机收到的拍照显示(送给大家个大橙子):
6.png

图4 上位机显示



评论

很好的资源,学习啦~~  发表于 2023-9-17 08:37

评分

参与人数 1威望 +1 收起 理由
g921002 + 1 很给力!

查看全部评分

mmuuss586 发表于 2019-1-8 22:17 | 显示全部楼层

感谢分享
Z赤心木QW 发表于 2019-1-9 10:03 | 显示全部楼层
使用嵌入式系统,对多任务调度非常方便。
磨砂 发表于 2019-2-1 11:27 | 显示全部楼层
绿色的底板是什么型号滴?

评论

绿色底板是自己画的,只用来连接摄像头  发表于 2019-2-1 11:35
磨砂 发表于 2019-2-1 11:41 | 显示全部楼层
@colin2135  好的 看着画的很规矩啊
pinglinmomo 发表于 2019-3-17 01:10 | 显示全部楼层
楼主,你好,之前那个STM32F446+OV2640采集JPEG的百度云链接失效了,请问可不可以重新分享一下,万分感谢!
 楼主| colin2135 发表于 2019-3-17 20:04 | 显示全部楼层
pinglinmomo 发表于 2019-3-17 01:10
楼主,你好,之前那个STM32F446+OV2640采集JPEG的百度云链接失效了,请问可不可以重新分享一下,万分感谢! ...

之前的那份源码有些bug,试一下按着这个源码移植回去吧,顺便练练手。
gygp 发表于 2019-3-18 22:46 | 显示全部楼层
在FreeRTOS支持DCMI?            
chenci2013 发表于 2019-3-18 22:47 | 显示全部楼层
I采集JPEG使用的是什么方式呢?
biechedan 发表于 2019-3-18 22:47 | 显示全部楼层
可以网络传输图片吗?         
wangdezhi 发表于 2019-3-18 22:47 | 显示全部楼层
JPEG的格式是不是压缩了呢?   
isseed 发表于 2019-3-18 22:47 | 显示全部楼层
STM32F446+OV2640            
xietingfeng 发表于 2019-3-18 22:47 | 显示全部楼层
还是使用ov7670的摄像头比较多。     
suzhanhua 发表于 2019-3-18 22:48 | 显示全部楼层
学FreeRTOS非常难吗?            
mituzu 发表于 2019-3-18 22:48 | 显示全部楼层
是楼主自己开发的这个例程吗?
hellosdc 发表于 2019-3-18 22:48 | 显示全部楼层
                          
uiint 发表于 2019-3-18 22:48 | 显示全部楼层
谢谢楼主的分享,后期学习一下。               
 楼主| colin2135 发表于 2019-3-19 10:28 | 显示全部楼层
gygp 发表于 2019-3-18 22:46
在FreeRTOS支持DCMI?

肯定支持啊。
 楼主| colin2135 发表于 2019-3-19 10:28 | 显示全部楼层
mituzu 发表于 2019-3-18 22:48
是楼主自己开发的这个例程吗?

是啊
 楼主| colin2135 发表于 2019-3-19 10:29 | 显示全部楼层
wangdezhi 发表于 2019-3-18 22:47
JPEG的格式是不是压缩了呢?

是啊,2640自带JPEG压缩。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

144

主题

533

帖子

8

粉丝
快速回复 在线客服 返回列表 返回顶部