打印

【试用】F207+OV7670+iLi9341 LCD

[复制链接]
1727|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 邹姆斯特朗 于 2016-4-21 17:05 编辑

       GD32F20X系列新品规划在现有GD32F1产品的基础上提供了全面增强的处理能力与全新的外设接口资源。全新增强型GD32F2系列MCU最高时钟频率为120MHz,为应对多个外设同时运行和嵌入式软件协议栈的资源开销,配备了256KB到3072KB的超大容量内置Flash及128KB到256KB的SRAM。内核访问闪存高速零等待,最高主频下的工作性能可达150DMIPS。作为当前市场最高性能的基于Cortex-M3内核的MCU产品,GD32F2系列提供了卓越的闪存缓存和连接能力方案。GD32F2系列MCU以先进的缓存架构配置了两个独立的SRAM存储器,可支持不同的总线上的主设备同时访问。首次配备的支持访问外部SDRAM内存的32位总线接口EXMC,能够以更高的性价比灵活方便的进行大容量数据缓冲扩展与高级界面控制。GD32F2还内置了TFT LCD控制器从而直接驱动液晶屏,最高可以支持SVGA 7吋800 x 600像素的RGB TFT显示。另外还集成了8位至14位的Camera视频接口,便于连接数字摄像头并实现图像采集与传输。

开始申请207小红板是想用来做基于摄像头的图像处理的,但是发现有点蛋疼,因为:

1、207是有LCD接口的,但是小红板没有引出所有引脚,红红火火;
2、207是有摄像头接口的,但是小红板没有引出所有引脚,恍恍惚惚。


没办法,只能稍微改变一下原计划了,先是买了一个带fifo的摄像头,再来是用SPI方式驱动LCD,也能凑合着用。  OV7670 的像素时钟( PCLK)最高可达 24Mhz,我们用 IO
口直接抓取,是非常困难的,也十分占耗 CPU(可以通过降低 PCLK 输出频率,来实现 IO口抓取,但是不推荐)。所以,这里我们并不是采取直接抓取来自 OV7670 的数据,而是通过 FIFO 读取, FIFO 芯片,用于暂存图像数据,有了这个芯片,就可以很方便的获取图像数据了,而不再需要单片机具有高速 IO,也不会耗费多少 CPU.
我现在要做的是用ov7670采集图像,RGB565输出,320*240的图像,然后用3.5寸的彩屏显示图像。相比STM32,GD207高达120M的主频真是个好东西。原始默认的频率是72M,我修改到120M(system_gd32f20x.c中修改),测试一下,跑起来妥妥的。



GD207的库使用起来,与ST没什么区别,用起来顺手,不过我在使用它的硬件SPI驱动液晶的时候,发现SPI的初始化还是有些许不同的,就是选择了串行时钟的稳态时,必须选择高电平才能保证数据的稳定。这算是GD的特色吧。

SPI_InitStructure.SPI_TransType = SPI_TRANSTYPE_FULLDUPLEX;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
        SPI_InitStructure.SPI_Mode = SPI_MODE_MASTER;                //设置SPI工作模式:设置为主SPI
        SPI_InitStructure.SPI_FrameFormat = SPI_FRAMEFORMAT_8BIT;                //设置SPI的数据大小:SPI发送接收8位帧结构
        SPI_InitStructure.SPI_SCKPL = SPI_SCKPL_HIGH;                //选择了串行时钟的稳态:时钟悬空高
        SPI_InitStructure.SPI_SCKPH = SPI_SCKPH_2EDGE;        //数据捕获于第二个时钟沿
        SPI_InitStructure.SPI_SWNSSEN = SPI_SWNSS_SOFT;                //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
        SPI_InitStructure.SPI_PSC = SPI_PSC_256;                //定义波特率预分频的值:波特率预分频值为256
        SPI_InitStructure.SPI_FirstBit = SPI_FIRSTBIT_MSB;        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
        SPI_InitStructure.SPI_CRCPOL = 7;        //CRC值计算的多项式
        SPI_Init(SPI1, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器

        SPI_Enable(SPI1, ENABLE); //使能SPI外设

因为是第一次接触摄像头,代码先初始化 OV7670 相关的 IO 口(包括 SCCB_Init),然后最主要的是完成OV7670 的寄存器序列初始化。 OV7670 的寄存器特多(百几十个),着实吓了一跳,配置特麻烦,幸好厂家有提供参考配置序列,让我省了不少事。

WrCmos7670(0x3a, 0x04);
        WrCmos7670(0x40, 0xd0);
        WrCmos7670(0x12, 0x14);  //输出格式为:QVGA(320*240) RGB
        //WrCmos7670(0x12, 0x08);  //输出格式为:QCIF:176?44,
        WrCmos7670(0x32, 0x80);
        WrCmos7670(0x17, 0x16);
        WrCmos7670(0x18, 0x04);
        WrCmos7670(0x19, 0x02);
        WrCmos7670(0x1a, 0x7b);
        WrCmos7670(0x03, 0x06);
        WrCmos7670(0x0c, 0x0c);
        WrCmos7670(0x15, 0x02);
        WrCmos7670(0x3e, 0x00);
        WrCmos7670(0x70, 0x3a);
        WrCmos7670(0x71, 0x01);
        WrCmos7670(0x72, 0x11);
        WrCmos7670(0x73, 0x00);
        WrCmos7670(0xa2, 0x02);
        WrCmos7670(0x11, 0x81);
        
        WrCmos7670(0x7a, 0x20);
        WrCmos7670(0x7b, 0x1c);
        WrCmos7670(0x7c, 0x28);
        WrCmos7670(0x7d, 0x3c);
        WrCmos7670(0x7e, 0x55);
        WrCmos7670(0x7f, 0x68);
        WrCmos7670(0x80, 0x76);
        WrCmos7670(0x81, 0x80);
        WrCmos7670(0x82, 0x88);
        WrCmos7670(0x83, 0x8f);
        WrCmos7670(0x84, 0x96);
        WrCmos7670(0x85, 0xa3);
        WrCmos7670(0x86, 0xaf);
        WrCmos7670(0x87, 0xc4);
        WrCmos7670(0x88, 0xd7);
        WrCmos7670(0x89, 0xe8);
        
        WrCmos7670(0x13, 0xe7);
        WrCmos7670(0x00, 0x00);
        WrCmos7670(0x10, 0x00);
        WrCmos7670(0x0d, 0x00);
        WrCmos7670(0x14, 0x20);
        WrCmos7670(0xa5, 0x05);
        WrCmos7670(0xab, 0x07);
        WrCmos7670(0x24, 0x75);
        WrCmos7670(0x25, 0x63);
        WrCmos7670(0x26, 0xA5);
        WrCmos7670(0x9f, 0x78);
        WrCmos7670(0xa0, 0x68);
        WrCmos7670(0xa1, 0x03);
        WrCmos7670(0xa6, 0xdf);
        WrCmos7670(0xa7, 0xdf);
        WrCmos7670(0xa8, 0xf0);
        WrCmos7670(0xa9, 0x90);
        WrCmos7670(0xaa, 0x94);//AEC公式选择:基于直方图的AEC算法;WrCmos7670(0xaa, 0x94)->基于平均值的AEC算法
        WrCmos7670(0x13, 0xe5);

        WrCmos7670(0x0e, 0x61);
        WrCmos7670(0x0f, 0x4b);
        WrCmos7670(0x16, 0x02);
        WrCmos7670(0x1e, 0x37);//翻转镜头图像WrCmos7670(0x1e, 0x27);上下颠倒WrCmos7670(0x1e, 0x01);
        WrCmos7670(0x21, 0x02);
        WrCmos7670(0x22, 0x91);
        WrCmos7670(0x29, 0x07);
        WrCmos7670(0x33, 0x0b);
        WrCmos7670(0x35, 0x0b);
        WrCmos7670(0x37, 0x1d);
        WrCmos7670(0x38, 0x71);
        WrCmos7670(0x39, 0x2a);
        WrCmos7670(0x3c, 0x78);
        WrCmos7670(0x4d, 0x40);
        WrCmos7670(0x4e, 0x20);
        WrCmos7670(0x69, 0x5d);//固定增益控制
        WrCmos7670(0x6b, 0x40);
        WrCmos7670(0x74, 0x19);
        WrCmos7670(0x8d, 0x4f);
        WrCmos7670(0x8e, 0x00);
        WrCmos7670(0x8f, 0x00);
        WrCmos7670(0x90, 0x00);
        WrCmos7670(0x91, 0x00);
        WrCmos7670(0x92, 0x00);
        WrCmos7670(0x96, 0x00);
        WrCmos7670(0x9a, 0x80);
        WrCmos7670(0xb0, 0x84);
        WrCmos7670(0xb1, 0x0c);
        WrCmos7670(0xb2, 0x0e);
        WrCmos7670(0xb3, 0x82);
        WrCmos7670(0xb8, 0x0a);

        WrCmos7670(0x43, 0x14);
        WrCmos7670(0x44, 0xf0);
        WrCmos7670(0x45, 0x34);
        WrCmos7670(0x46, 0x58);
        WrCmos7670(0x47, 0x28);
        WrCmos7670(0x48, 0x3a);
        WrCmos7670(0x59, 0x88);
        WrCmos7670(0x5a, 0x88);
        WrCmos7670(0x5b, 0x44);
        WrCmos7670(0x5c, 0x67);
        WrCmos7670(0x5d, 0x49);
        WrCmos7670(0x5e, 0x0e);
        WrCmos7670(0x64, 0x04);
        WrCmos7670(0x65, 0x20);
        WrCmos7670(0x66, 0x05);
        WrCmos7670(0x94, 0x04);
        WrCmos7670(0x95, 0x08);
        
        WrCmos7670(0x6c, 0x0a);
        WrCmos7670(0x6d, 0x55);
        
        WrCmos7670(0x4f, 0x80);//色彩矩阵系数
        WrCmos7670(0x50, 0x80);
        WrCmos7670(0x51, 0x00);
        WrCmos7670(0x52, 0x22);
        WrCmos7670(0x53, 0x5e);
        WrCmos7670(0x54, 0x80);
        
        WrCmos7670(0x6e, 0x11);
        WrCmos7670(0x6f, 0x9f);
  WrCmos7670(0x55, 0x00);
        WrCmos7670(0x56, 0x40);
        WrCmos7670(0x58, 0x9e);
其次就是iLi9341控制的触摸屏,英文的阅读能力有限,看不下去,还好论坛网友翻译了它的datasheet,简直感人。
delay_ms(100);
                LCD_WR_REG(0xCB);       //功耗控制A
                LCD_WR_DATAX(0x39);
                LCD_WR_DATAX(0x2C);
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x34);
                LCD_WR_DATAX(0x02);
               
                delay_ms(100);
                LCD_WR_REG(0xCF);       //功耗控制B
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0xC1);
                LCD_WR_DATAX(0X30);
               
                delay_ms(100);
                LCD_WR_REG(0xE8);       //驱动时序控制B
                LCD_WR_DATAX(0x85);
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x78);
               
                delay_ms(100);
                LCD_WR_REG(0xEA);       //驱动时序控制B
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x00);
               
                delay_ms(100);
                LCD_WR_REG(0xED);       //电源序列控制
                LCD_WR_DATAX(0x64);
                LCD_WR_DATAX(0x03);
                LCD_WR_DATAX(0X12);
                LCD_WR_DATAX(0X81);
               
               
                delay_ms(100);
                LCD_WR_REG(0xF7);       //泵比控制
                LCD_WR_DATAX(0x20);
               
               
                delay_ms(100);
                LCD_WR_REG(0xC0);    //功耗控制1
                LCD_WR_DATAX(0x23);   
               
                delay_ms(100);
                LCD_WR_REG(0xC1);    //功耗控制2
                LCD_WR_DATAX(0x10);   
               
                delay_ms(100);
                LCD_WR_REG(0xC5);    //VCOM控制1  
                LCD_WR_DATAX(0x3e);           
                LCD_WR_DATAX(0x28);         
               
                delay_ms(100);
                LCD_WR_REG(0xC7);     //VCOM控制1
                LCD_WR_DATAX(0X86);
               
                delay_ms(100);
                LCD_WR_REG(0x36);    // 存储器访问控制
                LCD_WR_DATAX(0x48);
//                LCD_WR_DATAX(0xE8);
               
                delay_ms(100);
                LCD_WR_REG(0x3A);     //COLMOD像素格式设置           
                LCD_WR_DATAX(0x55);
               
                delay_ms(100);
                LCD_WR_REG(0xB1);     //帧速率控制(正常/全色)
                LCD_WR_DATAX(0x00);   
                LCD_WR_DATAX(0x18);
               
                delay_ms(100);
                LCD_WR_REG(0xB6);    // 显示功能控制
                LCD_WR_DATAX(0x08);
                LCD_WR_DATAX(0x82);
                LCD_WR_DATAX(0x27);
               
                delay_ms(100);
                LCD_WR_REG(0xF2);    // 使能3G
                LCD_WR_DATAX(0x00);
               
                delay_ms(100);
                LCD_WR_REG(0x26);    //伽马设置
                LCD_WR_DATAX(0x01);
               
                delay_ms(100);
                LCD_WR_REG(0xE0);    //正极伽马校准
                LCD_WR_DATAX(0x0F);
                LCD_WR_DATAX(0x2A);
                LCD_WR_DATAX(0x28);
                LCD_WR_DATAX(0x08);
                LCD_WR_DATAX(0x0E);
                LCD_WR_DATAX(0x08);
                LCD_WR_DATAX(0x54);
                LCD_WR_DATAX(0XA9);
                LCD_WR_DATAX(0x43);
                LCD_WR_DATAX(0x0A);
                LCD_WR_DATAX(0x0F);
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x00);
               
                delay_ms(100);
                LCD_WR_REG(0XE1);    //负极伽马校准
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x15);
                LCD_WR_DATAX(0x17);
                LCD_WR_DATAX(0x07);
                LCD_WR_DATAX(0x11);
                LCD_WR_DATAX(0x06);
                LCD_WR_DATAX(0x2B);
                LCD_WR_DATAX(0x56);
                LCD_WR_DATAX(0x3C);
                LCD_WR_DATAX(0x05);
                LCD_WR_DATAX(0x10);
                LCD_WR_DATAX(0x0F);
                LCD_WR_DATAX(0x3F);
                LCD_WR_DATAX(0x3F);
                LCD_WR_DATAX(0x0F);
               
                delay_ms(100);
                LCD_WR_REG(0x2B);           //页地址设置
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x01);
                LCD_WR_DATAX(0x3f);
               
                delay_ms(100);
                LCD_WR_REG(0x2A);           //列地址设置
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0x00);
                LCD_WR_DATAX(0xef);
               
                delay_ms(100);
                LCD_WR_REG(0x11);           //退出休眠模式
               
                delay_ms(120);

整体来说,GD207这款片子给我的试用感觉还是很不错的:
第一,因为它和STM32很相似,所以用起来很方便,容易上手,这点在推广方便来说,应该是一个很好的优势;
其次,GD兼容ST,但不等于ST,独有flash加速技术确实让人眼前一亮(虽然只能做到前半部加速),而且120M的主频,也是让我一个让我感觉不错的地方;
最后,毕竟芯片是国产的,板子是免费的,用起来身心舒畅,期待国产MCU再上一层楼!

然后就是有两个小小的吐槽:

1,板子的丝印问题大大的,查看不方便还是其次的,重要的是印反的,接线半天才发现问题。
2,小红板144的引脚只引出了一半,可惜,camera和LCD接口都胎死腹中的感觉。

热心网友提供的板子示意图,十分感谢
GD207引脚示意A.pdf (314.32 KB) GD207引脚示意B.pdf (242.7 KB)



沙发
wolfgang_z| | 2016-4-26 13:47 | 只看该作者
能用得上就好!

使用特权

评论回复
板凳
邹姆斯特朗|  楼主 | 2016-4-26 22:22 | 只看该作者

板子引脚示意图原作者出现

使用特权

评论回复
地板
cnb12345| | 2016-4-29 10:27 | 只看该作者

使用特权

评论回复
5
jinyi7016| | 2016-5-1 20:29 | 只看该作者
camera和LCD接口都胎死腹中,怎么还有这么多camera和LCD的 程序啊。

使用特权

评论回复
6
邹姆斯特朗|  楼主 | 2016-5-2 23:24 | 只看该作者
jinyi7016 发表于 2016-5-1 20:29
camera和LCD接口都胎死腹中,怎么还有这么多camera和LCD的 程序啊。

camera接口没了,所以用了带fifo的摄像头,LCD接口没了,我用的是SPI的驱动方式。

使用特权

评论回复
7
cnb12345| | 2016-5-3 12:05 | 只看该作者

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

59

帖子

2

粉丝