本帖最后由 琥珀少年 于 2019-5-26 20:32 编辑
在原子的ov5640例程和ov2640的摄像头拍照例程的基础上做了移植,但是摄像头不显示图像。代码和运行照片贴出来,请各位大佬帮忙,有偿也可以的。跪谢。
[mw_shl_code=c,true]#include "sys.h"
#include "delay.h"
#include "led.h"
#include "usart.h"
#include "lcd.h"
#include "ltdc.h"
#include "sdram.h"
#include "key.h"
#include "usmart.h"
#include "timer.h"
#include "ov2640.h"
#include "dcmi.h"
#include "usart2.h"
//ALIENTEK 阿波罗STM32F429开发板 实验37
//摄像头 实验
//技术支持:
www.openedv.com
//广州市星翼电子科技有限公司
u16 rgb_buf[144][176]; //存放像素的数组,大小为144*176
u16 gray;//定义灰度值
u16 hang=0;
u8 X_MAX,Y_MAX=0; //小球的坐标信息
u8 X_MAX_LSAT, X_MIN_LSAT, Y_MAX_LSAT, Y_MIN_LSAT=0; //上一次小球坐标位置信息
u8 X,Y=0; //小球的质心信息
u8 X_MIN,Y_MIN=180;
u8 ovx_mode=0; //bit0:0,RGB565模式;1,JPEG模式
u16 curline=0; //摄像头输出数据,当前行编号
u16 yoffset=0; //y方向的偏移量
//处理JPEG数据
//当采集完一帧JPEG数据后,调用此函数,切换JPEG BUF.开始下一帧采集.
//RGB565测试
//RGB数据直接显示在LCD上面
//RGB565测试
void rgb565_test(void)
{
u8 key;
LCD_Clear(WHITE);
POINT_COLOR=RED;
LCD_ShowString(30,150,200,16,16,"test");
OV2640_ImageWin_Set((800-480)/2,(600-600)/2,480,600);//前两个数为调节画面移动,后两个为分辨率,1200*1200的分辨率
OV2640_OutSize_Set(144,176); //144,176为分到液晶屏幕上144*176区域,大小和数组大小相同
OV2640_RGB565_Mode(); //RGB565模式
DCMI_Init(); //DCMI配置
DCMI_DMA_Init((u32)rgb_buf,0,sizeof(rgb_buf)/4,1,1);//DCMI DMA配置//DMA搬运的像素点存放的地址为数组
DCMI_Start(); //启动传输
LCD_ShowString(30,170,200,16,16,"test");
while(1)
{
key=KEY_Scan(0);
if(key)
{
DCMI_Stop(); //停止显示
switch(key)
{
case KEY0_PRES: //对比度设置
break;
case KEY1_PRES: //饱和度Saturation
break;
case KEY2_PRES: //特效设置
break;
case WKUP_PRES:
break;
}
DCMI_Start();//重新开始传输
}
delay_ms(10);
}
}
int main(void)
{
u8 key;
u8 t;
u16 i,j;
Stm32_Clock_Init(360,25,2,8);//设置时钟,180Mhz
delay_init(180); //初始化延时函数
uart_init(90,115200); //初始化串口波特率为115200
usart2_init(45,921600); //初始化串口2波特率为921600
LED_Init(); //初始化与LED连接的硬件接口
SDRAM_Init(); //初始化SDRAM
LCD_Init(); //初始化LCD
KEY_Init(); //初始化按键
usmart_dev.init(90); //初始化USMART
POINT_COLOR=RED;
LCD_ShowString(30,50,200,16,16,"Apollo STM32F4");
LCD_ShowString(30,70,200,16,16,"OV5640 TEST");
LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
LCD_ShowString(30,110,200,16,16,"2015/12/30");
while(OV2640_Init())//初始化OV2640
{
LCD_ShowString(30,130,240,16,16,"OV2640 ERR");
delay_ms(200);
LCD_Fill(30,130,239,170,WHITE);
delay_ms(200);
}
LCD_ShowString(30,130,200,16,16,"OV2640 OK");
delay_ms(2000);
rgb565_test(); //开始向数组传送图像数据
while(1)
{
rgb565_test();
hang=0;
LCD_SetCursor(0,0);
LCD_WriteRAM_Prepare(); //开始写入GRAM,将数组中的像素写到液晶屏上
for(i=0;i<144;i++)
{
for(j=0;j<176;j++) //利用两个for循环将数组中的像素排列到液晶屏上
{
if(j==175)
{
hang++;
LCD_SetCursor(0,i+1);
LCD_WriteRAM_Prepare(); //开始写入GRAM
}
gray=((rgb_buf
[j]>>11)*19595+((rgb_buf[j]>>5)&0x3f)*38469 +(rgb_buf[j]&0x1f)*7472)>>16; //灰度计算。公式请百度,将RGB转为灰度
if(gray>=23) //23为固定灰度阈值,刚好卡在黑白之间,大于这个值为白,小于则为黑,根据效果调灰度阈值
{
if(i>8&&i<136&&j<160&&j>16) //此处遍历图像寻找小球最上最下 最左 最右四个点坐标
{
if(i>X_MAX) X_MAX=i;
if(i<X_MIN) X_MIN=i;
if(j>Y_MAX) Y_MAX=j;
if(j<Y_MIN) Y_MIN=j;
}
LCD->LCD_RAM=WHITE; //二值化,将大于灰度值的填充为白 {MOD}
}
else
{
LCD->LCD_RAM=BLACK;//二值化,将小于灰度值的填充为黑 {MOD}
}
}
}
X_MAX_LSAT = X_MAX; //更新pid的real坐标信息
X_MIN_LSAT = X_MIN;
Y_MAX_LSAT = Y_MAX;
Y_MIN_LSAT = Y_MIN;
X_MAX=0;
X_MIN=180;
Y_MAX=0;
Y_MIN=180; //清除掉本次坐标用于再次遍历最大值 最小值
X=(X_MAX_LSAT+X_MIN_LSAT)/2;
Y=(Y_MAX_LSAT+Y_MIN_LSAT)/2; //通过四个点坐标计算小球质心
delay_ms(200);
LED0 = ! LED0;
}
}
[/mw_shl_code]
一周热门 更多>