OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 11645|回复: 12

stm32f103+ov7670+串口传输rgb565图片到PC端并显示

[复制链接]

1

主题

3

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2019-5-6
在线时间
3 小时
发表于 2019-5-7 23:50:08 | 显示全部楼层 |阅读模式
最近因为课设的缘故在做这一块,参考了很多资料后总算调试成功了,所以分享出来,有需要的朋友可以参考一下。camara_refresh函数实现在TFTLCD显示,sendpicture函数实现传输图片数据,用按键实现两者的转换。PC端用串口助手接收数据并保存为txt文件,在matlab上实现将数据转化为图片。程序基本跟正点原子的代码一样,因为TFTLCD显示屏不同,所以TFT显示函数略有区别。ov7670寄存器是参考网上的RGB565格式的配置。先看下代码:
ov7670采集图片并在TFTLCD显示:
void camera_refresh(void)
{
        u32 j;
        u16 color;
        u16 temp;

        u16 count=0;
        if(ov_sta==2)
        {
                LCD_Set_Window(0,(tftlcd_data.height-240)/2,240-1,240-1);
               
                OV7670_RRST=0;                                 
                OV7670_RCK_L;
                OV7670_RCK_H;
                OV7670_RCK_L;
                OV7670_RRST=1;                               
                OV7670_RCK_H;
                for(j=0;j<57600;j++)   
                {
                         OV7670_RCK_L;
                         color=GPIOF->IDR&0XFF;       
                         OV7670_RCK_H;
                         color<<=8;  
                         OV7670_RCK_L;
                         color|=GPIOF->IDR&0XFF;       
                         OV7670_RCK_H;
                         LCD_WriteData_Color(color);
                }               
    EXTI_ClearITPendingBit(EXTI_Line7);               
                ov_sta=0;                                       
        }
}

ov7670采集图片并用串口发送到PC:
void sendpicture(void)
{
        u16 m;
        u16 n;
        u16 color;
        u16 count=0;
        if(ov_sta==2)
        {
                LCD_Set_Window(0,(tftlcd_data.height-240)/2,240-1,240-1);
               
                OV7670_RRST=0;                               
                OV7670_RCK_L;
                OV7670_RCK_H;
                OV7670_RCK_L;
                OV7670_RRST=1;                       
                OV7670_RCK_H;
          for(m=0;m<240;m++)   
         {
                 for(n=0;n<240;n++)
                 {
                         OV7670_RCK_L;
                         color=GPIOF->IDR&0XFF;       
                         while((USART1->SR&0X40)==0);  
                         USART1->DR = color;
                         OV7670_RCK_H;
                         color<<=8;  
                         OV7670_RCK_L;
                         color|=GPIOF->IDR&0XFF;       
                         while((USART1->SR&0X40)==0);
                         USART1->DR = color;               
                         OV7670_RCK_H;
                 }
         }
   EXTI_ClearITPendingBit(EXTI_Line7);               
         ov_sta=0;       
  }
}

主函数:
int main()
{
        u8 temp = 3;
        u8 key;       
        SysTick_Init(72);
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        LED_Init();
        KEY_Init();
        USART1_Init(115200);
        TFTLCD_Init();
        while(OV7670_Init())
        {
                LCD_ShowString(10,80,tftlcd_data.width,tftlcd_data.height,16,"OV7670 Error!");
                delay_ms(200);
                LCD_Fill(10,80,239,206,WHITE);
                delay_ms(200);
        }
        LCD_ShowString(10,80,tftlcd_data.width,tftlcd_data.height,16,"OV7670 OK!     ");
        delay_ms(1500);
        EXTI7_Init();
        OV7670_Window_Set(12,174,240,240);               
        OV7670_CS=0;       
        LCD_Clear(BLACK);
        while(1)
        {               
                key=KEY_Scan(0);
                if(key == KEY_UP)
          {
                  sendpicture();
          }else
                {
                  camera_refresh();
                }
        }
}

用串口调试助手时,要先勾选DTR,选择正确的波特率,然后勾选Hex显示。此时接收窗口可能有几个数据出现,记得要先清理掉。按下按键Key_up,开始接收数据。注意观察接收的数据总数是否等于所设置图片的“宽×高×2”。在我的调试过程中,一开始我没有将TFTLCD的显示和数据的传输分开,导致串口传输的数据一直为重复的几个序列,而且传输速率很慢,LCD显示也比较慢。将两个部分分开并用按键来做功能的切换后取得了较好的成效。比较麻烦的是我没有自己编写一个上位机来接收串口数据并转化为图片,所以只能用笨方法来保存数据并用matlab来实现转化。matlab程序是参考别人的代码,直接拿过来用就可以了,运行时间也不慢。总体来说,用串口来实现图像的传输,只要你不对分辨率有太高的要求,还是可行的。
matlab程序:
length=240;width=240;//由前面设置的图片分辨率决定
in_name='ov7670.txt';
out_name='ov7670.bmp';
pic=uint8(zeros(length,width,3));

in=textread(in_name,'%s');
dec_data=hex2dec(in);
% dlmwrite('dec.txt',dec_data,'','');
% dec_test=dec_data(1:320);
k=1;
for i=1:length
for j=1:width
  H=dec_data(k,1);
  if(k+1>width*length*2)
   k=k-1;
  else
   k=k;
  end
  L=dec_data(k+1,1);
  k=k+2;
  pic(i,j,1)=(H/8)*8;%前一字节的前五位为R
  pic(i,j,2)=(mod(H,8)*8+L/32)*4;%前一字节的后三位和后一字节的前三位为G
  pic(i,j,3)=(mod(L,32))*8;%后一字节的后五位为B
end
end
figure,imshow(pic);
imwrite(pic,out_name);

效果图就放一张240*240的好了,有点糊。。。

路飞.jpg
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

168

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
214
金钱
214
注册时间
2019-4-28
在线时间
5 小时
发表于 2019-5-8 11:33:44 | 显示全部楼层
回复 支持 反对

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2019-4-22
在线时间
10 小时
发表于 2019-5-11 09:17:39 | 显示全部楼层
楼主你好,我看你的数据发送只通过while((USART1->SR&0X40)==0);来判断是否发送完毕,这样串口接收助手上显示收到的程序时,不会出现数据丢失的情况吗?
    我在发送每个字节,并使用while循环,还要之后加入延时函数才能确保,串口接收助手上显示字节数目正确,不知道是发送出现丢失,还是接收端接受不及时。
     如果不加入延时函数就会出现,串口调试助手上显示接收字符个数不正确
     我采用波特率是115200
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
11
金钱
11
注册时间
2019-4-11
在线时间
1 小时
发表于 2019-5-17 21:41:50 | 显示全部楼层
能给我发一下工程吗?有偿
回复 支持 反对

使用道具 举报

1

主题

3

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2019-5-6
在线时间
3 小时
 楼主| 发表于 2019-5-23 12:42:27 来自手机 | 显示全部楼层
15级的许同学 发表于 2019-5-11 09:17
楼主你好,我看你的数据发送只通过while((USART1->SR&0X40)==0);来判断是否发送完毕,这样串口接收助手上显 ...

我在串口调试助手上显示的接收数据正常,并未出现数据出错或者丢失的现象
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
4
金钱
4
注册时间
2019-5-13
在线时间
1 小时
发表于 2019-6-2 14:55:21 | 显示全部楼层
有源码吗?
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2019-7-8
在线时间
10 小时
发表于 2020-3-19 15:52:50 | 显示全部楼层
楼主,PC端保存的数据,是程序书写要求的,还是你的PC端串口的功能啊
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2020-2-14
在线时间
5 小时
发表于 2020-4-26 20:59:26 | 显示全部楼层
能给我发下工程嘛  我出500块
回复 支持 反对

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2019-8-10
在线时间
6 小时
发表于 2020-5-6 15:37:51 | 显示全部楼层
谢谢大神分享 做出来了
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
266
金钱
266
注册时间
2017-12-25
在线时间
62 小时
发表于 2020-5-16 15:57:34 | 显示全部楼层
ljc565065205 发表于 2020-5-6 15:37
谢谢大神分享 做出来了

大佬分享一下~
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
4
金钱
4
注册时间
2023-2-25
在线时间
0 小时
发表于 2023-2-25 20:33:09 | 显示全部楼层
学习学习
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2023-7-13
在线时间
2 小时
发表于 2023-12-3 15:20:12 | 显示全部楼层
mark一下
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
6
金钱
6
注册时间
2024-3-14
在线时间
1 小时
发表于 2024-3-15 00:11:37 | 显示全部楼层
大佬可以私我一下源码吗?723524142@qq.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 22:56

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表