This article will introduce the ov7670 camera module connection with the STONE display module. displaying camera images through a serial display module. The methods and code described in this article are for individual developer testing only and cannot guarantee commercial stability.
ov7670 camera module connection with the STONE display module, the main function
- The display screen displays the pictures collected by the camera in real-time
- Click the button to shoot an image and save it to the TF card
- Switch colors and grayscale
- Resolution can be switched (240*320, 240*240, 160*160, 80*80)
- You can switch to the mode of viewing pictures
- You can browse the last picture
- You can browse to the next picture
Before proceeding with this project, let’s take a look at what hardware modules are needed.
- STONE 7-inch 800*480 resolution serial display module
- STM32F103ZE development board
- OV7670 camera module
- A small amount of relevant wire
STM32F103ZE development board
This development board has a number of integrated features
- Cortex-m3 core chip, STM32F103ZET6,
- 144P pin
- External crystal oscillator 8M, clock crystal oscillator 32768Hz
- Standard 20P socket, JTAG interface, used for downloading debugging programs such as Jlink, Ulink and st-link
- Standard 4P pin insertion, SWD interface, use 2-wire communication to debug and download the program
- All I/O ports are used to insert needles for convenient experiment expansion
- USB-TTL serial port conversion circuit, realizing serial port communication of USB interface
- automatic download adaptor circuit, use serial port download without frequent switching, a key to download
- MAX232 conversion circuit, suitable for external serial line
- Integrated infrared receiver, user remote infrared receiving function
- DS18B20 socket, directly inserted into the chip to achieve digital temperature measurement function
- with clock backup battery, keep the clock and important information not lost power
- EEPROM chip 24c02 to store common user information and use IIC for communication
- FLASH chip W25Q64,8M memory, can store pictures, system data, and other information
- SPI mode SD card holder, TF card, PI communication
- SDIO mode SD card holder, TF card, dedicated SDIO interface, high speed, stable.
- RF24L01 socket for testing wireless communication (at least 2 machines are required)
- 3-way normal key input function, man-machine interface
- 1 way wake up button, used to wake up from low power consumption or standby mode
- LED lamp of the 2-way user, making basic state and operation instructions
- 1 USB device interface, used for debugging USB device functions, such as card reader, USB serial port functions
- TFT color screen LCD interface, including touch screen interface, can be directly inserted into the supporting screen
- Camera reserved interface, supporting camera module to achieve video presentation function
- No. 1 buzzer
- 1 touch button function
- self-recovery fuse to protect the computer from damage
- Reset button
- Power indicator
- Choose to insert the pin
- Select the pin with VREF reference voltage
- CAN, USB switch pin
- 3.3v outboard power supply pin insertion
- 5V external expansion power supply pin insertion
But in fact, we only use his camera interface and serial port, and TF card interface
STONE TFT-LCD Display module
STONE STVC070WT-01 is a 7-inch display module with a resolution of 800*480. This display module can be purchased from STONE’s official website or from STONE’s online shopping platform link.
The communication mode of STONE stvc070wt-01 is uart-rs232 and uart-ttl.In this project, I used uart-TTL communication mode.
Display module development way is simple, the MCU only need through UART send an instruction to the STONE, the contents of the display module, control is ok, the same principle when a user touches the STONE display screen, display module and related instructions sent to MCU through UART, and then MCU to control the corresponding devices (such as motor rotation, light switch, etc.).
7 inches STONE STVC070WT-01
The materials provided by the manufacturer are as follows:
Main packing list
- Transfer connection and connection
- USB-TTL adapter board
- USB flash drive (including development materials)
- Micro USB cable
- USB transfer board
- STONE STVC070WT-01 display module
- 12V power adapter
STONE Display module profile
STVC070WT-01 is a TFT display and touch controller. It includes a processor, control program, driver, flash, RS232/RS485/TTL port, touch screen, power supply, etc., is a powerful display system
The operating system is simple and can be controlled by any single-chip microcomputer.STVC070WT-01 can be used to perform all basic functions, such as text display, image display, curve display, touch function, video and audio function, etc.
- built-in Cortex CPU and drivers
- can be controlled by any single-chip microcomputer
- display pictures/text/curves
- 65536 color TFT display
- – can be touched
- RS232/ RS485/ TTL UART interface and USB port
- wide voltage range
STVC070WT-01 Display module control principle
The TFT-LCD module communicates with the MCU by the command (hexadecimal), and the MCU will work according to the command it receives.
Three steps are required to complete the firmware development of the STONE display module
Using STONE’s TFT-LCD module requires only 3 steps:
- Design a set of man-machine pictures (UI).
- UART-TTL directly connects to the customer’s MCU.
- Write a simple program, by the MCU through the command control TFT-LCD module. (hexadecimal code).
The serial command frame of the TFT LCD module consists of five data blocks, all of which are represented in hexadecimal format. The way data is transferred to MSB.For example, for 0x1234, 0x12 is sent first, and then 0x34 is sent.
UI picture design
The user designs the UI using Photoshop or other software
The interface I designed is as follows:
The first picture is the main screen picture, and the second picture is the effect when the button is pressed.
Use the TOOL2019 software set to generate the LCD module configuration file
Click the arrow button to generate the configuration file, and then download the configuration file to the display module to display the UI interface we designed.
I won’t go into the details of this part of the content and tutorial, you can go to the STONE website to download a very detailed tutorial.
In addition, we also need to design an identical picture as the effect when the button is pressed. We just need to change the color of the button position to the following table.
STM32 MCU and VO7670 Wiring and welding
In the previous content, I introduced the relevant development operation of STONE STVC070WT-01. In the following content, I will focus on the STM32 MCU and the VO7670 camera. Before we do that, let’s take a look at how the hardware part of the project connects.
A complete wiring diagram for the STONE project
OV7670 module — STM32 development board:
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
The power adapter is 12V and needs to power the STONE stvc070wt-01 display module and power the MCU module and OV7670 through the dc-dc step-down to 5 volts.
Accessories used in the project
The main accessories are:
- STM32F103ZE development board
- Dc-dc step-down module
- UART switching
Since the default communication mode of STONE STVC070WT-01 is uart-TTL, we do not need the interface of RS232 for switching connection, and remove the interface of RS232:
Welding
By welding these parts together, the effect is as follows:
When this part is ready, you can write the program for the MCU.
OV7670 camera module
Functional block diagram of OV7670
OV7670 is a kind of image sensor, the operating temperature is -30℃-70℃, the analog voltage is 2.5-3.0v, the photosensitive array is 640*480, and the power consumption is 60mW/15fps.Less than 20uA in dormancy.
Small size, low operating voltage, providing all the features of a single VGA camera and image processor. Through SCCB bus control, you can input the whole frame, sub-sampling, window, and other ways of various resolution 8-bit image data. The product’s VGA image reaches a maximum of 30 frames per second. Users have complete control over image quality, data format, and transmission. All image processing functions including gamma curve, white balance, saturation, chroma, etc. can be programmed through the SCCB interface. By reducing or eliminating optical or electronic defects such as fixed pattern noise, tail support, floating, and so on, image quality can be improved to obtain clear and stable color images.
OV7670 is a 1/6-inch CMOS VGA image sensor produced by OV (OmniVision).The sensing
The device is small in size, low in working voltage, and provides all the functions of a single VGA camera and image processor. Through SCCB bus control, you can output the whole frame, sub-sampling, window, and other ways of various resolution 8-bit image data. The product’s VGA image reaches a maximum of 30 frames per second. Users have complete control over image quality, data format, and transmission. All image processing processes including gamma curve, white balance, degree, color, etc. can be programmed through the SCCB interface.OmniVision image sensor USES unique sensor technology to improve the image quality by reducing or eliminating optical or electronic defects such as fixed pattern noise, tail support, floating, etc., to obtain clear and stable color images.
Features of OV7670 include:
- High sensitivity, low voltage suitable for embedded applications
- Standard SCCB interface, compatible with IIC interface
- Support RawRGB, RGB(gbr4:2:2, RGB565/RGB555/RGB444), YUV(4:2:2) and YCbCr
- Supports VGA, CIF, and all sizes from CIF to 40*30
- Support automatic exposure control, automatic gain control, automatic white balance and automatic elimination of light streaks
- Automatic black level calibration and other automatic control functions. At the same time support color saturation, hue, gamma, sharpness, and other Settings.
- Flash support
- Supports image scaling
The OV7670 sensor includes the following functional modules.
1. Image Array
OV7670 has a total of 656*488 pixels, of which 640*480 are valid (i.e., effective pixels are 30W).
2. Video Timing Generator
The sequence generator has the following functions: whole sequence control and frame rate generation (output in 7 different formats), internal signal generator 535 and distribution, frame rate timing, automatic exposure control, and output of external timing (VSYNC, HREF/HSYNC, and PCLK).
3. Analog signal Processing
Analog signal processing all analog functions and includes automatic gain (AGC) and automatic white balance (AWB).
4. A/D conversion (A/D)
After the original signal passes through the analog processor module, it enters A 10-bit A/D converter via G and BR channels.
The A/D converter operates at an A frequency of 12M, fully synchronized with the pixel frequency (the conversion frequency is related to the frame rate).
The A/D range product and A/D range control jointly set the A/D range and maximum, allowing the user to adjust the brightness of the image based on the application.
Next, let’s introduce the image data output format of OV7670. First, let’s briefly introduce some definitions:
VGA, that is, the output mode with a resolution of 640*480;
QVGA, the output format with a resolution of 320*240, is the format we need in this chapter.
QQVGA, that is, the output format with a resolution of 160*120;
PCLK, or pixel clock, a PCLK clock, outputs one pixel (or half a pixel).
VSYNC, the frame synchronization signal.HREF /HSYNC, the line synchronization signal.
OV7670’s image data output (via D[7:0]) is controlled in PCLK, VSYNC, and HREF/ HSYNC
Below. First, take a look at the timing of the row output, as shown in the figure:
As can be seen from the figure above, the image data is output when the HREF is high, and when the HREF is high when each PCLK
Clock, output a byte of data. For example, we use VGA timing, RGB565 format output, every 2 bytes constitute a pixel color (high bytes before, low bytes after) so that the output of each line has a total of 640*2 PCLK cycles, the output of 640*2 bytes.
Frame timing (VGA mode) :
The figure above clearly shows the data output of OV7670 in VGA mode. Note the HSYNC and HREF in the figure
It’s actually a signal from the same pin, but in different ways under different situations, we’re using HREF in this chapter.
Since the pixel clock (PCLK) of OV7670 can reach up to 24Mhz, we use the IO port of STM32F103ZET6 to directly grasp, which is very difficult and takes up a lot of CPU (IO port can be captured by reducing the output frequency of PCLK, but it is not recommended).
In this project, I used RGB565 mode, and the image data captured was the original data of RGB, which was then transferred to the STONE display module through UART.
The driver code for the OV7670 camera module
u8 OV7670_Init(void)
{
u8 temp;
u16 i=0;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOG, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_4);
GPIO_InitStructure.GPIO_Pin = 0xff;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_SetBits(GPIOD,GPIO_Pin_6);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOG, &GPIO_InitStructure);
GPIO_SetBits(GPIOG,GPIO_Pin_14|GPIO_Pin_15);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); //SWD
SCCB_Init(); //³õʼ»¯SCCB µÄIO¿Ú
if(SCCB_WR_Reg(0x12,0x80))return 1; //¸´Î»SCCB
delay_ms(50);
temp=SCCB_RD_Reg(0x0b);
if(temp!=0x73)return 2;
temp=SCCB_RD_Reg(0x0a);
if(temp!=0x76)return 2;
//³õʼ»¯ÐòÁÐ
for(i=0;i<sizeof(ov7670_init_reg_tbl_rgb565) sizeof=""></sizeof(ov7670_init_reg_tbl_rgb565)>
{
SCCB_WR_Reg(ov7670_init_reg_tbl_RGB565[i][0],ov7670_init_reg_tbl_RGB565[i][1]);
delay_ms(2);
}
return 0x00; //ok
}
OV7670_CONFIG ov7670_config;
//ÅäÖÃOV7670µÄÊä³ö
void config_ov7670_OutPut(u16 xsta,u16 ysta,u16 width,u16 height,u8 ouput_mode){
int i=0;
ov7670_config.xsta = xsta;
ov7670_config.ysta = ysta;
ov7670_config.width = width;
ov7670_config.height = height;
ov7670_config.mode = ouput_mode;
if(ouput_mode){ //²ÊÉ«Êä³ö
for(i=0;i<sizeof(ov7670_init_reg_tbl_yuv) sizeof=""></sizeof(ov7670_init_reg_tbl_yuv)>
{
SCCB_WR_Reg(ov7670_init_reg_tbl_YUV[i][0],ov7670_init_reg_tbl_YUV[i][1]);
delay_ms(2);
}
}else{ //ºÚ°×Êä³ö
for(i=0;i<sizeof(ov7670_init_reg_tbl_rgb565) sizeof=""></sizeof(ov7670_init_reg_tbl_rgb565)>
{
SCCB_WR_Reg(ov7670_init_reg_tbl_RGB565[i][0],ov7670_init_reg_tbl_RGB565[i][1]);
delay_ms(2);
}
}
OV7670_Window_Set(176,10,width,height); //ÉèÖô°¿Ú
LCD_Clear(WHITE);
}
void OV7670_Light_Mode(u8 mode)
{
u8 reg13val=0XE7;
u8 reg01val=0;
u8 reg02val=0;
switch(mode)
{
case 1://sunny
reg13val=0XE5;
reg01val=0X5A;
reg02val=0X5C;
break;
case 2://cloudy
reg13val=0XE5;
reg01val=0X58;
reg02val=0X60;
break;
case 3://office
reg13val=0XE5;
reg01val=0X84;
reg02val=0X4c;
break;
case 4://home
reg13val=0XE5;
reg01val=0X96;
reg02val=0X40;
break;
}
SCCB_WR_Reg(0X13,reg13val);
SCCB_WR_Reg(0X01,reg01val);
SCCB_WR_Reg(0X02,reg02val);
}
void OV7670_Color_Saturation(u8 sat)
{
u8 reg4f5054val=0X80;
u8 reg52val=0X22;u8 reg53val=0X5E;
switch(sat)
{
case 0://-2
reg4f5054val=0X40;
reg52val=0X11;
reg53val=0X2F;
break;
case 1://-1
reg4f5054val=0X66;
reg52val=0X1B;
reg53val=0X4B;
break;
case 3://1
reg4f5054val=0X99;
reg52val=0X28;
reg53val=0X71;
break;
case 4://2
reg4f5054val=0XC0;
reg52val=0X33;
reg53val=0X8D;
break;
}
SCCB_WR_Reg(0X4F,reg4f5054val);
SCCB_WR_Reg(0X50,reg4f5054val);
SCCB_WR_Reg(0X51,0X00);
SCCB_WR_Reg(0X52,reg52val);
SCCB_WR_Reg(0X53,reg53val);
SCCB_WR_Reg(0X54,reg4f5054val);
SCCB_WR_Reg(0X58,0X9E);
}
void OV7670_Brightness(u8 bright)
{
u8 reg55val=0X00;//ĬÈϾÍÊÇbright=2
switch(bright)
{
case 0://-2
reg55val=0XB0;
break;
case 1://-1
reg55val=0X98;
break;
case 3://1
reg55val=0X18;
break;
case 4://2
reg55val=0X30;
break;
}
SCCB_WR_Reg(0X55,reg55val);
}
void OV7670_Contrast(u8 contrast)
{
u8 reg56val=0X40;
switch(contrast)
{
case 0://-2
reg56val=0X30;
break;
case 1://-1
reg56val=0X38;
break;
case 3://1
reg56val=0X50;
break;
case 4://2
reg56val=0X60;
break;
}
SCCB_WR_Reg(0X56,reg56val);
}
void OV7670_Special_Effects(u8 eft)
{
u8 reg3aval=0X04;//ĬÈÏΪÆÕͨģʽ
u8 reg67val=0XC0;
u8 reg68val=0X80;
switch(eft)
{
case 1:
reg3aval=0X24;
reg67val=0X80;
reg68val=0X80;
break;
case 2:
reg3aval=0X14;
reg67val=0X80;
reg68val=0X80;
break;
case 3:
reg3aval=0X14;
reg67val=0Xc0;
reg68val=0X80;
break;
case 4:
reg3aval=0X14;
reg67val=0X40;
reg68val=0X40;
break;
case 5:
reg3aval=0X14;
reg67val=0X80;
reg68val=0XC0;
break;
case 6:
reg3aval=0X14;
reg67val=0XA0;
reg68val=0X40;
break;
}
SCCB_WR_Reg(0X3A,reg3aval);
SCCB_WR_Reg(0X68,reg67val);
SCCB_WR_Reg(0X67,reg68val);
}
void OV7670_Window_Set(u16 sx,u16 sy,u16 width,u16 height)
{
u16 endx;
u16 endy;
u8 temp;
endx=(sx+width*2)%784; // sx:HSTART endx:HSTOP
endy=sy+height*2; // sy:VSTRT endy:VSTOP
//ÉèÖÃHREF
temp=SCCB_RD_Reg(0X32);
temp&=0XC0;
temp|=((endx&0X07)<<3)|(sx&0X07);
SCCB_WR_Reg(0X032,temp);
SCCB_WR_Reg(0X17,sx>>3);
SCCB_WR_Reg(0X18,endx>>3);
//ÉèÖÃVREF
temp=SCCB_RD_Reg(0X03);
temp&=0XF0;
temp|=((endy&0X03)<<2)|(sy&0X03);
SCCB_WR_Reg(0X03,temp);
SCCB_WR_Reg(0X19,sy>>2);
SCCB_WR_Reg(0X1A,endy>>2);
}
TF card driver
The project also requires a TF card to store the images taken. Because the TF card driver is too long, I will not post it here. You can search the relevant code on the network to use.
STM32F103ZE
There are a lot of information and development documents about this chip on the network, here is a brief introduction to this chip.
I won’t say much about this chip. The chip download code USES j-link, as shown in the figure below:
This is a simple version of j-link that only supports SWD debugging and downloading, not JTAG. But for STM32 chip development, SWD debugging is enough.
Download the code to the STM32 chip
Make sure the connection between j-link and STM32F103ZE is correct, and then the chip can be identified in the KEIL development environment:
Click the download button to download the code to the chip:
STM32 control code
The data receiving of the STONE display module can only receive 255 bytes at a time, while the image size of a single RGB565 data is 240*320*2=153600Byte= 153.6kb, so it needs to be sub distributed.
In addition, due to the limitation of serial communication rate, the effect of picture real-time refresh is not very good. The serial port baud rate is configured to 921600, which is also the highest communication baud rate for the STONE serial display module.
Buttons and text in the display have corresponding addresses. In this project, the address of the display component is as follows:
TAKE PICTURE BUTTON: 0X002A
COLOR&GRAY BUTTON: 0X002B
CHANGE RATION BUTTON:0X002C
PREV PICTURE BUTTON:0X002D
NEXT PICTURE BUTTON:0X002E
BROWSE BUTTON: 0X002F
The main function code is as follows:
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "string.h"
#include "ov7670.h"
#include "tpad.h"
#include "timer.h"
#include "exti.h"
#include "usmart.h"
#include "dma.h"
#include "sdio_sdcard.h"
extern u8 ov_sta;
extern u8 img_dis_cnt;
extern u8 data_ready;
extern u8 USART_RX_END;
u16 user_width=240;
u16 user_heigh=240;
#define PIC_TOTAL 20
u8 sd_select=1;
u16 color_r;
u16 color_g;
u16 color_b;
void UART1_Send_Array(u8 send_array[],u16 num)
{
u16 i=0;
while(i<num)< span=""></num)<>
{
USART_SendData(USART1,send_array[i]);
while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);
i++;
}
}
void ov7670_clock_set(u8 PLL)
{
u8 temp=0;
RCC->CFGR&=0XFFFFFFFC;
RCC->CR&=~0x01000000;
RCC->CFGR&=~(0XF<<18);
PLL-=2;//µÖÏû2¸öµ¥Î»
RCC->CFGR|=PLL<<18;
RCC->CFGR|=1<<16; //PLLSRC ON
FLASH->ACR|=0x12;
RCC->CR|=0x01000000; //PLLON
while(!(RCC->CR>>25));
RCC->CFGR|=0x02;
while(temp!=0x02)
{
temp=RCC->CFGR>>2;
temp&=0x03;
}
}
#define SEND_BUF_SIZE 169
#define LCD_X_H 5
#define LCD_X_L 6
#define LCD_Y_H 7
#define LCD_Y_L 8
u8 lcd_send_buf[SEND_BUF_SIZE]={0xa5,0x5a,0xa6,0x85,0x00,0x00,0x00,0x00,0x00};
u8 lcd_send_buf1[512]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
u8 upda_flag=1;
u16 dis_fixel=0;
void camera_refresh()
{
u16 i=0,j=0,k=0;
u8 color;
u8 cnt=9;
u16 user_x_cnt=0,user_x_start=0,lcd_send_times=0;
u16 user_width1=user_width;
u16 user_heigh1=user_heigh;
if(user_width1==240)
{
user_x_cnt=2;
user_x_start=450;
}
else if(user_width1==320)
{
user_x_cnt=3;
user_x_start=410;
}
else if(user_width1==160)
{
user_x_cnt=1;
user_x_start=490;
}
else if(user_width1==80)
{
user_x_cnt=0;
user_x_start=530;
}
if(ov_sta==2)
{
OV7670_RRST=0;
OV7670_RCK_L;
OV7670_RCK_H;
OV7670_RCK_L;
OV7670_RRST=1;
OV7670_RCK_H;
upda_flag=0;
for(i=0;i<user_heigh1;i++)< span=""></user_heigh1;i++)<>
{
k=i+150;
lcd_send_buf[LCD_Y_L] = (u8)(k & 0x00ff);
lcd_send_buf[LCD_Y_H] = (u8)(k >> 8);
cnt=9;
lcd_send_times=0;
for(j=0;j<user_width1*2;j++)></user_width1*2;j++)>
{
OV7670_RCK_L;
color=(u8)GPIOC->IDR&0XFF;
OV7670_RCK_H;
lcd_send_buf[cnt++]=color;
if(cnt > 168)
{
if(lcd_send_times==0)
{
dis_fixel=user_x_start;
lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
}
else if(lcd_send_times==1)
{
dis_fixel+=80;
lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
}
else if(lcd_send_times==2)
{
dis_fixel+=80;
lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
}
else if(lcd_send_times==3)
{
dis_fixel+=80;
lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
}
if(USART_RX_END==1)
{
EXTI_ClearITPendingBit(EXTI_Line8);
ov_sta=0;
upda_flag=1;
return;
}
else
{
UART1_Send_Array(lcd_send_buf,169);
}
lcd_send_times++;
if(lcd_send_times>user_x_cnt)
lcd_send_times=0;
cnt=9;
}
}
}
EXTI_ClearITPendingBit(EXTI_Line8);
ov_sta=0;
upda_flag=1;
}
}
void clear_display()
{
u16 i=0,j=0,k=0;
u8 cnt=9,lcd_send_times=0;
u8 color;
u16 user_x_cnt=0,user_x_start=0;
u16 user_width1=user_width;
u16 user_heigh1=user_heigh;
if(user_width1==240)
{
user_x_cnt=2;
user_x_start=450;
}
else if(user_width1==320)
{
user_x_cnt=3;
user_x_start=410;
}
else if(user_width1==160)
{
user_x_cnt=1;
user_x_start=490;
}
else if(user_width1==80)
{
user_x_cnt=0;
user_x_start=530;
}
upda_flag=0;
for(i=0;i<user_heigh1;i++)< span=""></user_heigh1;i++)<>
{
k=i+150;
lcd_send_buf[LCD_Y_L] = (u8)(k & 0x00ff);
lcd_send_buf[LCD_Y_H] = (u8)(k >> 8);
cnt=9;
lcd_send_times=0;
for(j=0;j<user_width1*2;j++)></user_width1*2;j++)>
{
OV7670_RCK_L;
color=(u8)GPIOC->IDR&0XFF;
OV7670_RCK_H;
lcd_send_buf[cnt++]=0xff;
if(cnt > 168)
{
if(lcd_send_times==0)
{
dis_fixel=user_x_start;
lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
}
else if(lcd_send_times==1)
{
dis_fixel+=80;
lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
}
else if(lcd_send_times==2)
{
dis_fixel+=80;
lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
}
else if(lcd_send_times==3)
{
dis_fixel+=80;
lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
}
UART1_Send_Array(lcd_send_buf,169);
lcd_send_times++;
if(lcd_send_times>user_x_cnt)
lcd_send_times=0;
cnt=9;
}
}
}
EXTI_ClearITPendingBit(EXTI_Line8);
ov_sta=0;
upda_flag=1;
}
void user_save_image()
{
u16 i=0,j=0,k=0;
u8 color;
u8 cnt=9,m_cnt=0;
u16 user_x_cnt=0,user_x_start=0,lcd_send_times=0;
u16 user_width1=user_width;
if(user_width1==240)
{
user_x_cnt=2;
user_x_start=450;
}
else
{
return;
}
while(ov_sta!=2);
if(ov_sta==2)
{
OV7670_RRST=0;
OV7670_RCK_L;
OV7670_RCK_H;
OV7670_RCK_L;
OV7670_RRST=1;
OV7670_RCK_H;
upda_flag=0;
for(i=0;i<240;i++)
{
k=i+150;
lcd_send_buf[LCD_Y_L] = (u8)(k & 0x00ff);
lcd_send_buf[LCD_Y_H] = (u8)(k >> 8);
cnt=9;
lcd_send_times=0;
for(j=0;j<240*2;j++)
{
OV7670_RCK_L;
color=(u8)GPIOC->IDR&0XFF;
OV7670_RCK_H;
lcd_send_buf[cnt++]=color;
if(cnt > 168)
{
m_cnt=0;
if(lcd_send_times==0)
{
dis_fixel=user_x_start;
lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
for(m_cnt=0;m_cnt<169;m_cnt++)
{
lcd_send_buf1[m_cnt]=lcd_send_buf[m_cnt];
}
}
else if(lcd_send_times==1)
{
dis_fixel+=80;
lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
for(m_cnt=0;m_cnt<169;m_cnt++)
{
lcd_send_buf1[m_cnt+169]=lcd_send_buf[m_cnt];
}
}
else if(lcd_send_times==2)
{
dis_fixel+=80;
lcd_send_buf[LCD_X_H] =(u8)(dis_fixel >> 8);
lcd_send_buf[LCD_X_L] = (u8)(dis_fixel & 0x00ff);
for(m_cnt=0;m_cnt<169;m_cnt++)
{
lcd_send_buf1[m_cnt+169*2]=lcd_send_buf[m_cnt];
}
}
UART1_Send_Array(lcd_send_buf,169);
lcd_send_times++;
if(lcd_send_times>user_x_cnt)
{
SD_WriteDisk(lcd_send_buf1,i+240*sd_select,1);
lcd_send_times=0;
}
cnt=9;
}
}
}
}
EXTI_ClearITPendingBit(EXTI_Line8);
ov_sta=0;
upda_flag=1;
}
void read_image()
{
u8 i=0;
for(i=0;i<240;i++)
{
if(SD_ReadDisk(lcd_send_buf1,i+240*sd_select,1)==0)
{
UART1_Send_Array(lcd_send_buf1,507);
}
}
}
int main(void)
{
u8 pixel_ch_flag=0,user_effect_flag=0;
delay_init();
NVIC_Configuration();
uart_init(921600);
LED_Init();
LCD_Init();
delay_ms(1000);
delay_ms(1000);
while(OV7670_Init())//³õʼ»¯OV7670
{
delay_ms(200);
}
while(SD_Init())
{
delay_ms(500);
LED0=!LED0;
}
if(SD_ReadDisk(lcd_send_buf1,240*(PIC_TOTAL+10),1)==0)
{
sd_select=lcd_send_buf1[0];
if(sd_select>=PIC_TOTAL )
{
lcd_send_buf1[0]=0x00;
SD_WriteDisk(lcd_send_buf1,240*(PIC_TOTAL+10),1);
sd_select=0;
}
}
//show_sdcard_info();
EXTI8_Init();
OV7670_CS=0;
config_ov7670_OutPut(20,60,user_width,user_heigh,0);
while(1)
{
if(USART_RX_END==1)
{
switch(USART_RX_BUF[5])
{
case 0x2c:
clear_display();
pixel_ch_flag+=1;//!pixel_ch_flag;
if(pixel_ch_flag>3)
pixel_ch_flag=0;
if(pixel_ch_flag==1)
{
user_width=160;
user_heigh=160;
}
else if(pixel_ch_flag==2)
{
user_width=80;
user_heigh=80;
}
else if(pixel_ch_flag==3)
{
user_width=320;
user_heigh=240;
}
else
{
user_width=240;
user_heigh=240;
}
config_ov7670_OutPut(20,60,user_width,user_heigh,0);
if(user_effect_flag)
OV7670_Special_Effects(1);
else
OV7670_Special_Effects(0);
break;
case 0x2b:
user_effect_flag=!user_effect_flag;
if(user_effect_flag)
OV7670_Special_Effects(1);
else
OV7670_Special_Effects(0);
break;
case 0x2a:
if(user_width!=240)break;
if(img_dis_cnt==0)
{
img_dis_cnt=1;
}
else
{
if(SD_ReadDisk(lcd_send_buf1,240*(PIC_TOTAL+10),1)==0)
{
if(lcd_send_buf1[0]>=PIC_TOTAL)
{
lcd_send_buf1[0]=PIC_TOTAL;
sd_select=1;
}
else
{
sd_select=lcd_send_buf1[0]+1;
lcd_send_buf1[0]=sd_select;
}
SD_WriteDisk(lcd_send_buf1,240*(PIC_TOTAL+10),1);
user_save_image();
//sd_select=lcd_send_buf1[0];
}
}
break;
case 0x2d:
if(SD_ReadDisk(lcd_send_buf1,240*(PIC_TOTAL+10),1)==0)
{
if(lcd_send_buf1[0]==0)
break;
else
{
sd_select-=1;
if(sd_select==0)sd_select=lcd_send_buf1[0];
}
if(sd_select>lcd_send_buf1[0])
sd_select=1;
}
if(user_width==320)
clear_display();
read_image();
img_dis_cnt=0;
break;
case 0x2e:
if(SD_ReadDisk(lcd_send_buf1,240*(PIC_TOTAL+10),1)==0)
{
if(lcd_send_buf1[0]==0)
break;
if(sd_select>=lcd_send_buf1[0])
{
sd_select=1;
}
else
{
sd_select+=1;
}
}
if(user_width==320)
clear_display();
read_image();
img_dis_cnt=0;
break;
case 0x2f:
img_dis_cnt=0;
break;
default:
break;
}
USART_RX_END=0;
USART_RX_STA=0;
}
else
{
// USART_RX_END=0;
// USART_RX_STA=0;
if(img_dis_cnt==1)
camera_refresh();
}
}
}
Finally, the code is downloaded to the STM32 chip, and then the completed circuit board is connected to the display screen, and the power supply is guaranteed to be stable. You can see the pictures taken by VO7670 through the STONE display module.
ov7670 camera module connection with STONE display module end of the project.