打印
[STM32F4]

【NUCLEO-F412ZG试用体验】利用mbed驱显16位并口TFTLCD显示

[复制链接]
1962|35
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhjb1|  楼主 | 2017-3-22 17:31 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 zhjb1 于 2017-3-24 22:31 编辑

【NUCLEO-F412ZG试用体验】利用mbed驱显16位并口TFTLCD显示
前几天看了网上有网友询问驱显并口LCD的问题,找了半天找不到了,先做实验放上以供学习共同提高。
实验平台:IAR7.5;工程:STM32F411的mbed改过来的;开发板:STM32F412ZG-NUCLEO。
在这块开发板上采用16位并口驱显TFTLCD是有一定难度的,因为这块板子的IO口是按照就近引出在2.54插座上,如果要采用常规的方法来定义一组[比如PTA、PTB、等],那么跳线将在板子上乱飞,难看不说,万一有干扰出现驱显不正常还真不知道应该找谁理论。给一张用户手册上的管脚排列照片看看,图x1。
这块显示屏买的是只有内屏的2.1寸显示屏,驱动芯片是S6D0128,16位地址线,5个控制信号线:CS-片选,RS-寄存器/数据操作,WR-线信号,RD读信号,RES-LCD复位,再加电源+ 和地,自己设计的5X5板子将背光LED串联电阻直接介入V+和GND上了。
利用mbed就方便多了,就近找几个可用的IO定义一下就OK了。按照以前的mbed介绍,要用并行输出,首先打开busOut.h文档,可以看到直接给出的实例如下:
BusOut(PinName p0, PinName p1 = NC, PinName p2 = NC, PinName p3 = NC,PinName p4 = NC, PinName p5 = NC, PinName p6 = NC, PinName p7 = NC,PinName p8 = NC, PinName p9 = NC, PinName p10 = NC, PinName p11 = NC,
PinName p12 = NC, PinName p13 = NC, PinName p14 = NC, PinName p15 = NC);
猛一看,还真是不理解什么意思,仔细琢摸后大致理解了,只能用实验来验证理解的正确与否。按照图x1,红框圈起来的作为16位数据线,蓝线圈起来的作为这块TFTLCD的控制信号线。下边开始实验:
先创建一个文件:21lcd.h
头文件:
//2.1 inch Color LCD 176X220dots Chip=S6D0128
#include "mbed.h"
而后创建定义总线对象:
//Define I/O Data
BusOut mybus(PB_4,PA_4,PB_3,PB_5,PC_7,PA_15,PB_12,PB_13,PB_15,PC_6,PD_2,PC_12,PC_11,PC_10,PC_9,PC_8);//16B LSB->MSB
DigitalOut rd(PD_7);
DigitalOut wr(PD_6);
DigitalOut dc(PD_5);
DigitalOut cs(PD_4);
DigitalOut res(PD_3);
DigitalOut im(PD_0);
接下来是外部变量定义,因为是彩色的LCD,需要从主函数送过来颜色信号:
extern int colo,cor;
接着是字符点阵,因为太多了,本例采用的是8X16的ASCII码和自己定义的16X16的中文,省略了。这种码很容易得到的。
接着的就是关于如何写屏的一些代码,都是模块化的,移植非常方便:
//Write plus
void wri(){
wr=0;wait(0.000001);wr=1;wait(0.000001);//wr=0;wait(0.000001);
}
//Write 2[Or 1] Byte to LCD
void b2l2(int dh,unsigned char com){
rd=1;
cs=0;
dc=com;
mybus=dh;
cs=1;
rd=0;
}
//Clear LCD
void lcdClear(){
int i,j;
b2l2(0x0021,0);b2l2(0x0000,1);//RamAddr:
b2l2(0x0040,0);b2l2(0x0000,1);//GScanPosition:
b2l2(0x0041,0);b2l2(0x00F0,1);//VerticalScrollControl:0x0000->0x00DB
b2l2(0x0042,0);b2l2(0xF000,1);//1st Screen Driving Position:SE17-10|SS17-10:DB00
b2l2(0x0043,0);b2l2(0xF000,1);//2nd Screen Driving Position:SE27-20|SS27-10:DB00
b2l2(0x0044,0);b2l2(0xB000,1);//Horizontal RAM Address Position:HEA7-0|HSA7-0:AF00
b2l2(0x0045,0);b2l2(0xF000,1);//Vertical RAM Address Position:VEA7-0|VSA7-0:DB00
b2l2(0x0022,0);//176x220=0x00,0xAF,0x00,0xDB
for(i=0;i<0xB0;i++){for(j=0;j<0xF0;j++){b2l2(0x0000,1);}}
}
//Set LCD x,y and Full ram
void setXY(unsigned char x,unsigned char y,unsigned char zc){
b2l2(0x0021,0);b2l2(y<<8|x,1);//RamAddr:
b2l2(0x0022,0);
}
//Send a ASCII 8X16dots to LCD,pag[row],col:addr,c:asc2[][]
void c2l(unsigned int pag,unsigned int col,unsigned char c){
unsigned char i,j,zf;
for (j=0;j<8;j++){
  setXY(pag*8,col*8+j,7);
  zf=asc2[c][j];
  for(i=0;i<8;i++){
   if(zf&0x80){cor=colo;}else{cor=0xFFFF-colo;}
   b2l2(cor,1);
   zf=zf<<1;
  }
}
for (j=8;j<16;j++){
  setXY(pag*8+8,col*8+j-8,7);
  zf=asc2[c][j];
  for(i=0;i<8;i++){
   if(zf&0x80){cor=colo;}else{cor=0xFFFF-colo;}
   b2l2(cor,1);
   zf=zf<<1;
  }
}
}
//Send Chineses 16X16dots to LCD,pag[row],col:addr,c:hanzi[c][32]
void h2l(unsigned char pag,unsigned char col,unsigned char c){
c2l(pag,col,(c*2+96));//1/2 chinese
c2l(pag+1,col,(c*2+97));//2/2 chinese
}
//LCD Initial
void lcdInit(void){
//im=0;
res=0;
wait(0.2f);
res=1;
wait(0.2f);
//Chip=S6D0128 176X240
b2l2(0x0000,0);b2l2(0x0001,1);//Start_osc
wait(0.05f);
b2l2(0x0001,0);b2l2(0x001D,1);//OutCtrl:0 VsplHsplDpl Epl SM GS SS 000 NL4-NL0[G1-G240=1D]=001D
b2l2(0x0002,0);b2l2(0x0400,1);//WaveCtrl:000001 B/C EOR 00000000:0x0700/4/5/7
b2l2(0x0003,0);b2l2(0x1030,1);//TRI DFM1 DFM0 BGR 0000 00 I/D1-0 0000=1030
//b2l2(0x0004,0);b2l2(0x0000,1);//?
b2l2(0x0007,0);b2l2(0x1817,1);//DispCtrl1:000 PT1-0 VLE2-1 SPT 000 GON CL REV D1-0=0x1817
b2l2(0x0008,0);b2l2(0x0202,1);//DispCtrl2:0000 FP3-0 0000 BP3-0:1<=BP+FP<=16&BP,FP>=0=0x0202
b2l2(0x000B,0);b2l2(0x0200,1);//FrameCycleCtrl:NO1-0 SDT1-0 ECS2-0 DIV1-0 0 DCREX DCR2-0 RTN1-0=0200
b2l2(0x000C,0);b2l2(0x0001,1);//ExtDispInterFaceCtrl:0000000 RM 00 DM1-0 00 RIM1-0=0001
wait(0.0005f);
b2l2(0x0010,0);b2l2(0x0B20,1);//PowerCtrl1:00 SAP2-0 BT2-0 DC2-0 BT3 00 SLP STB=0x0B20
wait(0.0005f);
b2l2(0x0011,0);b2l2(0x2801,1);//PowerCtrl2:00 GVD5-0 00000 VC2-0=0x2804
wait(0.0005f);
b2l2(0x0013,0);b2l2(0x0070,1);//PowerCtrl3:000000000 PON PON1 AON 0000=0x0070
wait(0.0005f);
b2l2(0x0014,0);b2l2(0x231D,1);//PowerCtrl4:0 VCMR VCM5-0 00 VML5-0=0x231D
wait(0.0005f);
b2l2(0x0021,0);b2l2(0x0000,1);//RamAddr:
//b2l2(0x0022,0);//AfterWriteDataToRAM
wait(0.0005f);
//Gama Setting0x0030->0x0039
b2l2(0x0030,0);b2l2(0x0000,1);
b2l2(0x0031,0);b2l2(0x0505,1);//b2l2(0x0505,1);
b2l2(0x0032,0);b2l2(0x0104,1);//b2l2(0x0104,1);
b2l2(0x0033,0);b2l2(0x0204,1);//b2l2(0x0204,1);
b2l2(0x0038,0);b2l2(0x0600,1);//b2l2(0x0600,1);//0100
b2l2(0x0034,0);b2l2(0x0306,1);//b2l2(0x0306,1);
b2l2(0x0035,0);b2l2(0x0202,1);//b2l2(0x0202,1);
b2l2(0x0036,0);b2l2(0x0707,1);//b2l2(0x0707,1);
b2l2(0x0037,0);b2l2(0x0402,1);//b2l2(0x0402,1);
b2l2(0x0039,0);b2l2(0x0202,1);//b2l2(0x0202,1);//0002

b2l2(0x0040,0);b2l2(0x0000,1);//GScanPosition=0000
b2l2(0x0041,0);b2l2(0x00DB,1);//VerticalScrollControl垂直滚动:0x0000->0x00EF[239=EFh]
b2l2(0x0042,0);b2l2(0xAF00,1);//1st Screen Driving Position:SE17-10|SS17-10:AF00
b2l2(0x0043,0);b2l2(0xAF00,1);//2nd Screen Driving Position:SE27-20|SS27-10:AF00
b2l2(0x0044,0);b2l2(0xAF00,1);//Horizontal RAM Address Position:HEA7-0|HSA7-0:AF00
b2l2(0x0045,0);b2l2(0xEF00,1);//Vertical RAM Address Position:VEA7-0|VSA7-0:EF00
wait(0.01f);
}
void dispAsc(){
int i,j,k=0;
for(i=0;i<11;i++){
  for(j=0;j<26;j++){
   c2l(i*2,j,k);
   if(k<145) k++;else k=0;
  }
  //colo+=0x377F;cor=0xFFFF-colo;
}
}

主函数main中:
#include "mbed.h"
#include "21lcd.h"

//Define Output GPIO
DigitalOut led1(PB_0);
DigitalOut led2(PB_7);
DigitalOut led3(PB_14);

int colo=0x037F,cor=0xFC00;

//LED TEST
void led(void){if(led1){led1=0;led3=0;led2=1;}else{led1=1;led3=1;led2=0;}}

int main(){
im=1;
lcdInit();
lcdClear();
while(true){
  colo+=0x377F;cor=0xFFFF-colo;
  dispAsc();
  led();
  wait(0.5);
  lcdClear();
}
}
由于程序仅仅是为了测试驱显16位并口TFTLCD,因此持续的作用就是将所有ASCII码和汉字显示出来,定时0.5秒后清除。没有具体应用。
下载程序后运行结果见照片x2。视屏见:http://v.youku.com/v_show/id_XMjY1NjI3MzE4MA==.html。
有问题欢迎讨论,谢谢。注意,所用的IO口,没有Arduino的。


x1-两个双排2.45插座的管脚序列.jpg (226.44 KB )

x1-两个双排2.45插座的管脚序列.jpg

x2-STM32F412驱显16位并口TFTLCD.jpg (312.21 KB )

16位并口TFTLCD驱显

16位并口TFTLCD驱显
沙发
kkzz| | 2017-3-24 16:50 | 只看该作者
mbed还能驱动LCD?

使用特权

评论回复
板凳
kkzz| | 2017-3-24 16:56 | 只看该作者
跟楼主是多多学习NUCLEO-F412ZG

使用特权

评论回复
地板
zhjb1|  楼主 | 2017-3-24 22:30 | 只看该作者
kkzz 发表于 2017-3-24 16:50
mbed还能驱动LCD?

用他的BusOut方式,但我知道的可以设置16位,如果是真彩的24位,还没有想好如何设置。但是再说吧。

使用特权

评论回复
5
稳稳の幸福| | 2017-3-25 15:43 | 只看该作者
干的漂亮,412虽然是入门级,但是强大的没法说。

使用特权

评论回复
6
i1mcu| | 2017-3-25 22:47 | 只看该作者
跟楼主多多学习mbed

使用特权

评论回复
7
i1mcu| | 2017-3-25 22:53 | 只看该作者
以前都是使用宏定义实现的移植。

使用特权

评论回复
8
heisexingqisi| | 2017-3-26 16:58 | 只看该作者
代码老长了,听说MBED部分的显示屏可以直接一个指令就驱动起来。

使用特权

评论回复
9
eefas| | 2017-3-26 22:43 | 只看该作者
能不能上传一下工程文件。

使用特权

评论回复
10
eefas| | 2017-3-26 22:44 | 只看该作者
mbed集成了TFTLCD的驱动吗?

使用特权

评论回复
11
zhjb1|  楼主 | 2017-3-27 07:49 | 只看该作者
eefas 发表于 2017-3-26 22:44
mbed集成了TFTLCD的驱动吗?

好像没有,需要自己写

使用特权

评论回复
12
zhjb1|  楼主 | 2017-4-2 17:46 | 只看该作者
eefas 发表于 2017-3-26 22:43
能不能上传一下工程文件。

所有的工程文件都在上边,没有多余的了

使用特权

评论回复
13
zhjb1|  楼主 | 2017-4-2 17:46 | 只看该作者
eefas 发表于 2017-3-26 22:44
mbed集成了TFTLCD的驱动吗?

mbed没有集成TFTLCD驱动,需要自己写初始化和驱显,上述程序都有了

使用特权

评论回复
14
hellosdc| | 2017-4-2 22:48 | 只看该作者
代码是自动生成的?

使用特权

评论回复
15
hellosdc| | 2017-4-2 22:51 | 只看该作者
以前就是使用宏定义实现的LCD移植的。

使用特权

评论回复
16
zhjb1|  楼主 | 2017-4-3 22:22 | 只看该作者
hellosdc 发表于 2017-4-2 22:48
代码是自动生成的?

代码不会自动生成,mbed只是将底层的寄存器、硬件相关的东西都封装好了。编程者只需要按照定义对象、类、属性、方法的操作方式就可以了。

使用特权

评论回复
17
zhjb1|  楼主 | 2017-4-3 22:23 | 只看该作者
heisexingqisi 发表于 2017-3-26 16:58
代码老长了,听说MBED部分的显示屏可以直接一个指令就驱动起来。

Arduino可能具有这个能力,mbed不可能有这种能力的。

使用特权

评论回复
18
usysm| | 2017-4-3 22:52 | 只看该作者
TFT触摸控制做好了吗

使用特权

评论回复
19
usysm| | 2017-4-3 22:53 | 只看该作者
现在有SMT32F4的宏定义移植算法。

使用特权

评论回复
20
pklong| | 2017-4-4 21:57 | 只看该作者
mbed离线开发包

使用特权

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

本版积分规则

个人签名:永远好心情 [img]https://bbs.21ic.com/static/image/s

35

主题

194

帖子

1

粉丝