还剩24页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
菜鸟学习led编程的起步首先再次声明我是菜鸟,我写出来的目的是给没有接触过led的伴侣看得,我本人水平有限,错误在所难免,欢迎指出之所以产生写这个东西的想法,是由于趁着寒假这段时间看了看学习板的源程序,在看led的时候很不顺当,花了五个晚上才看完(白天偷懒了八一八!,究竟在春节嘛)联想起还有很多水平和我差不多甚至可能还低一点的菜鸟,就觉得有义务把五个晚上的学习心得写出来,顺便也给自己整理整理思路,嘿嘿这个心得是针对学习板上的led驱动芯片SSD181X系列写的,当然思想应当是相通的其实是我没有用过其它系列led(众人呕吐ing)首先你要去网上下载一个SSD181X系列的PDF文件,这种文件网上处处都是,偶就不多说了刚开头需要借用51论坛电子白菜大虾的文章作为总领,由于偶比较懒,不想写这么多拉〜〜〜(不要飞鸡蛋)当然还是有部分内容增加的拉我介绍的这个是MOTO的手机屏,大小为96*54(96列54行)不过这个小小的LCD屏也是很不错的对比度可调,而且还有背光)具体驱动器是SSD1815,是黑白点阵驱动芯片,最多支持132个SEG和64个COM,还有一个ICON(功能设置)行说起SEG,COM,或许很多人没接触过,其实玻璃屏的LCD都是使用SEGCOM的扫描来驱动的,为便需要点亮的内容呈显示状态,须将沟通驱动电压加在LCD的段电极与公共电极之间原理涉及物理化学问题,这里就不多说,只打个比方一个‘井字,是两行两列组成的,共有四个交点,其实就好比是2个SEG,2个COM,要驱动一个固定的点,要相应的一条COM和一条SEG都有效假如要几个点亮,几个点灭,就需要用到扫描的原理,还记得行列键盘的原理吗?其实它的驱动原理就差不多了)上面说的它支持132个SEG,64个COM,所以它支持最多132*64个点的LCD但实际上假如我们的LCD没有那么多个点话,就需要在上电的时候对1815进行初始化,指定COM和SEG的数目,还有BIAS数,说至“BIAS,唉,又是个专业问题了,LCD的驱动波形由几级电平组成,为防止对比度不匀称,在不点亮象素对应的电极上仍加有肯定电压,这对降低点亮象素产生的交叉干扰和防止对比度不匀称很重要LCD中非点亮象素(非选点)的电压有效值与点亮象素(选择点)电压有效值之比(1/n)称为偏压比的确比较难以理解,你可以这样看BIAS是电平强度,和COM有关的东西以上这些都要在LCD上电的时候歹U写入0没想到吧?呵呵,由于液晶上一个字节的显示是竖的一排排的,存储在GDDRAM中当然也是竖着拉〜也就是一列代表一个字节8位八_八刚才我们把工作模式设置为读一改一写现在当然要结束这个模式啦,这就是wricmdOxee这个语句所起的作用最终连续循环Cis的工作就完成了/si#kJ^/show_ascucharch;//vlxk1*kiKlk1vjkIk|7,KlvlkIkT^kJk£//^TW«、〃、〃、1^*T*力、〃初始化液晶ucharlcdlight=32;voidinitlcdvoid{P2=0x00;〃P2作为总线时,其寄存器的值对总线没有影响〃初始化为0,是为了更好的协作液晶的6800总线motorola的液晶内部固定了680总线方式〃假如液晶是808总线,则无需这样做wricmd0x2f;//SETPOWERCONTROL,开启一系列与电源有关的功能wricmd0x20;//REGULATORRESISTORSELECT,内部反馈增益最小wricmd0x81;wricmdlcdlight;设置对比度值wricmd0x40;〃设置初始显示线,从哪里开头是玻璃上的布线打算的wricmdOxaO;//ADC=OSEGl-SEG132wricmd0xc8;//SHL=0COM1〜COM64wricmd0xa2;〃设置LCDBIAS为1/9cis⑼;〃全部清除包括iconwricmdOxaf;〃开启显示,也就是把GDRAM上的数值显示到屏上setcursor00;〃设置光标到左上角.上*1**1^sixsix/.J、.、■卜卜■.、■;、卜■卜“卜・卜■[、.、■卜■卜卜・卜■[、■.、■[、卜卜卜■.、■、卜■卜•卜•卜■[、.、■卜■卜卜・卜■[、■.、■[、卜/到这里,就正是进入我们的初始化了什么?弄了半天你还没有讲初始化啊?各位看官不要焦急,此初始化非彼初始化也刚才我们讲的都是整个程序的初始化,而现在我们进入的是液晶屏的初始化让我们看看这个过程吧首先是ucharlcdlight=32,顾名思义,这个参数的作用就是调整led对比度的拉motorola的液晶默认对比度为32先让lcdlight=32,到时候采用wriemd函数‘直接一个wriemdIcdlight语句‘多便利〜八—八闲谈少说,接着往下看下面是一个initlcd函数,这是可是如假包换的液晶初始化函数液晶在每次上电使用都需要初始化,而大多数初始化程序我们都可以不去理睬,由于那些都是依据说明书所说的,用于设置COM数和SEG数还有BIAS值的这里再解释一下P2=0x00;的作用开头的时候我们就说过,这个液晶使用的是6800总线,这段,其实是为了兼容6800总线加上的,LCD的D/C脚在一开头的时候应当设为(),也就是写成P22=0;就可以了,P22就是接到LCD的D/C脚上的此外再提示一点,一些必需的值,如COM,SEG,BIAS,显示模式等,在使用中这些设置用户是不应当转变的到这里,LCD初始化正式完成,已经可以供用户正常使用了/si#si#/,j、•、卜■卜卜■.、■卜■卜卜,卜,]、•、卜卜卜,卜,:、,[、,卜卜•卜■.、)、[、■卜卜•卜,]、•[、卜卜卜,卜,:、■.、・[、卜卜show_ascucharchuintaddr;ucharhzdata
[16];ucharxdoti;addr=16*ch;readepromaddrhzdata16;〃读出16个字节的点阵数据xdot=cursor.x*8;wricmdOxbO+cursor.y;〃将y位置送入液晶wricmdxdotOxOf;〃将x位置送入液晶wricmd0x10|xdot»4;wricmdOxeO;fori=0;i8;i++wridatahzdata[i];〃写上半个字符wricmdOxee;wricmdxb+cursor.y+1;wricmdxdotOxOf;wricmd0xl0|xdot»4;wricmdOxeO;wridatahzdata[i];wricmdOxee;}要理解这段程序,必需先知道点阵表示的含义我们知道,字母和汉字是按字模位信息显示的,那如何得到汉字的字模信息呢?莫非要我们自己去做?NODOS前辈们经过艰辛的努力,将制作好的字模放到了一个个标准的库中以免去后辈的麻烦,这就是点阵字库文件一般我们使用16*16的点阵宋体字库,所谓16*16,是每一个汉字在纵、横各16点的区域内显示的,前一个16表示列,后一个十六表示行不过后来又有了HZK
12、HZK24,HZK32和HZK48字库及黑体、楷体和隶书字库这段程序是用来在当前光标位置显示一个6x12点阵的ASC码字符的其实标准的ASC码字符应当是8x16点阵区域表示,这也就是为什么我们常说“一个汉字占据两个字符位的缘由表示的是asc字符的值首先说明一点,一个ASC字符分两部分显示,也就是说,把分为上下两个“半ASC码字符”汉字同样应当如此显示当然这只是我们目前介绍的这个led的特性假如你使用的是别的种类,千万不要生搬硬套,肯定要认真阅读说明书再回头看程序首先就是一堆定义,无符号整形数addr表示的是点阵在flash中的物理位置,表示ASC码字符”’的字符点阵占据的物理位置是0—15为什么?你看,16*8点阵区域,一个点用Ibit表示「0就是灭「1就是亮,那么总共128bit,是不是就是16byte同理,字符2是16-30,以此类推所以addr=16*ch比如我传递迸来的ch是4,贝”addr为64而hzdata这个数组是用来存储读出的数据的Xdot表示的是横向点位置,在下面我们可以知道它的计算公式是cursor.x*8,就是光标横坐标值乘以8由于之前我们将光标设置在左上角,所以cursor.x为,因此此时横向点位置也为0假如我们已经显示了一个ASC字符,此时的cursor.x就应当为1,那么xdot就应当为8这应当很好理解,从点阵区域的大小我们可以知道一个ASC码字符从横坐标上看占用的是8个点0—7,下一个ASC码字符当然应当从8开头拉接下来是readepromaddrhzdata16这个函数什么意思呢?由于它是属于此外一个.c文件,这里只是给出原型Readeprom函数原型如下readepromulongaduchar*pstuintnunion{ulongaddr_l;struct{uinta32;uintalO;}addr_i;struct{uchara3;uinta21;ucharaO;}addr;}address;uinti;ucharxdata*flash;Pl=0xff;//Pl口如被占用暂停读取whilePl!=0xff;address.addrl=ad;Pl=Pl0xc0|address.addr.a21/0x20;//设置bank线,每块8K字节flash=0x8000+address.addr_i.a10%0x2000;//flash窗口地址范围0x8000—0x9fffffori=0;i读N个字节〃*pst++=*flash++;ifflash==OxaOOO〃假如地址跨页贝U翻到下一个bankP1++;flash=0x8000;在这里我们就不单独解释了,只是说说他的或许作用,即读N个flash中的字节每次最多65535字节入口参数的含义分别是ulongad为字符在flash中的物理地址,uchar*pst表示读出来放在内存中的指针首位置,uintn表示读出多少个字节也就是说,readepromaddrhzdata』6后,我们已经把表示ch需要用的16个字节传到了hzdata数组中,到时候就可以直接拿来用了在接下来是送x,y的位置,为什么y位置是OxbO+cursor.y呢?OxbO是一个命令指令,表示设置page刚才说了,一个page是8行组成,也就是说高8个点,也就是说一个字符或者汉字都应当由两个page来供应数据刚才还说了,显示是分上下两半部分组成的,所以先page设置成OxbO+cursor.y,然后再设置成OxbO+cursor.y+1‘这样是不是先后选中两个page嘿嘿,很顺理成章吧?由于我们这个系列led默认是132点宽,所以横向点的数目也就是列地址至少需要8位表示才够了7位只有128,但是x位置送的列地址是xdotOxOf高8位的4个是命令标志,只有低4位,明显不能表示完怎么办呢?我们就分两步送,先送低4位,再说高四位忘了这个设置列地址的指令?回头去看看els函数中的内容吧八_八°高4位怎么送?wricmd0x10|xdot»4;这是设置高4位列地址的指令低四位表示列的高地址连续wricmdOxeO的作用是设置成读一改一写模式这个前面已经介绍过了在接下来就是送我们要送显的数据到GDDRAM中的过程了,这个过程很简洁,大体就是一列一列的送,送了一个字节后列GDDRAM中的列地址自动加一,数组下标也加一,然后再连续送,其实我们从els函数的过程中就能领悟到送完上半部分,凹凸列地址重新送,page+1,再重复这个过程具体指令就不介绍了,聪慧的你肯定能够理解〜呵呵show_hzucharchiucharch2ulongaddr;ucharhzdata
[32];ucharxdoti;ifchl=OxbO〃寻址汉字在flash中的物理位置addr=ch1-0xb0*94+ch2-0xal;addr=addr*32+0x5a40;elseaddr=ch1-Oxa1*94+ch2-0xal;addr=addr*32+0x800;readepromaddrhzdata32;〃读出32个汉字点阵数据xdot=cursor.x*8;〃计算X位置wricmdOxbO+cursor.y;wricmdxdotOxOf;wricmd0x10|xdot»4;wricmdOxeO;fori=0;i16;i++〃显示上半个汉字wridatahzdata[i];wricmdOxee;wricmdOxbO+cursor.y+1;wricmdxdotOxOf;wricmd0x1|xdot»4;wricmdOxeO;for;i32;i++〃显示下半个汉字wridatahzdata[i];wricmdOxee;初始化好,才能正确地显示图文°1815还自带显示RAM,英文是GraphicDisplayDataRam就是图象显示数据存储器,简称GDRAM对于现在很多现成的LCM屏来说,掌握芯片都带有了GDRAM的,大小就和他的最大显示点数相当我估量你看到现在还是一头雾水,呵呵,没关系,当时我看的时候也是一头雾水,看到后面你就会明白他们的原理了接着是1815的接口问题了,它支持8080,6800I2C总线8080,就是和我们51一样的总线,有CS,WR,RD,然后是数据地址线;6800又叫摩托罗拉总线,有R/W,E,然后是地址数据线;12c总线,呵呵,当然就是12c总线咯,还用说么?由于这个是摩托罗拉的LCD屏,出厂的时候已经配置为6800总线了,所以我们不能用正常的51总线来驱动,但实际上6800是可以兼容8080总线的,先等我介绍下这个总线吧R/WW读写脚,为1的时候是读,0的时候是写E脚使能脚,功能犹如51总线的CS,也是低有效的,但数据D0-D7在高的时候锁存D/C脚,这个是数据,命令选择脚,1的时候代表总线传输的是数据(不论是读还是写),的时候代表总线传输命令(不论是读还是写)D0-D7:理所当然的数据脚咯驱动原理很简洁,在E为低的时候对R/W脚输入读写信号,读就是1,写就是0;然后选择你读写的是数据还是命令,D/C脚1为数据,0为命令;最终就是数据脚的数据了以上原理,用单片机10做是很简洁的事情,不过使用10的缺点就是不能复用,铺张了很多的资源,所以在学习板上是使用总线驱动LCD的之前说了,某些680总线是可以用8080总线模拟的,而这个LCD就是可以使用8080总线的了6800总线读写掌握只需要1只脚R/W,1为读()为写,而8080总线是两只脚RD,WR,其中的某个脚为低就对应响应功能依据这个规律关系,我们很简洁就猜想到为什么6800的R/W脚可以直接接上8080的WR了这些都是垫场的开场白拉接下来我就以丁丁编写的1815的使用程序,来介绍使用1815驱动led的具体步骤为了让大家能够理解清晰,我肯定依据分段的形式,一段一段解释当然由于本菜鸟水平有限,假如解释错误还请大家不吝赐教开头的程序我会讲的很细,后面的我就讲个或许了,只要理解了这个过程就不难了这个程序的作用就是在当前光标位置显示一个16*16汉字或者全角字符入口参数chi表示该汉字的区码,入口参数ch2表示位码说到这里可能有一些伴侣不理解了下面我来讲一下前面已经介绍了汉字库的一些学问,虽然汉字库种类繁多,但都是依据区位的挨次排列的前一个字节为该汉字的区号,后一个字节为该字的位号每一个区纪录94个汉字,位号则为该字在该区中的位置因此,汉字在汉字库中的具体位置计算公式为94*(区号-1)+位号-1减1是由于数组是以为开头而区号位号是以1为开头的这仅为以汉字为单位该汉字在汉字库中的位置,那么,如何得到以字节为单位得到该汉字在汉字库中的位置呢?只需乘上一个汉字字模占用的字节数即可,即(94*(区号-1)+位号-1)*一个汉字字模占用字节数,而按每种汉字库的汉字大小不同又会得到不同的结果以16*16点阵字库为例,计算公式则为(94*(区号-1)+(位号-1))*32汉字库文该从该位置起的32字节信息即纪录了该字的字模信息Ok,明白了这些,这个程序就很好理解了,其实质是和我们分析的上一个显示ASC字符的程序是差不多的,首先除了定义,就是寻址汉字在flash中的物理位置由于在中文环境下,输入的是汉字的内码,我们必需将之转换成区位码,算出偏移量,从字库中找到对应的汉字,将其字模显示即可内码转换成区位码方法如下qh=c1—OxaOwh=c2—OxaO其区位码就是qw=qh*Oxff+wh该汉字在字库中离起点的位置是offset=(94*(qh—l)+(wh—1))*32L其它步骤和上一个函数几乎一模一样,就不多废话了/*1*kL*k1**1**1**fk|*A**A*kL*kL*k|*1kL*kL**t*k|*1kL*kL**1**f*1*1*1**L*k|*1/*i**T^^TwrT^rr**T**T**T*^T*^T**g**Trj*rj**T**T*voidsetcursorucharxucharyifx=LCD_MAX_Xcursor.x=x;elsecursor.x二LCDMAXX;ify=LCD_MAX_Ycursor.y=y;elsecursor.y=LCD_MAX_Y-1;kL*kL*kL*kivl*kikikL**1*1^kI*1vf^^L*ki^/[、[、J、,卜rr^^1%、、〃、
1、〃、—、、]、,卜力、[、元、〃、、〃、[再看接下来的这个程序这个程序的作用是设置光标位置,以8x8点阵为一个光标单位,人口参数表示x方向和y方向光标位置LCD_MAX_X和LCD_MAX_Y的含义和计算公式在刚开头的时候我们就已经说过了至于这里为什么是LCD_MAX_Y-1,前面已经说了一个字符或者汉字都应当由两个page来供应数据,现在我需要在7,8页显示东西,那么我应当是把纵坐标点设置到7页吧?呵呵,其实点破就很简洁了/vi7k1k17,7*ivikl7kJk17k|k|7,^1*kJk1*kl7,kJ^1*ki7,7/J*,J*J*rT*-J**1%-J*力、*T-J*-J*7^〃、voidlcdstringuchar*pstwhile*pst!=0if*pst0x80〃小于0x80是字符if*pst==0x0asetcursor0cursor.y+2;〃处理回车换行elseif*pst==OxOdsetcursor0cursor.y;elseshow_asc*pst;〃显示ASC字符cursor.x++;ifcursor.xLCD_MAX_X*pst+1!=0x0a{cursor.x=0;cursor.y=cursocursor.x=0;cursor.y=cursor.y+2;ifcursor.yLCD_MAX_Ycursor.y=;//show_hz*pst*pst+l;〃显示一个汉字cursor.x+=2;pst+=2;ifcursor.xLCD_MAX_X*pst+1!=OxOa{cursor.x=0;cursor.y=cursor.y+2;}ifcursor.yLCD_MAX_Y{cursor.x=0;cursor.y=0;return;}7,7,7,7,7,7,Kt7,7,7,//这个程序呢,也就是我们这篇文章介绍的内容的中心程序!地位重要吧那么他的作用是什么呢?就是在当前光标位置显示字符串拉入口参数就是要显示的字符串更关键的是同时也显示汉字!什么?你还是没有理解到这个东西的好处?这样说吧,只要你的程序中包含我们所介绍的这些程序,那么在应用程序中,我们假如想让led显示“风”,那么我们就直接lcdstring“风”就行了哈哈,这么奇妙的功能,实现起来其实是很简洁的拉下面我门就一起来分析分析这个函数首先是字符处理函数前面的whileif语句中的内容都很好理解,大家看程序注释就行了‘这里我要说的是if*pst==OxOasetcursor0cursor.y+2;这句是处理回车换行为什么?由于0x0a在asc码表中就是表示换行的,而接下来的OxOd是表示回车的,还有后来汉字显示需要用的0x20表示space呵呵,由于我当时看的时候半天没有找到asc码表,为了避开让大家也都去找,这里直接说出来了为什么是cursor.y+2呢?信任大家已经知道答案了什么?你不知道?ohyeah,请看上一页〜这里有必要再讲讲cursor.x++;这句为什么是cursor.x自增一?横坐标一个字符不是占用8个点么?千万不要忘了,横坐标的点是用xdot表示的计算公式是什么呢?xdot=cursor.x*8;明白了吧?接下来就是汉字处理部分其流程和前一部分完全一样,只不过cursor.x和pst都是自增2,缘由当然是由于汉字是由区码和位码打算的,因此占用的字节数是字符的两倍〜呵呵,你看看显示汉字的语句不是show_hz*pst*pst+l么到这里,我们的学习历程就基本结束了整个程序的精华已经给大家介绍完了当然最终还剩两个“在当前光标以十迸制方式在液晶上显示一个字节的值”和“在当前光标显示一个ASC字符”两个函数,不过特别简洁,这里只是作为附录附在后面,有爱好的伴侣可以试试自己分析一下这只是很多种led掌握器其中一种的使用方法但是不要怕,我这几天又看了看其它的驱动掌握器,原理其实是一样的,只不过是实现功能的程序可能不同,所以最关键的还是要理解思想思想理解了,学别的类似东西也就相通了盼望看到这个文章各位都能获得一些学问和心得假如能够关心你,将是我莫大的荣幸附录://si^six//ry*〃在当前光标以十迸制方式在液晶上显示一个字节的值〃入口:要显示的值lcddigitucharchuchari
[4];i
[0]=0x30+ch/100;i[l]=0x30+ch%100/10;i⑵二0x3+ch%10;i
[3]=0;〃添加结束符号lcdstringi;〃在当前光标显示一个ASC字符〃人口:要显示的字符lcdcharucharchuchari
[2];i[O]=ch;lcdstringi;留意哦,这个程序是来自”51单片机世界”,作者版主丁丁(聂小猛),未经允许,不得抄袭作为商业用途/^9^^9sl^k1^k1^^9^1#/^|*^r**4^1^*g^*T*#defineucharunsignedchar#defineuintunsignedint#defineulongunsignedlong#include#include#includestudy.h#defineLCMDXBYTE[0xAf00]〃液晶数据口#defineLCMCXBYTE[0xAb0]〃液晶命令口#defineLCD_DOT_X98//led的宽点数#defineLCD_DOT_Y54//led的高点数#defineLCD_MAX_X11//每行字符,LCD_MAX_X+1*8A#defineLCD_MAX_Y5〃共多少行,LCD_MAX_Y+1*8点假如你写过单片机程序,就会知道任何程序的初始化阶段都是这么些步骤,定义再定义,最终是某些功能的初始化函数这些就是刚开头的声明定义过程前面的几个define,include我就不多说了,假如你连这个都看不懂,只能先去补习补习c语言了#defineLCMDXBYTE[OxAfOOJ^#defineLCMCXBYTE[OxAbOO]两句是用来定义外部总线接口地址的OxAfOO用来传递数据,OxAbOO用来传递命令,之前说过,是传输命令还是数据主要是取决于A10的,上面两个地址对应的A10其实就是0xaf00-〉A10=l,0xab00-〉Al0=0照电子白菜大虾的话说,地址的取值只要确保在A000〜AFFF之间就可以了,所以以下定义一样能正确驱动LCD:#defineLCMDXBYTE[0xA400]〃液晶数据口#defineLCMCXBYTE[xA0]〃液晶命令口虽然地址不同了,但对A10的作用依旧不变接下来的两句则是用LCD_DOT_X来表示led的宽点数,LCD_DOT_Y表示高点数想象坐标轴,呵呵,是不是好理解了?这就说明我们现在用的led是LCD_DOT_X宽LCD_DOT_Y高的最终两句则是告知我们,这个led可以显示5行,每行11个字符这些参数都是可以依据led不同而变化的/777777777777777777/•卜•卜・卜•卜,丁、•卜,卜•卜q.•卜•卜rj*•卜•卜・卜,丁、q.・卜•卜•卜,卜•卜•卜structcursortypeucharx;uchary;;structcursortypecursor;voidwridataucharchLCMD=ch;voidwricmducharchLCMC=ch;1^^Xk1#s£^Xk1^1^1#k1#X/,卜,j.•[、卜7卜.
1、■.、■、■卜卜卜,卜,、•[、卜卜卜.卜.[、■.、■[、■卜卜.卜,[、■.、•;、卜卜•卜.[、,、•[、卜■[、卜.卜.[、■]、]、卜/这几句也都属于初始化步骤首先structcursortype这个结构体是用来定义光标的,光标在屏幕上当然可以用x和y两个值表示,这样我们到时候用cursor.x或者cursor.y确定光标位置就便利多了Wridata和wricmd两个函数则是写数据和写命令功能认真看,LCMD就是液晶数据口5LCMC就是液晶命令口峨们对他们迸行的操作实际上就是对OxAfOO或OxAOOO地址迸行操作例如我们用wridata0x33,也就是说我们把0x33这个数据通过OxAfOO这个外部总线接口地址送到SSD181X中由于是OxAfOO的地址,A10必定为1,掌握器就知道此时你要传递的是数据拉〜怎么样很便利吧voidlightucharnLCMC=0x81;LCMC=n;把这个程序单独列出来是由于想讲讲程序如何传递能够作用的有效参数首先这是一个调整led亮度(其实更加严格得说是对比度)的函数我们看到他用的LCMC,说明此时我们是发送程序给led,让他知道我们要调整亮度了那么究竟传递什么东西,掌握器才能知道我们的意图呢?不用担忧,pdf上会告知你按什么格式发送指令给掌握器才有效这是SSD181Xpdf上面的格式之一为了便利我只截取其中一个功能设置来进行说明最左边的数字表示你发送的命令必需是这样的格式,中间的英文表示该格式命令所起的作用,右边的文字表示这些XXXX,也就是不确定数字的值该如何选取才能获得我们想要的效果就以这个方框为例吧,首先我们看中间这个小方框,它告知我们这条指令的作用是设置对比度寄存器,也就是说我们可以通过对该寄存器的修改来实现调整对比度得调整那么具体如何调整呢?我们再来看看最左边的方框,这个内容告知我们,我们需要用LCMC发送两个字节数据,其中一个字节是固定的10000001就是0x81,其次个字节则是自己打算怎么打算呢?再看看第三个小方框吧嘏如你e文好,立刻就能看懂它的意思假如你e文不好…・・・嘿嘿,建议金山词霸!(倒,谁扔的香蕉皮!)这里的意思就是说,对比度分为64个等级,这样XXXXXX6位二进制数就可以表示完,那么我们需要用哪个等级就设置哪个数,比如现在我们需要等级n的对比度,因此程序中消失了LCMC=n这个n哪里来的?voidlight(ucharn),嘿嘿,主函数传递进来的呵呵,现在明白命令是怎么传送的了吧?一会儿还有例子,假如不明白不要惊慌voidclsucharchucharij;forj=OxO;jwricmdOxbO+j;//setpage//101Ixxxxwricmd0x10;//setcolumnmsbwricmdOxO;//setcolumnIsbwricmdOxeO;//setmodify-readmodefori=0;i98;i++wridataOxOO;//填满0即清屏wricmdOxee;//resetmodify-readmode这里就开头迸入实质性的编程部分了这是一个清屏函数,传递的参数ch=9就表示连带ICON一起清除,隹旻如ch=8则表示不清除ICON这里的ch实质上表示GDDRAM中的page页面值这里有点难以理解先看看GDDRAM是怎么构成的这是pdf中关于GDDRAM地址分布图的说明,我们可以从这里清晰看到page的概念一个page实际上是一个拥有8个高点的行,64点高的屏幕就有8个page,每个page的宽度都是和整个RAM宽度是一样的从pdf的最开头我们就可以看到1815的特性是132x64+1iconline,也就是说高为64,换算过来就是8个page而GDDRAM的数据分布图与led实际的数据显示图是完全全都的,实际上led的显示的就是GDDRAM的映射因此我们清屏的目的就是为了清除GDDRAM中的值因此从forj=x;j语句中我们得知,循环次数是由ch打算的假如ch=8,那么循环8次,就只能清除这8个page页面只有ch=9,才能清除最终的那一个1iconline好,我们接着往下看进入循环之后,程序要做的事就是一个page一个page得清除信息首先wricmdOxbO+j,翻翻pdf,找到相关信息:这下知道了,这个语句的意思就是选择要进行读写操作的页面由于总共只有8个页面,所以4个不确定位就够拉这也就是wricmd的参数是OxbO+j”的缘由page数只由j,也就是ch掌握接下来两句wricmdOxlO和wricmdOxO,我们同样可以通过pdf的信息得知,作用时用来设置列的低地址和列的高地址参数高四位为0001的表示设置高地址,0的表示设置低地址默认状况下凹凸地址均为0X0000接下来就是设置工作模式wricmdOxeO°这个语句的作用是setread-modify-readmode,就是设置成读一改一写模式???????????最终把本次循环我们选择的page填0,也就达到了请零的目的需要留意的是I的范围是0—97,为什么?由于我们现在举例用的led宽点数只有98owridataOxOO的作用是把某一。