本帖最后由 沙漠之风 于 2017-6-17 10:25 编辑
GD32Semi-Automatic-Camera
一、前言 本作品主要是围绕OV7670+LCD来设计的,玩单片机已经玩很多年了,一直没有搞过摄像头,心里总感觉缺点什么。这几年机器人、机器视觉、图像处理相当的火,当然玩这些东西,不一定要用这种摄像头,使用USB摄像头就够了,如前些日子玩的树莓派就是直接用USB摄像头来搞的。可是作为嵌入开发的追随者,还是更喜欢这种摄像头,让人能感觉到是自己实实在在的控制着它。 本作品非常的基础,但是基本需要的东西都覆盖了,分享出来给各位热爱摄像头,热爱机器视觉等嵌入式图像处理的伙伴们。如果你们想用来做项目,可以在我这个作品的基础上去提高其通信速度,将其中的软件IO模拟改成硬件通讯,速度定然能大大提高,做做简单的图像处理中的运动跟踪是完全没有问题的。
二、系统框图
图1.1半自动相机系统框图
三、功能介绍
图1.2 系统总体 从上图中我们可以看到整个系统包括电机部分、显示部分、按键部分、摄像头+MCU ,其中两个舵机够成了云台,使得摄像头可以多方位多角度的拍摄。LCD带有触摸功能,其实我们的矩阵键盘可以不要,直接用这个触摸屏就能实现键盘的功能,只是觉得,按键也是一个仪器设备不可缺少的,将其添加到系统中大家可以选择性的使用。整个系统实现了如下功能: 1、摄像头垂直+水平的移动 2、摄像头输出视频帧的特性设置 3、视频帧在LCD中显示
图1.3 LCD视频帧显示 4、视频帧在PC机的串口调试助手上显示
图1.4 PC端串口调试助手视频帧显示 5、LCD中实现了画板功能
图1.5 LCD画板
四、核心代码部分
代码非常的基础,没有什么好说的,所有的协议都是IO口模拟的,好处是,没有引脚的限制,坏处就是速度慢。 - <font size="3"><font size="5"><font size="4">int main(void)
- {
- uint8_t lightmode=1,saturation=0,brightness=1,contrast=1;
- uint8_t effect=0;
- uint8_t running=0;
- uint8_t OVstart=0;
- systick_config();
- Led_gpio_config();
- BT_gpio_config();//配置引脚
- BT_exit_config();//配置中断,一定要先配置引脚再配置中断,顺序有问题将运行不正确
- BT4x4_gpio_config();
- gd_usart2_init();
- usart2_exit_config();
- SG_gpio_config();
- timer1_config();
- timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_1,SG01);
- timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_2,SG02);
- while(OV7670_Init())//初始化OV7670
- {
- printf("\r\n The OV7670 is Error!!! \r\n");
- Delay_ms(200);
- }
- printf("\r\n The OV7670 Init OK!!! \r\n");
- Delay_ms(1500);
- OV7670_Light_Mode(lightmode);//白平衡设置
- OV7670_Color_Saturation(saturation);//色度设置
- OV7670_Brightness(brightness);//亮度设置
- OV7670_Contrast(contrast);//对比度设置
- OV7670_Special_Effects(effect);//特效设置
- EXTI15_Init();
- OV7670_Window_Set(10,174,320,240); //设置窗口
- Timer4_config();//10Khz计数频率,1秒钟中断
- OV7670_Window_Set(10,174,320,240); //设置窗口
- OV7670_CSL;//使能AL422B
- TP_Init();
- Lcd_Init(); //初始化OLED
- spistar() ;//模拟SPI初始化
- LCD_Clear(WHITE); //清屏
- BACK_COLOR=BLACK;;POINT_COLOR=WHITE;
- showimage(); //显示40*40图片
- while (1){
- if(OVstart==1)
- {
- camera_refresh();//更新显示
- }
- /* check whether the button is pressed */
- if(RESET == gpio_input_bit_get(GPIOA,GPIO_PIN_0)){
- delay_1ms(1);
- /* check whether the button is pressed */
- if(RESET == gpio_input_bit_get(GPIOA,GPIO_PIN_0)){
- GPIO_TG(GPIOD) = GPIO_PIN_7;
- }
- }
- if(jiance()) //检测触摸和按键
- {
- showimage(); //显示40*40图片
- }
- if(ref){showimage();} //显示40*40图片
- keychar = Scan4x4key();
- if(keychar!=20)
- {
- if(keychar==1|keychar==2|keychar==3|keychar==10)
- {
- //第一件事情,相机随机特效
- printf("Do the first thing\t\n");
- KeyEvent=1;
- effect++;
- effect = effect%6+1;
- OV7670_Special_Effects(effect);//特效设置
- LCD_Fill(0,240,240,320,WHITE);
- showhanzi(15,265,10);
- showhanzi(55,265,11);
- showhanzi(95,265,12);
- showhanzi(135,265,13);
- showhanzi(175,265,14); }
- if(keychar==4|keychar==5|keychar==6|keychar==11)
- {
- //第二件事情,让舵机水平加垂直
- printf("Do the second thing\t\n");
- KeyEvent=2;
- running=1;
- OV7670_Special_Effects(0);//特效设置
- LCD_Fill(0,240,240,320,WHITE);
- showhanzi(15,265,10);
- showhanzi(55,265,11);
- showhanzi(95,265,12);
- showhanzi(135,265,13);
- showhanzi(175,265,14);
- }
- if(keychar==7|keychar==8|keychar==9|keychar==12)
- {
- //第三件事情,让视频上传到上位机
- printf("Do the third thing\t\n");
- KeyEvent=3;
- running=0;
- OV7670_Special_Effects(0);//特效设置
- LCD_Fill(0,240,240,320,WHITE);
- showhanzi(15,265,10);
- showhanzi(55,265,11);
- showhanzi(95,265,12);
- showhanzi(135,265,13);
- showhanzi(175,265,14);
- }
- if(keychar==15|keychar==14|keychar==0|keychar==13)
- {
- //第四件事情,舵机暂停拍照
- printf("Do the last thing\t\n");
- KeyEvent=4;
- running=0;
- OV7670_Special_Effects(0);//特效设置
- OVstart=1;
- LCD_Fill(0,240,240,320,WHITE);
- showhanzi(15,265,10);
- showhanzi(55,265,11);
- showhanzi(95,265,12);
- showhanzi(135,265,13);
- showhanzi(175,265,14);
- } }
- if(running==1)
- {
- delay_1ms(10); //由于舵机转动到具体位置是需要时间的,所以预留一个延迟来保证舵机运转所以需要的时间。
- timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_1,SG01);
- timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_2,SG02);
- if(SGdracti==0)
- {
- SG01 = SG01+2;
- SG02 = SG02+2;
- }else
- {
- SG01 = SG01-2;
- SG02 = SG02-2;
- }
- if(SG01>1350)
- {
- SGdracti = 1;
- }
- if(SG01<=650)
- {
- SGdracti = 0;
- }
- if(SG02>1350)
- {
- SGdracti = 1;
- }
- if(SG02<=650)
- {
- SGdracti = 0;
- } }}}
- </font></font></font>
复制代码 |