Ableson
发表于: 2020-4-15 17:39:14 | 显示全部楼层

本文章将会介绍一种通过串口显示模组显示摄像头图片的方法。文章中所介绍的方法和代码仅供个人开发者测试使用,无法保证商用的稳定性。

项目的主要功能可以列为以下几个:
1、 显示屏实时显示摄像头采集到的图片
2、 可以点击按钮拍摄一张图片并且保存到TF卡中
3、 切换彩色和灰度
4、 可以切换分辨率(240*320240*240160*16080*80)
5、 可以切换到浏览图片的模式
6、 可以浏览上一张图片
7、 可以浏览下一张图片
在进行这个项目之前我们先来了解一下需要用到哪些硬件模块。
1、 STONE 7英寸800*480分辨率的串口显示模组
2、 STM32F103ZE开发板
3、 OV7670摄像头模组
4、 少量相关线材

跳转到指定楼层
回复

使用道具 举报

Ableson
发表于: 2020-4-15 17:43:15 | 显示全部楼层

我们可以先看看相关硬件模组的图片:

STONE TFT LCD Module


STM32F103ZE开发板

这个开发板有很多集成的功能:
1、 使用Cotex-M3核芯片,STM32F103ZET6,
2、 144P引脚
3、 外部晶振8M,时钟晶振32768Hz
4、 标准20P 插座,JTAG接口,用于Jlink、Ulink、ST-Link等下载调试程序
5、 标准4P插针,SWD接口,使用2线通信方式调试下载程序
6、 所有I/O口引出插针,方便扩展实验
7、 USB-TTL串口转换电路,实现USB接口串口通讯
8、 自动下载适配电路,使用串口下载无需频繁切换,一键下载
9、 MAX232转换电路,适用于外接串口线
10、 一体化红外接收头,用户红外遥控接收功能
11、 DS18B20插座,直接插入芯片即可实现数字测温功能
12、 带时钟后备电池,保持时钟及重要信息掉电不丢失
13、 EEPROM芯片24c02,存储常用用户信息,使用IIC通讯
14、 FLASH芯片W25Q64,8M存储器,可以存储图片、系统数据等多种信息
15、 SPI模式SD卡座,使用TF卡,使用PI通讯
16、 SDIO模式SD卡座,使用TF卡,专用的SDIO接口,高速,稳定。
17、 RF24L01插座,用于测试无线通讯(至少需2台机器配套使用)
18、 3路普通按键输入功能,人机接口
19、 1路唤醒按键,用于从低功耗或者待机模式唤醒
20、 2路用户LED灯,做基本的状态、运行指示
21、 1路USB设备接口,用于调试USB设备功能,如读卡器、usb转串口功能
22、 TFT彩屏液晶接口,包含触摸屏接口,直接插入配套屏幕可使用
23、 摄像头预留接口,配套摄像头模块实现视频演示功能
24、 1路蜂鸣器
25、 1路触摸按键功能
26、 自带自恢复保险丝,保护电脑不受损坏
27、 复位按键
28、 电源指示灯
29、 BOOT启动选择插针
30、 VREF参考电压选择插针
31、 CAN,USB切换插针
32、 3.3V外扩电源插针
33、 5V外扩电源插针
但是实际上,我们只用到了他的摄像头接口和串口。


STONE TFT-LCD显示模组

STONE STVC070WT-01是一款7英寸,分辨率为800*480的显示模组。这个显示模组可以在STONE官网购买,也可以在STONE的网上购物平台链接购买。
STONE STVC070WT-01的通讯方式为UART-RS232UART-TTL。本项目我使用的是UART-TTL通讯方式。
显示模组的开发方式很简单,MCU只需要通过UART发送指令到STONE显示模组控制显示的内容就可以了,同样的原理,当用户触碰STONE显示屏时,显示模组也通过UART把相关的指令发送到MCU,然后MCU再去控制相应的设备(如电机转动,灯的开关等等)。

7 inches STONE STVC070WT-01

厂家提供的物料如下:

主要包装清单:
1、 转接线和转接口
2、 USB-TTL转接板
3、 U盘(内含开发资料)
4、 Micro USB线
5、 USB转换板
6、 STONE STVC070WT-01显示模组
7、 12V电源适配器



STONE显示模组简介

STVC070WT-01是TFT显示器和触摸控制器。它包括处理器,控制程序,驱动程序,闪存,RS232/RS485/TTL端口,触摸屏、电源等,是一个功能强大的显示系统
操作系统简单,可由任意单片机控制。STVC070WT-01可用于执行所有基本功能,如文本显示、图像显示、曲线显示、触摸功能、视音频功能等。
-内置Cortex CPU和驱动
-可用任何单片机来控制
-显示图片/文字/曲线
- 65536彩色TFT显示
-可以触摸操作
- RS232/ RS485/ TTL UART接口和USB端口
-宽电压范围

STVC070WT-01显示模组的控制原理

TFT-LCD模块通过命令与MCU通信(十六进制),然后MCU将会按照接收到的命令工作。

3个步骤就可以完成STONE显示模组的固件开发

使用STONE的TFT-LCD模块只需3个步骤:
1.设计一组人机图片(UI)。
2.UART-TTL直接连接客户的MCU。
3.编写一个简单的程序,由单片机通过命令控制TFT-LCD模块。(十六进制代码)。
TFT液晶模块串口命令帧由5个数据块组成,所有的串口命令或数据都用十六进制格式表示。数据传输在MSB的方式。例如,对于0x1234,首先发送0x12,然后发送0x34。

回复

使用道具 举报

Ableson
发表于: 2020-4-15 17:45:46 | 显示全部楼层

STONE TFT-LCD显示模组的应用场景




STONE显示模组广泛应用于各种工业领域,如:
1、 医疗美容设备
2、 工程机械及车辆设备
3、 电子仪器
4、 工业控制系统
5、 电力行业
6、 民用电子设备
7、 自动化设备
8、 交通。


UI图片设计

用戶通过使用Photoshop或者其他软件设计UI界面
我设计的界面如下:
第一张图片是主界面图片,第二章图片是按钮按下时的效果。


利用TOOL2019软件设生成LCD模组配置文件


点击箭头所指的按钮就可以生成配置文件,然后把配置文件下载到显示模组中就可以显示出我们设计的UI界面了。
这部分的内容和教程我就不详细介绍了,大家可以到STONE官网去下载到很详细的教程。


回复

使用道具 举报

Ableson
发表于: 2020-4-15 17:47:04 | 显示全部楼层

另外还需要设计一张相同的图片作为按钮按下时的效果,只需要把按钮位置的颜色改表以下即可。


接线和焊接

前面的内容我介绍了STONE STVC070WT-01的相关开发操作,后面的内容我将会重点介绍STM32 MCUVO7670摄像头。在此之前,我们先了解一下整个项目的硬件部分如何连接。

STONE触摸显示项目完整的接线示意图

OV7670模块 ---------- STM32开发板
OV_D0~D7  -----------   PC0~7
OV_SCL    ------------  PD3
OV_SDA    ------------  PG13
OV_VSYNC  ------------  PA8
FIFO_RRST -----------   PG14
FIFO_OE   -----------   PG15
FIFO_WRST ------------  PD6
FIFO_WEN  ------------  PB3
FIFO_RCLK ------------  PB4
电源适配器是12V的,它需要给STONE STVC070WT-01显示模组供电同时通过DC-DC降压器把电压降到5伏给MCU模组和OV7670供电。

项目用到的配件

主要配件有:
1、 STM32F103ZE开发板
2、 DC-DC降压模组
3、 UART转接线
由于STONE STVC070WT-01的通讯方式默认是UART-TTL,所以转接线我们就不需要RS232的接口了,把RS232的接口去掉:


焊接

把这些配件焊接在一起,效果如下:
这部分准备就绪以后就可以编写MCU的程序了。

回复

使用道具 举报

Ableson
发表于: 2020-4-15 17:48:06 | 显示全部楼层

OV7670摄像头
OV7670是一个种图象传感器,操作温度是30℃-70℃,模拟电压是2.5-3.0V,感光阵列是640*480,功耗是工作时60mW/15fps;休眠时小于20uA。
体积小,工作电压低,提供单片VGA摄像头和影像处理器的所有功能。通过SCCB总线控制,可以输入整帧、子采样、取窗口等方式的各种分辨率8位影像数据。该产品VGA图像最高达到30帧/秒。用户可以完全控制图像质量、数据格式和传输方式。所有图像处理功能过程包括伽玛曲线、白平衡、饱和度、色度等都可以通过SCCB接口编程。通过减少或消除光学或电子缺陷如固定图案噪声、托尾、浮散等,提高图像质量,得到清晰的稳定的彩色图像。
OV7670 是 OV(OmniVision)公司生产的一颗 1/6 寸的 CMOS VGA 图像传感器。该传感
器体积小、工作电压低,提供单片 VGA 摄像头和影像处理器的所有功能。通过 SCCB 总线控制,可以输出整帧、子采样、取窗口等方式的各种分辨率 8 位影像数据。该产品 VGA 图像最高达到 30 帧/秒。用户可以完全控制图像质量、数据格式和传输方式。所有图像处理功能过程包括伽玛曲线、白平衡、度、色度等都可以通过 SCCB 接口编程。 OmmiVision 图像传感器应用独有的传感器技术,通过减少或消除光学或电子缺陷如固定图案噪声、托尾、浮散等,提高图像质量,得到清晰的稳定的彩色图像。
OV7670 的特点有:
l 高灵敏度、低电压适合嵌入式应用
l 标准的 SCCB 接口,兼容 IIC 接口
l 支持 RawRGB、 RGB(GBR4:2:2, RGB565/RGB555/RGB444), YUV(4:2:2)和 YCbCr
l 支持 VGA、 CIF,和从 CIF 到 40*30 的各种尺寸输出
l 支持自动曝光控制、自动增益控制、自动白平衡、自动消除灯光条纹
l 自动黑电平校准等自动控制功能。同时支持色饱和度、色相、伽马、锐度等设置。
l 支持闪光灯
l 支持图像缩放
OV7670 的功能框图:


OV7670 传感器包括如下一些功能模块。

1. 感光整列(Image Array)
OV7670 总共有 656*488 个像素,其中 640*480 个有效(即有效像素为 30W)。
2. 时序发生器(Video Timing Generator)
时序发生器具有的功能包括:整列控制和帧率发生(7 种不同格式输出)、内部信号发生器535和分布、帧率时序、自动曝光控制、输出外部时序(VSYNC、 HREF/HSYNC 和 PCLK)。
3. 模拟信号处理(Analog Processing)
模拟信号处理所有模拟功能,并包括:自动增益(AGC)和自动白平衡(AWB)。
4. A/D 转换(A/D)
原始的信号经过模拟处理器模块之后 ,分 G 和 BR 两路进入一个 10 位的 A/D 转换器,
A/D 转换器工作在 12M 频率,与像素频率完全同步(转换的频率和帧率有关)。
A/D 范围乘积和 A/D 的范围控制共同设置 A/D 的范围和最大值,允许用户根据应用调整图片的亮度。
接下来我们介绍一下 OV7670 的图像数据输出格式。首先我们简单介绍几个定义:
VGA,即分辨率为 640*480 的输出模式;
QVGA,即分辨率为 320*240 的输出格式,也就是本章我们需要用到的格式;
QQVGA,即分辨率为 160*120 的输出格式;
PCLK,即像素时钟,一个 PCLK 时钟,输出一个像素(或半个像素)。
VSYNC,即帧同步信号。HREF /HSYNC,即行同步信号。
OV7670 的图像数据输出(通过 D[7:0])就是在 PCLK, VSYNC 和 HREF/ HSYNC 的控制下进行的。

回复

使用道具 举报

Ableson
发表于: 2020-4-15 17:49:23 | 显示全部楼层

首先看看行输出时序,如图所示:
从上图可以看出,图像数据在 HREF 为高的时候输出,当 HREF 变高后,每一个 PCLK 时
钟,输出一个字节数据。比如我们采用 VGA 时序, RGB565 格式输出,每 2 个字节组成一个像素的颜色(高字节在前,低字节在后),这样每行输出总共有 640*2 个 PCLK 周期,输出 640*2个字节。
再来看看帧时序( VGA 模式):

上图清楚的表示了 OV7670 在 VGA 模式下的数据输出,注意,图中的 HSYNC 和 HREF
其实是同一个引脚产生的信号,只是在不同场合下面,使用不同的信号方式,我们本章用到的是 HREF。
因为 OV7670 的像素时钟( PCLK)最高可达 24Mhz,我们用 STM32F103ZET6 的 IO 口直接抓取,是非常困难的,也十分占耗 CPU(可以通过降低 PCLK 输出频率,来实现 IO 口抓取,但是不推荐)。

在本项目中,我使用了RGB565模式,拍摄到的图像数据是RGB原始数据,然后通过UART传输到STONE显示模组中。



回复

使用道具 举报

Ableson
发表于: 2020-4-15 17:50:34 | 显示全部楼层

OV7670的驱动程序

  1. u8 OV7670_Init(void)

  2. {

  3. u8 temp;

  4. u16 i=0;



  5.         GPIO_InitTypeDef  GPIO_InitStructure;

  6.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOG, ENABLE);         





  7. GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_8;

  8. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

  9. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  10.         GPIO_Init(GPIOA, &GPIO_InitStructure);






  11.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4;

  12.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  13.         GPIO_Init(GPIOB, &GPIO_InitStructure);

  14.         GPIO_SetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_4);





  15. GPIO_InitStructure.GPIO_Pin  = 0xff;

  16. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

  17.         GPIO_Init(GPIOC, &GPIO_InitStructure);







  18.            GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_6;  

  19. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  20.         GPIO_Init(GPIOD, &GPIO_InitStructure);

  21. GPIO_SetBits(GPIOD,GPIO_Pin_6);



  22.    



  23. GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_14|GPIO_Pin_15;  

  24. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  25.         GPIO_Init(GPIOG, &GPIO_InitStructure);

  26. GPIO_SetBits(GPIOG,GPIO_Pin_14|GPIO_Pin_15);



  27.     GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);        //SWD



  28.         SCCB_Init();                //³õʼ»¯SCCB µÄIO¿Ú                     

  29.         if(SCCB_WR_Reg(0x12,0x80))return 1;        //¸´Î»SCCB          

  30. delay_ms(50);

  31. temp=SCCB_RD_Reg(0x0b);   

  32. if(temp!=0x73)return 2;  

  33.         temp=SCCB_RD_Reg(0x0a);   

  34. if(temp!=0x76)return 2;

  35. //³õʼ»¯ÐòÁР         

  36. for(i=0;i<sizeof(ov7670_init_reg_tbl_RGB565)/sizeof(ov7670_init_reg_tbl_RGB565[0])/2;i++)

  37. {

  38.            SCCB_WR_Reg(ov7670_init_reg_tbl_RGB565[i][0],ov7670_init_reg_tbl_RGB565[i][1]);

  39. delay_ms(2);

  40.         }

  41.            return 0x00; //ok

  42. }



  43. OV7670_CONFIG ov7670_config;



  44. //ÅäÖÃOV7670µÄÊä³ö

  45. void config_ov7670_OutPut(u16 xsta,u16 ysta,u16 width,u16 height,u8 ouput_mode){

  46. int i=0;

  47. ov7670_config.xsta = xsta;

  48. ov7670_config.ysta = ysta;

  49. ov7670_config.width = width;

  50. ov7670_config.height = height;

  51. ov7670_config.mode = ouput_mode;


  52.   

  53. if(ouput_mode){        //²ÊÉ«Êä³ö

  54. for(i=0;i<sizeof(ov7670_init_reg_tbl_YUV)/sizeof(ov7670_init_reg_tbl_YUV[0])/2;i++)

  55. {

  56. SCCB_WR_Reg(ov7670_init_reg_tbl_YUV[i][0],ov7670_init_reg_tbl_YUV[i][1]);

  57. delay_ms(2);

  58. }



  59. }else{        //ºÚ°×Êä³ö

  60. for(i=0;i<sizeof(ov7670_init_reg_tbl_RGB565)/sizeof(ov7670_init_reg_tbl_RGB565[0])/2;i++)

  61. {

  62. SCCB_WR_Reg(ov7670_init_reg_tbl_RGB565[i][0],ov7670_init_reg_tbl_RGB565[i][1]);

  63. delay_ms(2);

  64. }

  65. }

  66. OV7670_Window_Set(176,10,width,height);        //ÉèÖô°¿Ú

  67. LCD_Clear(WHITE);

  68. }

  69. void OV7670_Light_Mode(u8 mode)

  70. {

  71. u8 reg13val=0XE7;

  72. u8 reg01val=0;

  73. u8 reg02val=0;

  74. switch(mode)

  75. {

  76. case 1://sunny

  77. reg13val=0XE5;

  78. reg01val=0X5A;

  79. reg02val=0X5C;

  80. break;

  81. case 2://cloudy

  82. reg13val=0XE5;

  83. reg01val=0X58;

  84. reg02val=0X60;

  85. break;

  86. case 3://office

  87. reg13val=0XE5;

  88. reg01val=0X84;

  89. reg02val=0X4c;

  90. break;

  91. case 4://home

  92. reg13val=0XE5;

  93. reg01val=0X96;

  94. reg02val=0X40;

  95. break;

  96. }

  97. SCCB_WR_Reg(0X13,reg13val);

  98. SCCB_WR_Reg(0X01,reg01val);

  99. SCCB_WR_Reg(0X02,reg02val);

  100. }          

  101. void OV7670_Color_Saturation(u8 sat)

  102. {

  103. u8 reg4f5054val=0X80;

  104. u8 reg52val=0X22;u8 reg53val=0X5E;

  105.         switch(sat)

  106. {

  107. case 0://-2

  108. reg4f5054val=0X40;           

  109. reg52val=0X11;

  110. reg53val=0X2F;                  

  111. break;

  112. case 1://-1

  113. reg4f5054val=0X66;            

  114. reg52val=0X1B;

  115. reg53val=0X4B;          

  116. break;

  117. case 3://1

  118. reg4f5054val=0X99;          

  119. reg52val=0X28;

  120. reg53val=0X71;          

  121. break;

  122. case 4://2

  123. reg4f5054val=0XC0;          

  124. reg52val=0X33;

  125. reg53val=0X8D;          

  126. break;

  127. }

  128. SCCB_WR_Reg(0X4F,reg4f5054val);

  129. SCCB_WR_Reg(0X50,reg4f5054val);         

  130. SCCB_WR_Reg(0X51,0X00);         

  131. SCCB_WR_Reg(0X52,reg52val);         

  132. SCCB_WR_Reg(0X53,reg53val);         

  133. SCCB_WR_Reg(0X54,reg4f5054val);         

  134. SCCB_WR_Reg(0X58,0X9E);         

  135. }

  136. void OV7670_Brightness(u8 bright)

  137. {

  138. u8 reg55val=0X00;//ĬÈϾÍÊÇbright=2

  139.           switch(bright)

  140. {

  141. case 0://-2

  142. reg55val=0XB0;                  

  143. break;

  144. case 1://-1

  145. reg55val=0X98;                  

  146. break;

  147. case 3://1

  148. reg55val=0X18;                  

  149. break;

  150. case 4://2

  151. reg55val=0X30;                  

  152. break;

  153. }

  154. SCCB_WR_Reg(0X55,reg55val);

  155. }

  156. void OV7670_Contrast(u8 contrast)

  157. {

  158. u8 reg56val=0X40;

  159.           switch(contrast)

  160. {

  161. case 0://-2

  162. reg56val=0X30;                  

  163. break;

  164. case 1://-1

  165. reg56val=0X38;                  

  166. break;

  167. case 3://1

  168. reg56val=0X50;                  

  169. break;

  170. case 4://2

  171. reg56val=0X60;                  

  172. break;

  173. }

  174. SCCB_WR_Reg(0X56,reg56val);         

  175. }  

  176. void OV7670_Special_Effects(u8 eft)

  177. {

  178. u8 reg3aval=0X04;//ĬÈÏΪÆÕͨģʽ

  179. u8 reg67val=0XC0;

  180. u8 reg68val=0X80;

  181. switch(eft)

  182. {

  183. case 1:

  184. reg3aval=0X24;

  185. reg67val=0X80;

  186. reg68val=0X80;

  187. break;

  188. case 2:

  189. reg3aval=0X14;

  190. reg67val=0X80;

  191. reg68val=0X80;

  192. break;

  193. case 3:

  194. reg3aval=0X14;

  195. reg67val=0Xc0;

  196. reg68val=0X80;

  197. break;

  198. case 4:

  199. reg3aval=0X14;

  200. reg67val=0X40;

  201. reg68val=0X40;

  202. break;

  203. case 5:

  204. reg3aval=0X14;

  205. reg67val=0X80;

  206. reg68val=0XC0;

  207. break;

  208. case 6:

  209. reg3aval=0X14;

  210. reg67val=0XA0;

  211. reg68val=0X40;

  212. break;         

  213. }

  214. SCCB_WR_Reg(0X3A,reg3aval);

  215. SCCB_WR_Reg(0X68,reg67val);

  216. SCCB_WR_Reg(0X67,reg68val);

  217. }

  218. void OV7670_Window_Set(u16 sx,u16 sy,u16 width,u16 height)

  219. {

  220. u16 endx;

  221. u16 endy;

  222. u8 temp;



  223. endx=(sx+width*2)%784;        //   sx:HSTART endx:HSTOP   

  224.         endy=sy+height*2;        //   sy:VSTRT endy:VSTOP


  225. //ÉèÖÃHREF

  226. temp=SCCB_RD_Reg(0X32);

  227. temp&=0XC0;

  228. temp|=((endx&0X07)<<3)|(sx&0X07);

  229. SCCB_WR_Reg(0X032,temp);

  230. SCCB_WR_Reg(0X17,sx>>3);

  231. SCCB_WR_Reg(0X18,endx>>3);



  232. //ÉèÖÃVREF

  233. temp=SCCB_RD_Reg(0X03);

  234. temp&=0XF0;

  235. temp|=((endy&0X03)<<2)|(sy&0X03);

  236. SCCB_WR_Reg(0X03,temp);

  237. SCCB_WR_Reg(0X19,sy>>2);

  238. SCCB_WR_Reg(0X1A,endy>>2);

  239. }

复制代码


回复

使用道具 举报

Ableson
发表于: 2020-4-15 17:52:41 | 显示全部楼层

TF卡驱动

项目还需要用到一张TF卡来存储拍摄的图片。
由于TF卡驱动程序篇幅过长,在此就不贴出来了。
大家可自行到网络上面搜索相关的代码使用。

STM32F103ZE

网络上有很多关于这颗芯片的资料和开发文档,在此简单介绍这颗芯片。
这个是STM32F103ZE的开发板:


对于这颗芯片我就不做过多介绍了。芯片下载代码是用了J-LINK,如下图:


这是一个简易版本的J-LINK,只支持SWD方式调试和下载,不支持JTAG。但是对于STM32芯片的开发,SWD调试方式已经足够了。

下载代码到STM32芯片

确保J-LINKSTM32F103ZE的接线正确,然后在KEIL开发环境中可以识别到芯片:
点击download按钮就可以把代码下载到芯片中:
STM32控制代码

STONE显示模组的数据接收一次只能接收255字节,而一张RGB565数据的图片大小是240*320*2=153600Byte=153.6KB,所以需要进行分包发送处理。
另外由于串口通讯速率的限制,图片实时刷新的效果并不是很好。本项目串口波特率配置到921600,这也是STONE串口显示模组的最高通讯波特率。
显示屏中的按钮和文本都有对应的地址,在这个项目中,显示屏组件的地址如下:
TAKE PICTRUE BUTTON : 0X002A
COLOR&GRAY BUTTON : 0X002B
CHANGE RATION BUTTON:0X002C
PREV PICTURE BUTTON:0X002D
NEXT PICTURE BUTTON:0X002E
BROWSE BUTTON : 0X002F

回复

使用道具 举报

Ableson
发表于: 2020-4-15 17:55:43 | 显示全部楼层

Main函数代码如下:

回复

使用道具 举报

Ableson
发表于: 2020-4-15 17:56:48 | 显示全部楼层

Main函数代码如下:
  1. #include "led.h"
  2. #include "delay.h"
  3. #include "key.h"
  4. #include "sys.h"
  5. #include "lcd.h"
  6. #include "usart.h"         
  7. #include "string.h"
  8. #include "ov7670.h"
  9. #include "tpad.h"
  10. #include "timer.h"
  11. #include "exti.h"
  12. #include "usmart.h"
  13. #include "dma.h"
  14. #include "sdio_sdcard.h"   

  15. extern u8 ov_sta;       
  16. extern u8 img_dis_cnt;
  17. extern u8 data_ready;       
  18. extern u8 USART_RX_END;
  19. u16 user_width=240;
  20. u16 user_heigh=240;
  21. #define PIC_TOTAL     20
  22. u8 sd_select=1;
  23. u16 color_r;
  24. u16 color_g;
  25. u16 color_b;
  26. void UART1_Send_Array(u8 send_array[],u16 num)
  27. {
  28.         u16 i=0;  
  29.         while(i<num)
  30.         {
  31.                 USART_SendData(USART1,send_array[i]);  
  32.                 while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);  
  33.                 i++;  
  34.         }
  35. }
  36. void ov7670_clock_set(u8 PLL)
  37. {
  38.         u8 temp=0;          
  39.         RCC->CFGR&=0XFFFFFFFC;       
  40.         RCC->CR&=~0x01000000;            
  41.         RCC->CFGR&=~(0XF<<18);       
  42.         PLL-=2;//µÖÏû2¸öµ¥Î»
  43.         RCC->CFGR|=PLL<<18;          
  44.         RCC->CFGR|=1<<16;                  //PLLSRC ON  
  45.         FLASH->ACR|=0x12;          
  46.         RCC->CR|=0x01000000;          //PLLON
  47.         while(!(RCC->CR>>25));       
  48.         RCC->CFGR|=0x02;       
  49.         while(temp!=0x02)     
  50.         {   
  51.                 temp=RCC->CFGR>>2;
  52.                 temp&=0x03;
  53.         }   
  54. }
  55. #define SEND_BUF_SIZE   169
  56. #define LCD_X_H         5
  57. #define LCD_X_L         6
  58. #define LCD_Y_H         7
  59. #define LCD_Y_L         8
  60. u8 lcd_send_buf[SEND_BUF_SIZE]={0xa5,0x5a,0xa6,0x85,0x00,0x00,0x00,0x00,0x00};
  61. u8 lcd_send_buf1[512]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  62. u8 upda_flag=1;
  63. u16 dis_fixel=0;
  64. void camera_refresh()
  65. {
  66.         u16 i=0,j=0,k=0;
  67.         u8 color;
  68.         u8 cnt=9;
  69.         u16 user_x_cnt=0,user_x_start=0,lcd_send_times=0;
  70.        
  71.         u16 user_width1=user_width;
  72.         u16 user_heigh1=user_heigh;
  73.        
  74.         if(user_width1==240)
  75.         {
  76.                 user_x_cnt=2;
  77.                 user_x_start=450;
  78.         }
  79.         else if(user_width1==320)
  80.         {
  81.                 user_x_cnt=3;
  82.                 user_x_start=410;
  83.         }
  84.         else if(user_width1==160)
  85.         {
  86.                 user_x_cnt=1;
  87.                 user_x_start=490;
  88.         }
  89.         else if(user_width1==80)
  90.         {
  91.                 user_x_cnt=0;
  92.                 user_x_start=530;
  93.         }
  94.        
  95.         if(ov_sta==2)
  96.         {
  97.                 OV7670_RRST=0;         
  98.                 OV7670_RCK_L;
  99.                 OV7670_RCK_H;
  100.                 OV7670_RCK_L;
  101.                 OV7670_RRST=1;         
  102.                 OV7670_RCK_H;  
  103.                 upda_flag=0;
  104.                
  105.                 for(i=0;i<user_heigh1;i++)
  106.                 {
  107.                         k=i+150;
  108.                        
  109.                         lcd_send_buf[LCD_Y_L] = (u8)(k & 0x00ff);
  110.                         lcd_send_buf[LCD_Y_H] = (u8)(k >> 8);                
  111.                         cnt=9;
  112.                         lcd_send_times=0;
  113.                         for(j=0;j<user_width1*2;j++)
  114.                         {
  115.                                 OV7670_RCK_L;
  116.                                 color=(u8)GPIOC->IDR&0XFF;
  117.                                 OV7670_RCK_H;
  118.                                 lcd_send_buf[cnt++]=color;
  119.                                 if(cnt > 168)
  120.                                 {
  121.                                   if(lcd_send_times==0)
  122.                                         {
  123.                                                 dis_fixel=user_x_start;
  124.                                                 lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
  125.                                                 lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
  126.                                         }
  127.                                         else if(lcd_send_times==1)
  128.                                         {
  129.                                                 dis_fixel+=80;
  130.                                                 lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
  131.                                                 lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
  132.                                         }
  133.                                         else if(lcd_send_times==2)
  134.                                         {
  135.                                                 dis_fixel+=80;
  136.                                                 lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
  137.                                                 lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
  138.                                         }
  139.                                         else if(lcd_send_times==3)
  140.                                         {
  141.                                                 dis_fixel+=80;
  142.                                                 lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
  143.                                                 lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
  144.                                         }
  145.                                         if(USART_RX_END==1)
  146.                                         {
  147.                                                 EXTI_ClearITPendingBit(EXTI_Line8);  
  148.                                                 ov_sta=0;       
  149.                                                 upda_flag=1;
  150.                                                 return;
  151.                                         }
  152.                                         else
  153.                                         {
  154.                                                 UART1_Send_Array(lcd_send_buf,169);
  155.                                         }
  156.                                         lcd_send_times++;
  157.                                         if(lcd_send_times>user_x_cnt)
  158.                                                 lcd_send_times=0;
  159.                                         cnt=9;
  160.                                 }
  161.                         }
  162.                 }
  163.                 EXTI_ClearITPendingBit(EXTI_Line8);  
  164.                 ov_sta=0;       
  165.                 upda_flag=1;
  166.         }
  167. }       

  168. void clear_display()
  169. {
  170.         u16 i=0,j=0,k=0;
  171.         u8 cnt=9,lcd_send_times=0;
  172.   u8 color;       
  173.         u16 user_x_cnt=0,user_x_start=0;
  174.         u16 user_width1=user_width;
  175.         u16 user_heigh1=user_heigh;
  176.         if(user_width1==240)
  177.         {
  178.                 user_x_cnt=2;
  179.                 user_x_start=450;
  180.         }
  181.         else if(user_width1==320)
  182.         {
  183.                 user_x_cnt=3;
  184.                 user_x_start=410;
  185.         }
  186.         else if(user_width1==160)
  187.         {
  188.                 user_x_cnt=1;
  189.                 user_x_start=490;
  190.         }
  191.         else if(user_width1==80)
  192.         {
  193.                 user_x_cnt=0;
  194.                 user_x_start=530;
  195.         }
  196.                 upda_flag=0;
  197.                 for(i=0;i<user_heigh1;i++)
  198.                 {
  199.                         k=i+150;
  200.                         lcd_send_buf[LCD_Y_L] = (u8)(k & 0x00ff);
  201.                         lcd_send_buf[LCD_Y_H] = (u8)(k >> 8);                
  202.                         cnt=9;
  203.                         lcd_send_times=0;
  204.                         for(j=0;j<user_width1*2;j++)
  205.                         {
  206.                                 OV7670_RCK_L;
  207.                                 color=(u8)GPIOC->IDR&0XFF;
  208.                                 OV7670_RCK_H;
  209.                                 lcd_send_buf[cnt++]=0xff;
  210.                                 if(cnt > 168)
  211.                                 {
  212.                                   if(lcd_send_times==0)
  213.                                         {
  214.                                                 dis_fixel=user_x_start;
  215.                                                 lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
  216.                                                 lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
  217.                                         }
  218.                                         else if(lcd_send_times==1)
  219.                                         {
  220.                                                 dis_fixel+=80;
  221.                                                 lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
  222.                                                 lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
  223.                                         }
  224.                                         else if(lcd_send_times==2)
  225.                                         {
  226.                                                 dis_fixel+=80;
  227.                                                 lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
  228.                                                 lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
  229.                                         }
  230.                                         else if(lcd_send_times==3)
  231.                                         {
  232.                                                 dis_fixel+=80;
  233.                                                 lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
  234.                                                 lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
  235.                                         }
  236.                                         UART1_Send_Array(lcd_send_buf,169);
  237.                                         lcd_send_times++;
  238.                                         if(lcd_send_times>user_x_cnt)
  239.                                                 lcd_send_times=0;
  240.                                         cnt=9;
  241.                                 }
  242.                         }
  243.                 }
  244.                 EXTI_ClearITPendingBit(EXTI_Line8);  
  245.                 ov_sta=0;
  246.                 upda_flag=1;       
  247. }

  248. void user_save_image()
  249. {
  250.         u16 i=0,j=0,k=0;
  251.         u8 color;
  252.         u8 cnt=9,m_cnt=0;
  253.         u16 user_x_cnt=0,user_x_start=0,lcd_send_times=0;
  254.         u16 user_width1=user_width;
  255.         if(user_width1==240)
  256.         {
  257.                 user_x_cnt=2;
  258.                 user_x_start=450;
  259.         }
  260.         else
  261.         {
  262.                 return;
  263.         }
  264.         while(ov_sta!=2);
  265.         if(ov_sta==2)
  266.         {
  267.                 OV7670_RRST=0;         
  268.                 OV7670_RCK_L;
  269.                 OV7670_RCK_H;
  270.                 OV7670_RCK_L;
  271.                 OV7670_RRST=1;
  272.                 OV7670_RCK_H;  
  273.                 upda_flag=0;
  274.                
  275.                 for(i=0;i<240;i++)
  276.                 {
  277.                         k=i+150;
  278.                         lcd_send_buf[LCD_Y_L] = (u8)(k & 0x00ff);
  279.                         lcd_send_buf[LCD_Y_H] = (u8)(k >> 8);                
  280.                         cnt=9;
  281.                         lcd_send_times=0;
  282.                         for(j=0;j<240*2;j++)
  283.                         {
  284.                                 OV7670_RCK_L;
  285.                                 color=(u8)GPIOC->IDR&0XFF;
  286.                                 OV7670_RCK_H;
  287.                                 lcd_send_buf[cnt++]=color;
  288.                                 if(cnt > 168)
  289.                                 {
  290.                                         m_cnt=0;
  291.                                   if(lcd_send_times==0)
  292.                                         {
  293.                                                 dis_fixel=user_x_start;
  294.                                                 lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
  295.                                                 lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
  296.                                                
  297.                                                 for(m_cnt=0;m_cnt<169;m_cnt++)
  298.                                                 {
  299.                                                                 lcd_send_buf1[m_cnt]=lcd_send_buf[m_cnt];
  300.                                                 }
  301.                                         }
  302.                                         else if(lcd_send_times==1)
  303.                                         {
  304.                                                 dis_fixel+=80;
  305.                                                 lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
  306.                                                 lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
  307.                                                 for(m_cnt=0;m_cnt<169;m_cnt++)
  308.                                                 {
  309.                                                                 lcd_send_buf1[m_cnt+169]=lcd_send_buf[m_cnt];
  310.                                                 }
  311.                                         }
  312.                                         else if(lcd_send_times==2)
  313.                                         {
  314.                                                 dis_fixel+=80;
  315.                                                 lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
  316.                                                 lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
  317.                                                 for(m_cnt=0;m_cnt<169;m_cnt++)
  318.                                                 {
  319.                                                                 lcd_send_buf1[m_cnt+169*2]=lcd_send_buf[m_cnt];
  320.                                                 }
  321.                                         }
  322.                                         UART1_Send_Array(lcd_send_buf,169);
  323.                                         lcd_send_times++;
  324.                                         if(lcd_send_times>user_x_cnt)
  325.                                         {
  326.                                                 SD_WriteDisk(lcd_send_buf1,i+240*sd_select,1);
  327.                                                 lcd_send_times=0;
  328.                                         }
  329.                                         cnt=9;
  330.                                 }
  331.                         }
  332.                 }
  333.         }
  334.                 EXTI_ClearITPendingBit(EXTI_Line8);  
  335.                 ov_sta=0;
  336.                 upda_flag=1;
  337. }

  338. void read_image()
  339. {
  340.         u8 i=0;
  341.                 for(i=0;i<240;i++)
  342.                 {
  343.                                         if(SD_ReadDisk(lcd_send_buf1,i+240*sd_select,1)==0)
  344.                                         {
  345.                                                 UART1_Send_Array(lcd_send_buf1,507);
  346.                                         }
  347.                 }
  348. }

  349. int main(void)
  350. {
  351.         u8 pixel_ch_flag=0,user_effect_flag=0;
  352.         delay_init();             
  353.         NVIC_Configuration();        
  354.         uart_init(921600);         
  355.         LED_Init();       
  356.         LCD_Init();       
  357.         delay_ms(1000);
  358.         delay_ms(1000);
  359.                              
  360.         while(OV7670_Init())//³õʼ»¯OV7670
  361.         {
  362.                 delay_ms(200);
  363.         }
  364.         while(SD_Init())
  365.         {
  366.                 delay_ms(500);
  367.                 LED0=!LED0;
  368.         }


复制代码

回复

使用道具 举报

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

本版积分规则

主题 11 | 回复: 23



手机版|

GMT+8, 2024-4-26 02:11 , Processed in 0.052470 second(s), 5 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

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