找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 11130|回复: 1
收起左侧

基于单片机MSP430G2553的LCD12864的显示课程设计报告

[复制链接]
ID:267370 发表于 2017-12-26 21:13 | 显示全部楼层 |阅读模式
这是我最近在做MSP430开发时整理出的一些关于12864的资料,供大家参考。
单片机课程设计报告
基于单片机MSP430G2553的LCD 12864的显示
专业班级:
学生姓名:
学  号:
指导教师:
设计时间:

一、设计任务与要求

1、在LCD上显示文字,字符

2、用C语言写关于MSP430G2553相关的代码

3、掌握LCD12864的运用方法

二、硬件模块介绍

1、MSP430芯片

MSP430 是美国Texas Instruments(TI)公司于1996年开始推向市场的超低功耗微处理器。除了超低功耗这一特点外,在MSP430 系列产品中还集成了很多功能模块,可以应用于各个方面,使得用一片MSP430 芯片就能完成以前要用多片芯片组合才能完成的功能,大大地缩小了产品的体积,并且降低了成本。因此,MSP430 系列一经推出,就受到了业内人士的欢迎。迄今为止,MSP430 已经广泛应用于各个领域,尤其是便携式仪器仪表、监测、医疗器械以及汽车电子等领域。

2、LCD12864

(1)概述

带中文字库的128×64是一种具有4位/8位并行、2线或3线串行多种接口方式,内部含有国标一级、二级简体中文字库的点阵图形液晶显示模块;其显示分辨率为128×64, 内置8192个16×16点汉字,和128个16×8点ASCII字符集.利用该模块灵活的接口方式和简单、方便的操作指令,可构成全中文人机交互图形界面。可以显示8×4行16×16点阵的汉字. 也可完成图形显示.低电压低功耗是其又一显著特点。由该模块构成的液晶显示方案与同类型的图形点阵液晶显示模块相比,不论硬件电路结构或显示程序都要简洁得多,且该模块的价格也略低于相同点阵的图形液晶模块。

(2)基本特性

  • 低电源电压(VDD:+3.0--+5.5V
  • 显示分辨率:128×64
  • 内置汉字字库,提供819216×16点阵汉字(简繁体可选)
  • 内置 12816×8点阵字符
  • 2MHZ时钟频率
  • 显示方式:STN、半透、正显
  • 驱动方式:1/32DUTY1/5BIAS
  • 视角方向:6
  • 背光方式:侧部高亮白色LED,功耗仅为普通LED1/5—1/10
  • 通讯方式:串行、并口可选
  • 内置DC-DC转换电路,无需外加负压
  • 无需片选信号,简化软件设计
  • 工作温度: 0 - +55 ,存储温度: -20 - +60

(3)模块接口说明如表3-5所示:

3-5 LCD12864接口说明

管脚号
管脚名称
电平
管脚功能描述
1
VSS
0V
电源地
2
VCC
3.0+5V
电源正
3
V0
-
对比度(亮度)调整
4
RS(CS)
H/L
RS=“H”,表示DB7——DB0为显示数据
RS=“L”,表示DB7——DB0为显示指令数据
5
R/W(SID)
H/L
R/W=“H”,E=“H”,数据被DB7——DB0
R/W=“L”,E=“H→L”, DB7——DB0的数据被写到IR或DR
6
E(SCLK)
H/L
使能信号
7
DB0
H/L
三态数据线
8
DB1
H/L
三态数据线
9
DB2
H/L
三态数据线
10
DB3
H/L
三态数据线
11
DB4
H/L
三态数据线
12
DB5
H/L
三态数据线
13
DB6
H/L
三态数据线
14
DB7
H/L
三态数据线
15
PSB
H/L
H:8位或4位并口方式,L:串口方式(见注释1)
16
NC
-
空脚
17
/RESET
H/L
复位端,低电平有效(见注释2)
18
VOUT
-
LCD驱动电压输出端
19
A
VDD
背光源正端(+5V)(见注释3)
20
K
VSS
背光源负端(见注释3)

*注释1:如在实际应用中仅使用串口通讯模式,可将PSB接固定低电平,也可以将模块上的J8和“GND”用焊锡短接。

*注释2:模块内部接有上电复位电路,因此在不需要经常复位的场合可将该端悬空。

*注释3:如背光和模块共用一个电源,可以将模块上的JA、JK用焊锡短接。

三、方案设计与论证

12864有两种工作模式

1、方案一

LCD12864的并行模式:

并行模式就是常用的8位数据线,4为控制线。这种方式虽然占用的IO口较多,但是向液晶收发数据较容易实现,数据传输速度较快。所以在一些连续显示多幅图画,演示动画或对显示的实时性要求较高的场合应该考虑这种方式。其中在并行模式中,在向液晶写数据或命令前,要进行液晶忙标志判断 BF,要确定液晶显示不忙了,才能进行操作。接线方式如图:

2、方案二

LCD12864的串行模式:

串行模式只用到了两根线WR,EN于单片机进行通信。这种方式可以大大减少单片机IO口的开销,适用于IO口资源有限的单片机(如msp430g2553)。但是这种方式实现起来较麻烦,数据的传输效率不高。对于一般的文字,简单图形的显示还是可以的。

SCLK:串行同步时钟线,每操作一位数据都要有一个SCLK跳变沿,而且在这里是上升沿有效。也即是说,每次SCLK由低电平变为高电平的瞬间,液晶控制器将SID上的数据读入或输出。

SID:串行数据,每一次操作都由三个字节数据组成,第一个字节向控制器发送命令控制字,告诉控制器接下来是什么操作,若为写指令则发送11111000

(0xf8),若为若为写数据则发送11111010(0xfa),若为读状态则发送11111100(0xfc),若为读数据则发送11111110(0xfe)。

第二个字节的高4位为发送指令或数据的高4位,第二个字节的低4位补0.

第三个字节的高4位为发送指令或数据的低4位,第三个字节的低4位补0

接线方式如图:

综上,由于MSP430G2553的IO口比较少,所以我选方案二

四、硬件设计

虽然开发板上的电压有3.8V,但是由于LCD的最佳工作电压是5V,所以在3.8V工作下的LCD12864并不能正常工作,所以我采用的是外接5V电压,将IO口输出的3.8V电压用74HC04芯片做成的缓冲器转换成5V,总体设计如下图:

五、软件设计

1、main.c程序

  1. #include  "msp430g2553.h"
  2. #include  "lcd.h"
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. void InitSys();
  6. void main(void)
  7. {
  8.        WDTCTL = WDTPW + WDTHOLD;                 // 关闭看门狗
  9.        InitSys();
  10.       Lcd_Init();
  11.        write_com(0x01);
  12.        W_str(1,1,"床前明月光,");
  13.        W_str(1,2,"疑是地上霜。");
  14.        W_str(1,3,"举头望明月,");
  15.        W_str(1,4,"低头思故乡。");           
  16. }
  17. void InitSys()
  18. {
  19.   if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)//判断系统的宏是否被删除                                    
  20.   {
  21.     while(1);//如果删除程序就停在这里                              
  22.   }
  23.   BCSCTL1 = CALBC1_8MHZ;                  
  24.   DCOCTL = CALDCO_8MHZ;  //设置系统时钟为8MHZ                 
  25. }
复制代码

2、lcd.c程序

  1. #include <msp430g2553.h>
  2. #include "lcd.h"
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. /*=============================
  6. #define SID P2.1;
  7. #define CLCLK P2.0;
  8. 接线:LCD12864的5脚接P2.1
  9.       LCD12864的6脚接P2.0
  10.       LCD12864的4引脚直接接VCC

  11. ==============================*/

  12. #define SID_1 P2OUT|=0x02;
  13. #define SID_0 P2OUT&=~0x02;
  14. #define CLK_1 P2OUT|=0x01;
  15. #define CLK_0 P2OUT&=~0x01;
  16. #define CPU_F ((double)8000000)
  17. #define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
  18. #define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))

  19. void W_str(uchar x,uchar y,uchar *s);
  20. void write_com(uchar x);
  21. void write_data(uchar x);
  22. void delay(uint z);
  23. void W_8bits(uchar W_bits);
  24. void W_byte(uchar rw,uchar rs,uchar W_data);
  25. void Lcd_Init(void);
  26. void delay(uint z)
  27. {
  28. uint x,y;
  29. for(x=z;x>0;x--)
  30. for(y=240;y>0;y--);
  31. }

  32. void W_8bits(uchar W_bits)
  33. {
  34. uchar i,temp;
  35. for(i=0;i<8;i++)
  36. {
  37. temp=W_bits;
  38. temp<<=i;//将数据每一位依次移到最高位
  39. if((temp&0x80)==0)//判断每位是否为0,如果是,则SID为0,即写入数据0
  40. {
  41. SID_0;
  42. delay_us(20);
  43. CLK_1;
  44. delay_us(40);
  45. CLK_0;
  46. delay_us(20);
  47. SID_0;
  48. }
  49. else
  50. {
  51. SID_1;
  52. delay_us(20);

  53. CLK_1;
  54. delay_us(40);

  55. CLK_0;

  56. delay_us(20);

  57. SID_0;
  58. }
  59. }
  60. }
  61. /*
  62. rw=1 则表示读出
  63. rw=0 则表示输入
  64. rs=1 则表示写数据
  65. rs=0 则表示写命令
  66. W_byte(0,0,x)写命令x;
  67. W_byte(0,1,y)写数据y;
  68. */
  69. void W_byte(uchar rw,uchar rs,uchar W_data)
  70. {
  71. uchar H_data,L_data,s_id=0xf8;
  72. if(rw==0)
  73. {
  74. s_id&=~0x04;//第一个字节s_id为oxf8,写命令
  75. }
  76. else
  77. {
  78. s_id|=0x04;//第一个字节s_id为0xfa,写数据
  79. }
  80. if(rs==0)
  81. {
  82. s_id&=~0x02;
  83. }
  84. else
  85. {
  86. s_id|=0x02;
  87. }
  88. H_data=W_data;
  89. H_data&=0xf0;//取出高四位
  90. L_data=W_data;
  91. L_data&=0x0f;//取出第四位
  92. L_data<<=4;
  93. /*串口数据一次输入为三个字节,第一个为控制字,第二个为数据或命令的高四位,第三个为数据或命令的第四位*/
  94. W_8bits(s_id);//写入控制字
  95. W_8bits(H_data);//写入数据或命令的高四位
  96. W_8bits(L_data);//写入数据或命令的第四位

  97. }
  98. void Lcd_Init()
  99. {
  100. P2DIR|=0x03;//P2的低两位为输出
  101. CLK_0;
  102. SID_0;

  103. delay_us(5);
  104. W_byte(0,0,0x38);//设置16X2显示,显示5X7点阵,8位数据接口
  105. delay_us(5);
  106. W_byte(0,0,0x38);
  107. delay_us(5);
  108. W_byte(0,0,0x0c);//整体显示开,游标关,反白关
  109. delay_us(5);
  110. W_byte(0,0,0x01);//写入空格清屏
  111. delay_us(5);
  112. W_byte(0,0,0x02);//清DDRAM
  113. delay_us(5);
  114. W_byte(0,0,0x80);//设定首次显示位置
  115. delay_us(5);
  116. }

  117. // x代表偏移量
  118. //y代表第几行
  119. //*S是字符串的指针
  120. void W_str(uchar x,uchar y,uchar *s)
  121. {
  122. switch(y)
  123. {
  124. case 1:W_byte(0,0,0x80+x);break;//0x80是第一行起始位置
  125. case 2:W_byte(0,0,0x90+x);break;//0x90是第二行起始位置
  126. case 3:W_byte(0,0,0x88+x);break;//0x88是第三行起始位置
  127. case 4:W_byte(0,0,0x98+x);break;//0x98是第四行起始位置
  128. default:W_byte(0,0,0x80+x);//否则都当成第一行处理
  129. }
  130. while(*s)
  131. {
  132. W_byte(0,1,*s);
  133. s++;
  134. }
  135. }
  136. void write_com(uchar x)
  137. {
  138. W_byte(0,0,x);
  139. }
  140. void write_data(uchar x)
  141. {
  142. W_byte(0,1,x);
  143. }

复制代码

3、lcd.h程序
#define uchar unsigned char
#define uint unsigned int
void W_str(uchar x,uchar y,uchar *s);
void write_com(uchar x);
void write_data(uchar x);
void delay(uint z);
void W_8bits(uchar W_bits);
void W_byte(uchar rw,uchar rs,uchar W_data);
void Lcd_Init(void);

六、系统的调试

              刚开始的时候以为3.8V的电压可以使LCD12864正常工作,结果怎么修改程序都不显示文字,以为是程序中的时序写错了,但是改了还是没用,又以为是电路接线出错了,重新接

线后还是没用,后来才想到可能是电压不够,结果外接电源真的有用了。

七、总结

              通过这次设计,我学会了LCD12864的基本工作原理和运用,掌握了一些MSP430单片机的基本运用和编程方法,最重要的是在调试过程中让我懂得了最什么是都要考虑周全,遇到什么事都不能慌,问题要一个一个解决,不能急,也不能轻易放弃。

八、参考文献

    [1] 苏小红等编著.C语言大学实用教程(第三版).北京:电子工业出版社,2012

    [2] 张晞,王德银,张晨编著.MSP430 系列单片机实用C 语言程序设计.北京:人民邮电出版社,2005


完整的Word格式文档51黑下载地址,还附带了430驱动12864的其他相关资料:
http://www.51hei.com/bbs/dpj-103116-1.html




评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:30541 发表于 2019-1-2 13:56 | 显示全部楼层
谢谢楼主分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表