【记录开源】使用STM32F4探索板 DCMI接口对MT9M111取像 FSMC接口到7寸LCD

2019-07-20 12:29发布


恰巧空出时间,就开源个玩具吧。

某一天:
    准备东西开始玩摄像头,ST官方有F407的OV7670程序。使用DCMI接口,接受数据之后直接DMA到LCD GRAM上。
恰巧手上有F407 discovery 和原子的7寸电容液晶屏,先调通LCD吧,所以先把板子焊下,使用FSMC调通对LCD的控制,
RS我记得好像是用A[0],有点久忘记了,各位以程序为准。
用的是F407,HCLK有点高,适当加大读写时序的保持时间。

各位听我解释,这个只是初期测试做的板子,飞成这样我自己都不好意思拿出来。。 求别喷  后面测试完成会做块漂亮的。
某一天+2:
   慢慢LCD写完之后使用F4的RNG测试、调、测调  测调  测调  测调   写时序OK。读时序我还没测哦各位= =
LCD章节完成。
那么接下来就要开始懂MT9M111这个摄像头了,之前在wang工那里看到他便宜啊镜头也霸气而且有130W就买下了,开始看datasheet  试用。
期间多亏wang工和xxn59的提醒,特此感谢。



这期间过了一段时间,具体我也忘了,包括参考ST例程xxn59例程、写程序、调程序。终于在某一天+N天完成。
从分辨率设置到避开干扰。
到最后出一点点图像还出现偏红现象。
                确诊为硬件问题,线不好。。
                   当然还有一些等等的细节问题。
某一天+N+2:
    我重新做了一块板子,程序修复一些问题。终于有点成功了。
这次焊的板子还好点= =

(这次我尽力了,焊得还不好你们就喷吧喷吧。。)
基本上完成了,开源给大家玩玩,各位可以基于这个什么玩玩图形算法啊,捕捉什么什么的。。

效果视频:




2013年7月完成的:

另外一个。







友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
49条回答
正点原子
1楼-- · 2019-07-25 06:52
先检查硬件设置,如果没问题,那就检查软件是不是有问题。
yh12345
2楼-- · 2019-07-25 08:00
 精彩回答 2  元偷偷看……
正点原子
3楼-- · 2019-07-25 13:57
 精彩回答 2  元偷偷看……
yh12345
4楼-- · 2019-07-25 19:55
回复【40楼】正点原子:
---------------------------------
/*********************************************************************************************************
*
* File             : TouchPanel.c
* Hardware Environment: 
* Build Environment: RealView MDK-ARM  Version: 4.20
* Version          : V1.0
* By               : 
*
*                                  (c) Copyright 2005-2011, WaveShare
*                                       http://www.waveshare.net
*                                          All Rights Reserved
*
*********************************************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "TouchPanel/TouchPanel.h"
#include "TouchPanel/config.h"
#include "LCD/LCD.h"
#include "ctiic.h"


/* rivate variables ---------------------------------------------------------*/

/* rivate define ------------------------------------------------------------*/
//电容触摸屏控制器
_m_ctp_dev ctp_dev=
{
GT811_Init,
GT811_Scan,//获得触摸点坐标,并保存
0,
0,
0,
0,
};  

//触摸屏配置参数(触摸屏厂家提供)
const u8 GTP_CFG_DATA[]=
{
    0x12,0x10,0x0E,0x0C,0x0A,0x08,0x06,0x04,0x02,0x00,0x05,0x55,0x15,0x55,0x25,0x55,
    0x35,0x55,0x45,0x55,0x55,0x55,0x65,0x55,0x75,0x55,0x85,0x55,0x95,0x55,0xA5,0x55,
    0xB5,0x55,0xC5,0x55,0xD5,0x55,0xE5,0x55,0xF5,0x55,0x1B,0x03,0x00,0x00,0x00,0x13,
    0x13,0x13,0x0F,0x0F,0x0A,0x50,0x30,0x05,0x03,0x64,0x05,0xe0,0x01,0x20,0x03,0x00,
    0x00,0x32,0x2C,0x34,0x2E,0x00,0x00,0x04,0x14,0x22,0x04,0x00,0x00,0x00,0x00,0x00,
    0x20,0x14,0xEC,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x30,
    0x25,0x28,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 
};  

//触摸屏中断处理
void EXTI9_5_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line5) != RESET)                 //没有这句话和下句话时,会一直运行中断程序
{
EXTI_ClearITPendingBit(EXTI_Line5);   

ctp_dev.tpsta|=0X80;//标记有有效触摸
}

//向GT811写入一次数据
//reg:起始寄存器地址
//buf:数据缓缓存区
//len:写数据长度
//返回值:0,成功;1,失败.
u8 GT811_WR_Reg(u16 reg,u8 *buf,u8 len)
{
u8 i;
u8 ret=0;
CT_IIC_Start();
  CT_IIC_Send_Byte(CT_CMD_WR);    //发送写命令   
CT_IIC_Wait_Ack();
CT_IIC_Send_Byte(reg>>8);    //发送高8位地址
CT_IIC_Wait_Ack();          
CT_IIC_Send_Byte(reg&0XFF);    //发送低8位地址
CT_IIC_Wait_Ack();  
for(i=0;i<len;i++)
{    
     CT_IIC_Send_Byte(buf);   //发数据
ret=CT_IIC_Wait_Ack();
if(ret)break;  
}
    CT_IIC_Stop(); //产生一个停止条件     
return ret; 
}
//从GT811读出一次数据
//reg:起始寄存器地址
//buf:数据缓缓存区
//len:读数据长度   
void GT811_RD_Reg(u16 reg,u8 *buf,u8 len)
{
u8 i;
  CT_IIC_Start();
  CT_IIC_Send_Byte(CT_CMD_WR);    //发送写命令   
CT_IIC_Wait_Ack();
  CT_IIC_Send_Byte(reg>>8);    //发送高8位地址
CT_IIC_Wait_Ack();          
  CT_IIC_Send_Byte(reg&0XFF);    //发送低8位地址
CT_IIC_Wait_Ack();  
  CT_IIC_Start();        
CT_IIC_Send_Byte(CT_CMD_RD);    //发送读命令    
CT_IIC_Wait_Ack();    
for(i=0;i<len;i++)
{    
     buf=CT_IIC_Read_Byte(i==(len-1)?0:1); //发数据   

    CT_IIC_Stop();//产生一个停止条件     
}
//向GT811发送配置参数
//buf:配置参数表指针
//cfg_len:配置参数长度
//返回值:0,成功;1,失败.
u8 GT811_Send_Cfg(u8 * buf,u16 cfg_len)
{
u8 ret=0;
u8 retry=0;
for(retry=0;retry<5;retry++)
{
ret=GT811_WR_Reg(CT_CONFIG_REG,buf,cfg_len);
if(ret==0)break;
delay_ms(10);  
}
return ret;
}
//GT811唤醒
void GT811_Wakeup_Sleep(void)
{
TP_CS(0); //复位
delay_ms(10);
  TP_CS(1); //释放复位     
delay_ms(100);
}     
//GT811初始化
//返回值:初始化结果
//0,初始化成功;
//1,发送配置参数错误
//2,版本错误
u8 GT811_Init(void)
{
  u16 version=0;
u8 temp;
  GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC,ENABLE);
  /* TP_CS  */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
    /*TP_IRQ */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN ;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
   TP_CS(1);

//  Ex_NVIC_Config(GPIO_F,10,FTIR);  //下降沿触发    
// MY_NVIC_Init(3,3,EXTI15_10_IRQChannel,2); //抢占3,子优先级3,组2  
    EXIT_TouchPanel_Config();
NVIC_TouchPanel_Config();

  CT_IIC_Init(); //电容触摸屏部分,IIC初始化
GT811_Wakeup_Sleep();  //唤醒GT811 
   GT811_RD_Reg(0X717,&temp,1); //读取版本高八位
version=(u16)temp<<8; 
GT811_RD_Reg(0X718,&temp,1); //读取版本低八位  
version|=temp;
printf("version:%x ",version); 
if(version==0X2010) //版本正确,发送配置参数

temp=GT811_Send_Cfg((u8*)GTP_CFG_DATA,sizeof(GTP_CFG_DATA));//发送配置参数
}else temp=2; //版本错误
return temp;   
}    
//扫描GT811
//得到的结果保存在ctp_dev结构体内      
void GT811_Scan(void)
{    
u8 buf[34];//一次读取34字节
if((ctp_dev.tpsta&0X80)==0)return; //有有效触摸,则读取数据,否则直接退出
   GT811_RD_Reg(CT_READ_XY_REG,buf,34); //一次读取34个字节
ctp_dev.tpsta=buf[0]&0X1F; //触摸点标记位,同时清除有效触摸标记
#if CT_EXCHG_XY==1 //调转XY
ctp_dev.y[0]=480-(((u16)buf[2]<<8)+buf[3]); //触摸点0坐标
ctp_dev.x[0]=((u16)buf[4]<<8)+buf[5];   
ctp_dev.ppr[0]=buf[6];  
ctp_dev.y[1]=480-(((u16)buf[7]<<8)+buf[8]); //触摸点1坐标
ctp_dev.x[1]=((u16)buf[9]<<8)+buf[10];   
ctp_dev.ppr[1]=buf[11];
ctp_dev.y[2]=480-(((u16)buf[12]<<8)+buf[13]);//触摸点2坐标
ctp_dev.x[2]=((u16)buf[14]<<8)+buf[15];   
ctp_dev.ppr[2]=buf[16];    
ctp_dev.y[3]=480-(((u16)buf[17]<<8)+buf[24]);//触摸点3坐标
ctp_dev.x[3]=((u16)buf[25]<<8)+buf[26];   
ctp_dev.ppr[3]=buf[27];
ctp_dev.y[4]=480-(((u16)buf[28]<<8)+buf[29]);//触摸点4坐标
ctp_dev.x[4]=((u16)buf[30]<<8)+buf[31];   
ctp_dev.ppr[4]=buf[32];
#else 
ctp_dev.y[0]=((u16)buf[2]<<8)+buf[3]; //触摸点0坐标
ctp_dev.x[0]=800-(((u16)buf[4]<<8)+buf[5]);   
ctp_dev.ppr[0]=buf[6];  
ctp_dev.y[1]=((u16)buf[7]<<8)+buf[8]; //触摸点1坐标
ctp_dev.x[1]=800-(((u16)buf[9]<<8)+buf[10]);   
ctp_dev.ppr[1]=buf[11];
ctp_dev.y[2]=((u16)buf[12]<<8)+buf[13]; //触摸点2坐标
ctp_dev.x[2]=800-(((u16)buf[14]<<8)+buf[15]);   
ctp_dev.ppr[2]=buf[16];    
ctp_dev.y[3]=((u16)buf[17]<<8)+buf[24]; //触摸点3坐标
ctp_dev.x[3]=800-(((u16)buf[25]<<8)+buf[26]);   
ctp_dev.ppr[3]=buf[27];
ctp_dev.y[4]=((u16)buf[28]<<8)+buf[29]; //触摸点4坐标
ctp_dev.x[4]=800-(((u16)buf[30]<<8)+buf[31]);   
ctp_dev.ppr[4]=buf[32];
#endif       
}

/*************************************************
Function:    void EXIT_Config(void);  
Description: 触摸屏外部中断配置函数
       Input:       无
Output:      无                            
*************************************************/
void EXIT_TouchPanel_Config(void)
{
EXTI_InitTypeDef EXTI_InitStructure;

/*使能外部中断复用时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

/*映射GPIOA的Pin0至EXTILine0*/
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource5);  
EXTI_ClearITPendingBit(EXTI_Line5);        //清外部线路0中断
EXTI_InitStructure.EXTI_Line = EXTI_Line5;      //线路0
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;    //触发模式为中断
//EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//;   //下降沿触发
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//   //上升沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;      //开外部中断
EXTI_Init(&EXTI_InitStructure);

}

/*************************************************
Function:    void NVIC_TouchPanel_Config(void)  
Description: 触摸屏嵌套中断断配置函数       
Input:       无
Output:      无                            
*************************************************/
void NVIC_TouchPanel_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);        //嵌套分组为组0
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;       //中断通道为通道0
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢断优先级为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;    //响应优先级为0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     //开中断
NVIC_Init(&NVIC_InitStructure);

}

/*********************************************************************************************************
      END FILE
*********************************************************************************************************/>
yh12345
5楼-- · 2019-07-25 22:10
 精彩回答 2  元偷偷看……
正点原子
6楼-- · 2019-07-26 01:46
回复【42楼】yh12345:
---------------------------------
仿真找下问题吧...

一周热门 更多>