MSP430单片机驱动LCM240128液晶显示汉字和字符数字

代码如下,没有验证,请需要的同志自己验证:

  1 //器件:LCM2401282ZK
  2 //控制器:T6963C
  3 //日期:2009.06.15
  4 #include <msp430x14x.h>
  5 #include "LCM2401282ZK.h"
  6 //============================控制线定义========================================
  7 #define WR1   BIT3           // WR1 = P5.3
  8 #define RD1   BIT2           // RD1 = P5.2
  9 #define CE    BIT1           // CE  = P5.1
 10 #define CD    BIT6           // CD  = P3.6
 11 #define FS    BIT0           // FS  = P5.0
 12 #define RST   BIT7           // RST = P3.7  正常情况下,5个低电平信号实现复位,然后高电平进入正常工作状态
 13 #define WR1_0  P5OUT &= ~WR1
 14 #define WR1_1  P5OUT |= WR1
 15 #define RD1_0  P5OUT &= ~RD1
 16 #define RD1_1  P5OUT |= RD1
 17 #define CE_0   P5OUT &= ~CE
 18 #define CE_1   P5OUT |= CE
 19 #define CD_0   P3OUT &= ~CD
 20 #define CD_1   P3OUT |= CD
 21 #define FS_0   P5OUT &= ~FS
 22 #define FS_1   P5OUT |= FS
 23 #define RST_0  P3OUT &= ~RST
 24 #define RST_1  P3OUT |= RST  // 控制线输出高、低电平定义
 25 unsigned char cradd1,cradd2,dat2,dat0,com,ctrlcode;
 26 unsigned char urow,ucol,h;
 27 unsigned char STA;          //用于存放p4口的状态
 28 //==============================================================================
 29 //                        定义的汉字字库
 30 //==============================================================================
 31 const unsigned char hztab_bzj[175][32]={
 32            };// 这里自己定义字库
 33 //==============================小延时==========================================
 34 void short_delay(unsigned int i)
 35 {
 36   unsigned int j;
 37   for(j=0;j<=i;j++);
 38 }
 39 //==============================延时ms级========================================
 40 void delayms(unsigned char tickms)
 41 {
 42   unsigned int count,i;
 43        _NOP();
 44        _NOP();
 45        _NOP();
 46        for(i=tickms;i>0;i--)
 47          { for(count=0;count<4000;count++) {;}
 48            _NOP();
 49          }
 50 }
 51 //==============================写显示数据子程序(左)==========================
 52 void wrdata(unsigned char dat0)
 53     {
 54       unsigned char cradd1;
 55       CD_1;
 56       CE_0;
 57       do
 58       {
 59         P4DIR=0xff;             //P4口设置为输出
 60         P4OUT=0xff;
 61         RD1_0;
 62         P4DIR=0x00;             //P4口设置为输入
 63         cradd1=P4IN;
 64         RD1_1;
 65       }
 66       while((cradd1&0x03)==0) ;
 67       P4DIR=0xff;               //P4口设置为输出
 68       P4OUT=0xff;
 69       CD_0;
 70       P4OUT=dat0;
 71       WR1_0;
 72       WR1_1;
 73      }
 74 //==============================/* 写指令代码子程序(左)*/=====================
 75 void wrctrl0(unsigned char com)
 76     {
 77       unsigned char cradd1;
 78       CD_1;
 79       CE_0;
 80       do
 81         {
 82           P4DIR=0xff;           //P4口设置为输出
 83           P4OUT=0xff;
 84           RD1_0;
 85           P4DIR=0x00;           //P4口设置为输入
 86           cradd1=P4IN;
 87           RD1_1;
 88         }
 89       while((cradd1&0x03)==0);
 90       P4DIR=0xff;               //P4口设置为输出
 91       P4OUT=0xff;
 92       CD_1;
 93       P4OUT=com;
 94       WR1_0;
 95       WR1_1;
 96     }
 97 void wrctrl(unsigned char dat1,unsigned char dat2,unsigned char ctrlcode)
 98      {
 99        wrdata(dat1);
100        _NOP();
101        _NOP();
102        _NOP();
103        wrdata(dat2);
104        _NOP();
105        _NOP();
106        _NOP();
107        wrctrl0(ctrlcode);
108       }
109 //==============================清屏============================================
110 void clrc(void)
111      { unsigned char i,j;
112            wrctrl(0x00,0x00,0x24);
113            wrctrl0(0xb0);
114            for(i=0;i<64;i++)
115               {
116            for(j=0;j<30;j++)
117              {
118                wrdata(0x10);
119              }
120           }
121       }
122 //==============================清寄存器========================================
123 void clrg(void)
124      { unsigned char i,j;
125           wrctrl(0x00,0x08,0x42);
126           wrctrl(0x1e,0x00,0x43);
127           wrctrl(0x00,0x08,0x24);
128           wrctrl0(0xb0);
129            for(i=0;i<128;i++)
130               {
131            for(j=0;j<30;j++)
132              {
133                wrdata(0x00);
134              }
135           }
136            wrctrl0(0xb2);
137       }
138 //==============================================================================
139 void allon(void)
140         { unsigned char i,j;
141           wrctrl(0x00,0x08,0x42);
142           wrctrl(0x1e,0x00,0x43);
143           wrctrl(0x00,0x08,0x24);
144           wrctrl0(0xb0);
145            for(i=0;i<64;i++)
146               {
147            for(j=0;j<30;j++)
148              {
149                wrdata(0xff);
150              }
151           }
152            wrctrl0(0xb2);
153       }
154 //==============================================================================
155 void stripe(void)
156        { unsigned char i,j;
157           wrctrl(0x00,0x08,0x42);
158           wrctrl(0x1e,0x00,0x43);
159           wrctrl(0x00,0x08,0x24);
160           wrctrl0(0xb0);
161            for(i=0;i<64;i++)
162               {
163            for(j=0;j<30;j++)
164              {
165                wrdata(0xaa);
166              }
167           }
168            wrctrl0(0xb2);
169       }
170 //==============================================================================
171 void stripe1(void)
172      { unsigned char i,j;
173           wrctrl(0x00,0x08,0x42);
174           wrctrl(0x1e,0x00,0x43);
175           wrctrl(0x00,0x08,0x24);
176           wrctrl0(0xb0);
177            for(i=0;i<64;i++)
178            {
179            for(j=0;j<30;j++)
180              {
181                wrdata(0x55);
182              }
183            }
184             wrctrl0(0xb2);
185       }
186 //==============================/* 设置当前地址*/===============================
187 void fnSetPos(unsigned char urow, unsigned char ucol)
188 {
189         unsigned int  iPos;
190         iPos = urow * 30 + ucol;
191         wrctrl(iPos & 0xFF,iPos / 256+0x08,0x24);
192 }
193 //==============================/*写汉字子程序*/================================
194 void wrhz_lcd(unsigned char h,unsigned char urow,unsigned char ucol)
195      { unsigned char dat10;
196        unsigned int i,j,k;
197        wrctrl(0x00,0x08,0x42);
198        wrctrl(0x1e,0x00,0x43);
199        wrctrl(0x00,0x08,0x24);
200        fnSetPos(urow, ucol);
201        k=0;
202        for(i=0;i<16;i++)
203           { wrctrl0(0xb0);
204         for(j=0;j<2;j++)
205             {
206             dat10= hztab_bzj[h][k];
207             wrdata(dat10);
208              k++;
209              }
210            wrctrl0(0xb2);
211            fnSetPos(urow+(i+1), ucol);
212           }
213       }
214 //2009.07.06 evening
215 //==============================================================================
216 //==============================读液晶状态字到STA===============================1
217 //功能:用于往液晶写数据或命令之前判断忙闲
218 void read_sta(void)
219 {
220   P4DIR=0x00; //P4数据输入,由液晶到430,不需要电平的转换,因为是3.3V的液晶模块
221   CD_1;       //命令方式
222   RD1_0;       //read
223   STA=P4IN;   //读回状态
224   RD1_1;       //cancel read
225   P4DIR=0xff; //P4口设置为数据输出模式,由430到液晶
226 }
227 //==============================判断位S1,S0函数(读写指令和读写数据状态)=======2
228 void ST1(void)
229 {
230   do
231   {
232     read_sta();
233   }
234   while((STA&0x03)!=0x03); //0000 0011---忙:1  闲:0
235 }
236 //==============================判断位S2函数(数据自动读状态)==================3
237 void ST2(void)
238 {
239   do
240   {
241     read_sta();
242   }
243   while((STA&0x04)!=0x04);  //0000 0100---忙:1  闲:0
244 }
245 //==============================判断位S3函数(数据自动写状态)==================4
246 void ST3(void)
247 {
248   do
249   {
250     read_sta();
251   }
252   while((STA&0x08)!=0x08);   //0000 1000---忙:1  闲:0
253 }
254 //==============================/*写入数据字节 */ ==============================5
255 //one byte
256 void write_data(unsigned char Byte )
257 {
258          ST1(); //读完状态后,设置为输出模式---这里是正确的
259          P4OUT = Byte;
260          CD_0;        //数据方式
261          WR1_0;       // write
262          WR1_1;
263 }
264 //==============================/*自动写入数据字节 */ ==========================6
265 //不用判断状态标志位
266 void autowrite_data(unsigned char Byte )
267 {
268          P4OUT = Byte;
269          CD_0;         //数据方式
270          WR1_0;        // write
271          WR1_1;
272 }
273 //==============================/*写入命令字 */ ================================7
274 void write_cmd(unsigned char cmd )
275 {
276          ST1();
277          P4OUT = cmd ;
278          CD_1;       //命令方式
279          WR1_0;      // write
280          WR1_1;
281 }
282 //==============================/*写只有一个参数的命令  */ =====================8
283 void write_onepara(unsigned char dat1,unsigned char command )
284 {
285   write_data(dat1);
286   write_cmd(command);
287 }
288 //==============================/*写含有二个参数的命令  */ =====================9
289 void write_doublepara(unsigned char dat1,unsigned char dat2,unsigned char command )
290 {
291   write_data(dat1);
292   write_data(dat2);
293   write_cmd(command);
294 }
295 //==============================/*清显示缓冲的函数   */ ========================10
296 void CLEAR_RAM( void )
297      {
298      int i;
299      write_doublepara(0x00,0x00,0x24);          /* 设置显示RAM 首地址 */
300      //24H Address Pointer Set D1:Low ADRS  D2:High ADRS
301      //the address pointer se command is used to indicate the start address for writing(or reading) to external RAM.
302      write_cmd(0xb0);                           /* 设置自动写方式 */
303      //b0H Data auto write set
304      //Note:Status check for auto mode(STA2,STA3)should be checked between each data.
305      for(i=0;i<8192;i++)                        /* 清8K=8192存储器 */
306         {
307           ST3();                                /* 判状态位S3 */
308           write_data(0x00);                     /* 写入数据 */
309          }
310       write_cmd(0xb2);                          /* 设置自动写结束指令 */
311      //b2H Auto reset
312      //     Auto reset should be peRFormed after checking STA3=1(STA2=1).
313      }
314 //==============================/*对液晶屏的一些初始设置函数   */ ==============11
315 void LcdIni( void )
316      {
317         write_doublepara(0x00,0x00,0x40);        /*设文本显示区域首地址*/
318         //40H Text home address set   D1:Low address  D2:High address
319         //The starting address of external display RAM for Text display is defined by this command.
320         //The text home address shows the left end and most upper position.
321         write_doublepara(0x20,0x00,0x41);        /*设文本显示区域宽度*/
322         //显示区域宽度为32.。需要说明的是为了计算地址的方便,设置显示区域的宽度为20H
323         //41H Text area set   D1:Columns(列)  D2:00H
324         //---------------------------宽度根据实际情况来改变吧!!!2009.07.06
325         /*
326         ------------------------------------------------------------------------
327         TH          |                     | TH+CL
328         ------------------------------------------------------------------------
329         TH+TA       |                     | TH+TA+CL
330         ------------------------------------------------------------------------
331         (TH+TA)+TA  |                     | TH+2TA+CL
332         ------------------------------------------------------------------------
333         TH:Text home address
334         TA:Text area number(columns)
335         CL:Columns are fixed by hardware.(pin-programmable)
336         */
337         //write_doublepara(0x03,0x00,0x22);        /* 设置CGRAM偏置地址 */
338         //22H Function:Offset Register Set  D1:Data   D2:00H
339         //The offset register is used to determine external character generator RAM area.
340         //The upper 5bit(ad15-ad11)are determined by offset register.
341         write_doublepara(0x00,0x08,0x42);        /*设图形显示区域首地址*/
342         //42H Graphic home address set D1:Low address  D2:High address
343         write_doublepara(0x20,0x00,0x43);        /*设图形显示区域宽度*/
344         //0x1e-ox20
345         //43H Graphic area set  D1:Columns  D2:00H
346                 /*
347         ------------------------------------------------------------------------
348         GH          |                     | GH+CL
349         ------------------------------------------------------------------------
350         GH+GA       |                     | GH+GA+CL
351         ------------------------------------------------------------------------
352         (GH+GA)+GA  |                     | GH+2GA+CL
353         ------------------------------------------------------------------------
354         GH:Graphic home address
355         GA:Graphic area number(columns)
356         CL:Columns are fixed by hardware.(pin-programmable)
357         */
358         write_cmd(0xa0);                         /*光标形状设置*/
359         write_doublepara(0x00,0x00,0x21);        /* 设置光标位置*/
360         /*
361         1010 0000           |  1 line  cursor
362         1010 0001           |  2 line  cursor
363         ……                |  ……
364         10100111            |  8 lines cursor,选择为最大的光标
365         when cursor display is ON,this command selects the cursor pattern form 1
366         line to 8 lines.the cursor address is defined by cursor pointer set command.
367         */
368         //write_doublepara(0x08,0x08,0x21);        /* 设置光标 位置*/
369         //21H Cursor Pointer Set  X ADRS   Y ADRS
370         //X ADRS----=00H~4FH (Lower 7bits are valid)
371         //Y ADRS----=00H~1FH (Lower 5bits are valid)
372         //The cursor position is moved only by this command.
373         write_cmd(0x80);        /*显示方式设置逻辑"或"合成, 内部字符发生器有效*/
374         /* Mode Set
375         ------------------------------------------------------------------------
376         Code              |  Function
377         1000x000          |  "OR" Mode
378         1000x001          |  "EXOR" Mode
379         1000x011          |  "AND" Mode
380         1000x100          |  "TEXT ATTRIBUTE" Mode
381         10000xxx          |  Internal Charater Generator Mode
382         10001xxx          |  External ……
383         ------------------------------------------------------------------------
384             When internal character generator mode is selected,character code 00
385         -7FH are selected from built-in character generator ROM.The character code
386         80H-FFH are automatically selected external character generator RAM.
387         */
388         //write_cmd(0x9c);                  /*显示开关设置---开本和开图形显示*/
389         write_cmd(0x9f);
390         /* Display Set
391         ------------------------------------------------------------------------
392         Code              |  Function
393         10010000          |  Display off
394         1001xx10          |  Cursor on,blink off
395         1001xx11          |  Cursor on,blink on
396         100101xx          |  Text on,graphic off
397         100110xx          |  Text off,graphic on
398         100111xx          |  Text on,graphic on
399         ------------------------------------------------------------------------
400         1 0 0 1 d3 d2 d1 d0
401         |d0:Cursor  blink    on:1,off:0
402         |d1:Cursor  display  on:1,off:0
403         |d2:Text    display  on:1,off:0
404         |d3:Graphic display  on:1,off:0
405         Note:It is necessary to turn on "Text display" and "Graphic display" in
406              following case.
407         1)Combination of text/graphic display;
408         2)Attribute function;
409         */
410         /*初始化完成后,开文本和图形显示。此时调整对比度电压,显示屏上将因显示存
411         储器上电时的随机数据而显示出随机的图形和字符。以此可以验证接口电路和驱动
412           程序的正确性。*/
413         //CLEAR_RAM();
414      }
415 //==============================西文字符写入函数================================
416 //x_asx:0~29; y_asc:0~15
417 void write_asc(unsigned char x_asc,unsigned char y_asc,unsigned char code_asc)
418 {
419   unsigned int address;
420   address=y_asc*32+x_asc;
421   write_doublepara((unsigned char)(address),(unsigned char)(address>>8),0x24);
422   //设置显示存储器地址
423   write_onepara(code_asc,0xc4);
424   //装入字符代码,写入数据,地址不变
425 }
426 //==============================汉字写入函数(正显)============================
427 //x_hz:0-29; y_hz:0-127
428 void write_hz1(unsigned char x_hz,unsigned char y_hz,unsigned char code_hz)
429 {
430   unsigned char i_hz;
431   unsigned int address,addr_hz;
432   address=y_hz*32+x_hz+0x0800;      //计算显示存储器的地址
433   //addr_hz=code_hz*32;             //计算汉字字模地址(cctab的下标)由32改为16
434   addr_hz=0;
435   for(i_hz=0;i_hz<16;i_hz++)        //计数值16
436   {
437       write_doublepara((unsigned char)(address),(unsigned char)(address>>8),0x24);
438                                    //设置显示存储器地址
439       write_onepara(hztab_bzj[code_hz][addr_hz],0xc0);     //写入汉字字模左部
440       write_onepara(hztab_bzj[code_hz][16+addr_hz++],0xc0);//写入汉字字模右部
441       address+=32;//修改显示存储器地址,显示下一列(共16列)
442   }
443 }
444 //==============================汉字写入函数(反显)============================
445 void write_hz2(unsigned char x_hz,unsigned char y_hz,unsigned char code_hz)
446 {
447   unsigned char i_hz;
448   unsigned int address,addr_hz;
449   address=y_hz*32+x_hz+0x0800;   //计算显示存储器的地址
450   //addr_hz=code_hz*32;             //计算汉字字模地址(cctab的下标)由32改为16
451   addr_hz=0;
452   for(i_hz=0;i_hz<16;i_hz++)    //计数值16
453   {
454       write_doublepara((unsigned char)(address),(unsigned char)(address>>8),0x24);
455   //设置显示存储器地址
456         write_onepara((255-hztab_bzj[code_hz][addr_hz]),0xc0);//写入汉字字模左部
457           write_onepara((255-hztab_bzj[code_hz][16+addr_hz++]),0xc0);//写入汉字字模右部
458           address+=32;//修改显示存储器地址,显示下一列(共16列)
459   }
460 }
461 //================================显示一个点函数================================
462 //x:0-239;   y:0-127(消除点) 128-255(显示点)
463 void write_point(unsigned char x,unsigned char y)
464 {
465   unsigned char x_pt,y_pt;
466   unsigned int address;
467   x_pt=x;
468   y_pt=y;
469   address=(y_pt&0x7f)*32+x_pt/8+0x0800;//计算显示存储器地址
470    write_doublepara((unsigned char)(address),(unsigned char)(address>>8),0x24);
471   //设置显示存储器地址
472    x_pt=(~(x_pt%8))&0x07;
473    y_pt=((y_pt&0x80)>>4)|0xf0;
474    write_cmd(x_pt|y_pt);//写入数据
475 }
476 //===================================显示矩形框=================================
477 //x:0-239,y:0-127
478 void rectangle(unsigned char xstar,unsigned char xend,unsigned char ystar,unsigned char yend)
479 {
480   unsigned char i;
481   ystar+=128;
482   yend+=128;                   //显示点
483   for(i=xstar;i<=xend;i++)
484   {
485     write_point(i,ystar);
486     write_point(i,yend);
487   }
488     for(i=ystar;i<=yend;i++)
489   {
490     write_point(xstar,i);
491     write_point(xend,i);
492   }
493 }
494 //========================================擦除矩形框============================
495 void clr_rectangle(unsigned char xstar,unsigned char xend,unsigned char ystar,unsigned char yend)
496 {
497   unsigned char i;
498   for(i=xstar;i<=xend;i++)
499   {
500     write_point(i,ystar);
501     write_point(i,yend);
502   }
503     for(i=ystar;i<=yend;i++)
504   {
505     write_point(xstar,i);
506     write_point(xend,i);
507   }
508 }
509 //==============================================================================1400
原文地址:https://www.cnblogs.com/guochaoxxl/p/14162743.html