STM32F407 OV2640 DCMI+DMA RGB565格式的图像上传给上位机,基于正点JPEG程序修改可是有错误,希望论坛里的朋友和原子哥指导一下

2019-07-20 12:18发布

如题,先说说我要完成的功能,就是用OV2640采集图像,然后将图像像素点缩放成200×200,以RGB格式上传给上位机 ,参考实验35 摄像头实验 例程,里面的JPEG格式是用OV2640采集完成后通过串口上传给PC端的,所以就根据这个改本来以为改改 OV2640的输出格式就行了那,结果问题多多啊。 我更改的位置:    可是实际输出的结果却不行,和想象中的完全不一样、 输出的图像  debug的时候发现jepg_data_len的长度是20008,  就算×2也才是40000,可是按照设想,传给上位机的数据长度应该是40000×2=80000 正好是200×200像素点一共200×200×2个字节。 希望原子哥帮帮小弟,我已经调试几天,没有思路了。。@正点原子
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
10条回答
lvehe
1楼-- · 2019-07-20 17:43
 精彩回答 2  元偷偷看……
z755924843
2楼-- · 2019-07-20 20:46
回复【2楼】lvehe:
---------------------------------我是按照索者STM32F4开发板例程代码 库函数实验35 摄像头实验 改的。我只改了以上的部分

#define jpeg_buf_size 200*200 //定义rgb的数据缓存buf
u16 jpeg_buf[jpeg_buf_size]; //rgb数据缓存buf
volatile u32 jpeg_data_len=0;    //buf中的JPEG有效数据长度
volatile u8 jpeg_data_ok=0;    //JPEG数据采集完成标志
          //0,数据没有采集完;
          //1,数据采集完了,但是还没处理;
          //2,数据已经处理完成了,可以开始下一帧接收
//处理JPEG数据
//当采集完一帧JPEG数据后,调用此函数,切换JPEG BUF.开始下一帧采集.
void jpeg_data_process(void)
{
 
  if(jpeg_data_ok==0) //jpeg数据还未采集完?
  { 
   DMA_Cmd(DMA2_Stream1, DISABLE);//停止当前传输
   while (DMA_GetCmdStatus(DMA2_Stream1) != DISABLE){}//等待DMA2_Stream1可配置 
   jpeg_data_len=jpeg_buf_size-DMA_GetCurrDataCounter(DMA2_Stream1);//得到此次数据传输的长度
    
   jpeg_data_ok=1;     //标记JPEG数据采集完按成,等待其他函数处理
  }
  if(jpeg_data_ok==2) //上一次的jpeg数据已经被处理了
  {
   DMA2_Stream1->NDTR=jpeg_buf_size; 
   DMA_SetCurrDataCounter(DMA2_Stream1,jpeg_buf_size);//传输长度为jpeg_buf_size*4字节
   DMA_Cmd(DMA2_Stream1, ENABLE);   //重新传输
   jpeg_data_ok=0;      //标记数据未采集
  }
}
//JPEG测试
//JPEG数据,通过串口2发送给电脑.
void jpeg_test(void)
{
 u32 i;
 u8 *p;
  OV2640_RGB565_Mode();  //RGB模式
 My_DCMI_Init();   //DCMI配置
 DCMI_DMA_Init((u32)&jpeg_buf,jpeg_buf_size,DMA_MemoryDataSize_HalfWord,DMA_MemoryInc_Enable);//DCMI DMA配置  
 OV2640_OutSize_Set(200,200);
 DCMI_Start();   //启动传输
 while(1)
 {
  if(jpeg_data_ok==1) //已经采集完一帧图像了
  { 
   p=(u8*)jpeg_buf;
   for(i=0;i<jpeg_data_len*2;i++)  //dma传输1次等于2字节,所以乘以2.
   {
        while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕    
    USART_SendData(USART2,p);
   }
   while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET);
   USART_SendData(USART2,'J');
    while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET);
   USART_SendData(USART2,'E');
   jpeg_data_ok=2; //标记jpeg数据处理完了,可以让DMA去采集下一帧了.
  }  
 }   
}

int main(void)
{
 u8 key;
 u8 t;
 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
 delay_init(168);  //初始化延时函数
 uart_init(115200);  //初始化串口波特率为115200
 usart2_init(42,115200);  //初始化串口2波特率为115200
 LED_Init();     //初始化LED
  LCD_Init();     //LCD初始化 
  KEY_Init();     //按键初始化
 TIM3_Int_Init(10000-1,8400-1);//10Khz计数,1秒钟中断一次
  usmart_dev.init(84);  //初始化USMART
 while(OV2640_Init())//初始化OV2640
 {
  LCD_ShowString(30,130,240,16,16,"OV2640 ERR");
  delay_ms(200);
     LCD_Fill(30,130,239,170,WHITE);
  delay_ms(200);
 }
 LCD_ShowString(30,130,200,16,16,"OV2640 OK");    
 
 jpeg_test();
 
}
这个就是主程序的代码,代码附件我也一并上传了,麻烦你帮我看看,谢谢了。

lvehe
3楼-- · 2019-07-20 23:31
回复【3楼】z755924843:
---------------------------------
你这个显示RGB565图像的上位机是自己编写的吗?
建议将缓冲区再弄大点,刚好200x200可能少了点。
z755924843
4楼-- · 2019-07-21 01:18
 精彩回答 2  元偷偷看……
正点原子
5楼-- · 2019-07-21 02:52
先显示在lcd看看正常不。
蓝蓝的枫
6楼-- · 2019-07-21 08:06
 精彩回答 2  元偷偷看……

一周热门 更多>