六、 应用编程
1 硬件连接图2 软件设计2.1 系统初始化(SystemInit)对系统设备进行初始化设置,初始化完成后所有设备都处于正常工作状态,这时可以进行图像采集和LCD输出显示。 以下为金龙107的参考代码: Init_KEY(); //初始化按键 Init_Usart(); //初始化串口 Usart_Configuration(115200); //配置波特率 Printf("串口初始化完成\r\n"); LCD_Init(); //初始化显示屏 LCD_Clear(0x0000); //显示黑色背景 Init_OV7670(); //初始化Sensor LCD_WindowMax(0,0,240,320); //设置显示窗口大小 while(1) { 图像采集过程 } 2.2 OV7670初始化过程摄像头初始化包括SCCB总线端口配置、ID号检测和寄存器初始化列表配置。 uint8_t Init_OV7670(void) { GPIO_SCCB(); //SCCB总线端口配置 Init_XCLK_ON(); //OV7670的输入时钟配置 wrOV7670Reg(0x12, 0x80); //复位SCCB总线 (……) //检测OV7670芯片ID号 (……) //OV7670初始化列表配置 GPIO_OV7670(); //初始化FIFO和中断引脚 set_qvga(); //设置Sensor图像输出格式为QVGA } 2.2.1 SCCB总线端口配置GPIO_SCCB(); //这是函数名,以下为函数内容 GPIO_InitTypeDef GPIO_InitStructure; //定义初始化结构变量 RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC, ENABLE); //启用SCCB的IO口时钟 GPIO_InitStructure .GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; //定义SCCB总线IO口 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//配置IO口输出模式为复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置SCCB输出速率为50赫兹 GPIO_Init (GPIOC, &GPIO_InitStructure); //初始化SCCB总线IO口 2.2.2 OV7670的输入时钟配置OV7670要正常工作必须外部提供一个时钟信号MCLK,MCLK可以通过配置IO口提供一个时钟源,也可以通过外部晶振提供时钟源。当OV7670完成初始化之后会产生一个数据输出的同步时钟PCLK,PCLK是通过OV7670内部寄存器配置产生,可以配置想要的频率输出,这个频率会直接影响OV7670的图像输出帧率。 Init_XCLK_ON(); //这是函数名,以下为函数内容 GPIO_InitTypeDef GPIO_InitStructure; //定义初始化结构变量 RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA, ENABLE);//启用摄像头IO口时钟 GPIO_InitStructure .GPIO_Pin = OV7670_XCLK_BIT; //定义摄像头输入时钟IO口 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //配置IO口输出模式为复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置时钟输出速率为50赫兹 GPIO_Init (GPIOA, &GPIO_InitStructure); //初始化时钟输出IO口 RCC_MCOConfig( RCC_MCO_HSE); //使能外部晶振作为OV7670时钟 2.2.3 检测OV7670芯片ID号wrOV7670Reg(0x12, temp); //复位SCCB rdOV7660Reg(0x0a, &ovidmsb); //读产品的高位序列号 if(ovidmsb !=0x76) return 0; //检测ID值,OV7670的高位ID值是0x76 rdOV7660Reg(0x0b, &ovidlsb ); //读产品的低位序列号 if(ovidlsb !=0x73) return 0; //检测ID值,OV7670的低位ID值是0x73 2.2.4 OV7670初始化列表配置初始化摄像头主要就是把配置列表的地址和值填写到OV7670对应的寄存器地址和寄存器值。填写完OV7670的寄存器后,OV7670就会按寄存器配置列表的配置模式进行工作。 CHANGE_REG_NUM:指定配置寄存器列表有多少组 change_reg[CHANGE_REG_NUM][2]:OV7670寄存器初始化列表 每一组数据都是由寄存器地址和寄存器值构成,通过FOR循环把所有数组的寄存器值填写到OV7670对应的寄存器里面,看下面代码: for(i=0;i { if( 0 == wrOV7670Reg(change_reg[0],change_reg[1]))//填写寄存器值 { return 0; //错误反回0 } } 2.2.5 初始化FIFO和中断引脚void GPIO_OV7670(void) { GPIO_FIFO(); //AL422缓存引脚配置 EXTI_OV7670(); //摄像头帧同步信号中断引脚配置 VSYNC } 2.2.6 设置OV7670图像输出格式void set_qvga(void) //设置QVGA输出 { while(1!= wrOV7670Reg(0x12, 0x14));//设置输出格式RAW,大小QVGA wrOV7670Reg(0x17, 0x16);//HSTART,输出格式-行频开始高八位(低三位在HREF[2:0]) wrOV7670Reg(0x18, 0x04); //HSTOP,输出格式-行频结束高八位(低三位在HREF[5:3]) wrOV7670Reg(0x19, 0x03); //VSTRT, 输出格式-场频开始高八位(低二位在VREF[1:0]) wrOV7670Reg(0x1A, 0x7B); //VSTOP,输出格式-场频结束高八位(低二位在VREF[3:2]) wrOV7670Reg(0x03, 0x0a); //VREF 位[3:2]VREF结束的低两位(高八位见VSTOP[7:0]) 位[1:0]VREF开始的低两位(高八位见VSTOP[7:0]) wrOV7670Reg(0x70, 0x35); //SCALING_XSC,水平缩放系数 wrOV7670Reg(0x71, 0x3a); //SCALING_YSC,垂直缩放系数 wrOV7670Reg(0x72, 0x11); //SCALING_DCWCTR,DCW控制 wrOV7670Reg(0x73, 0xF7); //SCALING_PC,旁路DSP缩放时钟分频控制 wrOV7670Reg(0xA2, 0x02); //SCALING_PCLK_DELAY,像素始终延迟 wrOV7670Reg(0xac, 0x0); //亮度 } void set_cif(void) //设置CIF输出 { while(1!= wrOV7670Reg(0x12, 0x24)); //设置输出格式RAW,大小CIF wrOV7670Reg(0x17, 0x15);//HSTART,输出格式-行频开始高八位(低三位在HREF[2:0]) wrOV7670Reg(0x18, 0x0B); //HSTOP,输出格式-行频结束高八位(低三位在HREF[5:3]) wrOV7670Reg(0x19, 0x03); //VSTRT, 输出格式-场频开始高八位(低二位在VREF[1:0]) wrOV7670Reg(0x1A, 0x7b); //VSTOP,输出格式-场频结束高八位(低二位在VREF[3:2]); wrOV7670Reg(0x03, 0x0a); //VREF 位[3:2]VREF结束的低两位(高八位见VSTOP[7:0]) 位[1:0]VREF开始的低两位(高八位见VSTOP[7:0]) wrOV7670Reg(0x32, 0xb6); //HREF,HREF控制 位[7:6]:HREF沿距数据输出的偏移 位[5:3]:HREF结束的低3位(高8位在HSTOP) 位[2:0]:HREF开始的低3位(高8位在HSTOP) wrOV7670Reg(0x70, 0x3A); //SCALING_XSC,水平缩放系数 wrOV7670Reg(0x71, 0x35); //SCALING_YSC,垂直缩放系数 wrOV7670Reg(0x72, 0x11); //SCALING_DCWCTR,DCW控制 wrOV7670Reg(0x73, 0xF2); //SCALING_PC,旁路DSP缩放时钟分频控制 wrOV7670Reg(0xA2, 0x03); //SCALING_PCLK_DELAY,像素始终延迟 } void set_light(unsigned char i) //设置亮度 { wrOV7670Reg(0x55, i); //BRIGHT,亮度控制 }
|