您的位置:控制工程论坛网论坛 » 嵌入式系统 » 分享个用STM32F429做的网络摄像头

openmcu889

openmcu889   |   当前状态:在线

总积分:91  2024年可用积分:0

注册时间: 2016-12-01

最后登录时间: 2017-01-12

空间 发短消息加为好友

分享个用STM32F429做的网络摄像头

openmcu889  发表于 2016/12/14 16:49:33      1969 查看 3 回复  [上一主题]  [下一主题]

手机阅读

先来看看硬件资源:   
      主控是STM32F429IG,1MB flash,256KB RAM;外扩32MB SDRAM,用于暂存camera 输出的JPEG数据和LCD显存,摄像头这块使用DCMI传输数据。

简单实现原理:
      以太网使用lwip,netconn API编程,这种编程方式相比RAW 比较简单,只是需要OS的支持;然后,板子当服务器,PC当客户端,当建立连接后,服务器将采集到的摄像头数据发送到客户端显示。

关键代码:

    系统(ucos_ii)中建立了两个任务,task1用来处理服务器的一些周期性任务,task2用来发送JPEG数据流。

/**
* @brief  TCP服务器任务
* @param  
* @retval None
*/
void TCP_Server_task(void *arg)
{
       err_t err=0;
       err_t recv_err;
       struct netconn *server_coon; //服务器连接

       struct netbuf *recvbuf;             //接收数据netbuf指针        
       struct pbuf *bufptr;         //pbuf数据缓冲区指针
       
       server_coon = netconn_new(NETCONN_TCP);                 //创建一个TCP链接
       netconn_bind(server_coon,IP_ADDR_ANY,TCP_SERVER_PORT);  //绑定端口 
       netconn_listen(server_coon);                            //进入监听模式
       server_coon->recv_timeout = 10;                         //禁止阻塞线程 等待10ms
        
       while (1)   
       {
                 err = netconn_accept(server_coon,&client_conn);        //接收连接请求
                 //printf("\r\nerr=0x%x\r\n",err);
               if (err == ERR_OK)                                     //正确说明有客户端联入
                 {                                                 
                         while(1)
                               {                                
                                       if((recv_err = netconn_recv(client_conn,&recvbuf)) == ERR_OK)          //接收到数据且正确
                                       {                
                                               bufptr=recvbuf->p;                                  //得到数据指针
                                               memcpy(Data_buff,bufptr->payload,bufptr->tot_len);  //拷贝数据                                       
                                               Data_buff[bufptr->tot_len]='\0';                        //加入结束符
                                               
                                               if(!memcmp(Data_buff,Video_Start,9))               //开始采集
                                               {                     
                                                       Video_flag=1;                                   //标志位值1
                                                       CamFrame=0;                                   //帧率清零
                                                       cam_start();                                   //开始采集
                                                       RTC_ITConfig(RTC_IT_WUT,ENABLE);
                                               }
                                               else if(!memcmp(Data_buff,Video_Stop,8))            //关闭采集
                                               {                     
                                                       Video_flag=0;                                     //标志位值0,自动采集完最后一帧,自动停止
                                                       RTC_ITConfig(RTC_IT_WUT,DISABLE);
                                               }
                                               
                                               netbuf_delete(recvbuf);                             //清除缓冲netbuf
                                       }
                                       else if(recv_err == ERR_CLSD)       //关闭连接
                                       {
                                               netconn_close(client_conn);     //关闭连接
                                               netconn_delete(client_conn);    //删除连接
                                               break;
                                       }
                               }
                               
                 }
       }
}

/*********************分割线*************************/

/**
* @brief  发送数据任务
* @param  
* @retval None
*/
void CAM_Send_task(void *arg)
{                 
       u16  len,i,temp;
       u8  *ptr;
       u8   flag; 
       
       while(1)
       {                                

               if(Buf_DoutPtr!=Buf_DinPtr)
               {
                       len=(*Buf_DoutPtr);                        
                       ptr=(u8 *)(Buf_DoutPtr+1);                  //指向CAMbuf
                       flag=0;
                       
                       for(i=0;i<len;i++)
                       {
                               if((ptr==0xFF)&&(ptr[i+1]==0xD9))      //找数据尾
                               {
                                       ptr[i+2]='\r';
                                       ptr[i+3]='\n';
                                       temp=i+4;                               //有效数据长度
                                       flag=1;
                                       break;
                               }
                       }
                       if(flag)
                       {        
                               netconn_write(client_conn ,ptr,temp,NETCONN_COPY);  //发送数据
                               CamFrame++;                                       //帧率+1
                       }
                       
                         Buf_DoutPtr+=BUFF_SIZE;                        
                         if(Buf_DoutPtr==Buf_EndPtr)  Buf_DoutPtr=Buf_StartPtr;  //到最后一个了
                                                         //回到开头                        
           }

               OSTimeDly(1);
       }
}
现象:

如果关注的人多的话,我就收拾收拾上位机的代码,发给你们玩玩[PS:用的是labview,其实也没什么好玩的]。

【】红龙429_网络摄像头TCP.rar


1楼 3 0 回复
总共 , 当前 /