admin 管理员组

文章数量: 1086019


2024年3月6日发(作者:removechild 卡)

> > LCD_DRIVER.c, change:2008-08-18,size:9411b

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

12.

13.

14.

15.

16.

17.

18.

19.

20.

21.

22.

23.

24.

25.

26.

27.

28.

29.

30.

31.

32.

33.

34.

35.

36.

Search codes

//===================================================

//= LCD控制驱动程序 =

//===================================================

//= 本程序可对于YLF12864J 128*64 20针液晶屏进行控制=

//=输出输入。 =

//= =

//= 北京信息科技大学电子电工实习中心=

//= 易恺迪 =

//= 2008.8.17 =

//= =

//= =

//===================================================

/*基本操作时序

1,读状态:输入:D/I=L,CS1或CS2=H,R/W=H,E=H 输出:D0-D7=状态字

2,写指令:输入:D/I=L,CS1或CS2=H,R/W=L,E=高脉冲 D0-D7=指令码 输出:无

3,读数据:输入:D/I=H,CS1或CS2=H,R/W=H,E=H 输出:D0-D7=数据

4,写数据:输入:D/I=H,CS1或CS2=H,R/W=L,E=高脉冲 D0-D7=数据 输出:无

状态字说明:D0-D7中D5为液晶显示状态:1为关闭,0为显示。D7为读写操作使能:1为禁止,0为允许。其他D0-D4,D6未使用

指令说明

1,初始化设置

1.1显示开/关设置

指令码 功能

3EH 关显示

3FH 开显示

1.2显示初始设定

指令码 功能

0C0H 设置显示初始行

2,数据控制

控制器内部设有一个数据地址页指针和一个数据地址列指针,用户可通过它们来访问内部的全部512字节RAM

数据指针设置

37.

38.

39.

40.

41.

42.

43.

44.

45.

46.

47.

48.

49.

50.

51.

52.

53.

54.

55.

56.

57.

58.

59.

60.

61.

62.

63.

64.

65.

66.

67.

68.

69.

70.

71.

72.

73.

74.

75.

76.

77.

78.

79.

80.

指令码 功能

0B8H+页码(0-7) 设置数据地址页指针

40H+列码(0-63) 设置数据地址列指针

3,初始化过程

写指令0C0H:设置显示初始行

写指令3FH: 开显示

*/

#include

#include

#include"config.c"//引入管脚配置文件

#define LCD_CMD_COL 0x40//定义128X64液晶屏幕每个分控制器列基地址

#define LCD_CMD_PAGE 0XB8//定义128X64液晶屏幕每个分控制器页基地址

#define LCD_CMD_ON 0x3F//初始化开指令

#define LCD_CMD_OFF 0x3E//初始化关指令

#define LCD_CMD_STARTLINE 0xC0//初始化显示初始行

#define LCD_LEFT 0x00//LCD左上角坐标X定义

#define LCD_TOP 0x00//LCD左上角坐标Y定义

#define LCD_RIGHT 0x7F//LCD右下角坐标Y定义

#define LCD_BOTTOM 0x3F//LCD右下角坐标X定义

#define LCD_DS CON_DS//配置D0-D7数据管脚

#define LCD_ACT_CS1 0x01//控制器1活动标志

#define LCD_ACT_CS2 0x02//控制器2活动标志

//这里为了使用方便把需要更改的管脚定义放到CONFIG.C文件中,用户可以到CONFIG.C中更改自己的管脚连接配置关系

//sbit LCDRS;//数据/命令选择管脚定义

//sbit LCDWR;//读写控制管脚定义

//sbit LCDEN;//使能管脚定义

//sbit LCDCS1;//片选CS1管脚定义

//sbit LCDCS2;//片选CS2管脚定义

//sbit LCDRST;//重起管脚定义

unsigned char LCD_CurrentX,LCD_CurrentY;//定义当前操作LCD位置指针

void Delay(unsigned int uiTime);//延时

void CheckBusy(unsigned char ucACT);//忙检测,参数传递片选端

void SendCMD(unsigned char ucACT,unsigned char ucCMD);//向控制器传输命令,参数1为片选,2为命令

void SendData(unsigned char ucACT,unsigned char ucData);//写数据,参数1为片选,2为数据

void LCDWriteCMD(unsigned char ucCMD);//向LCD写入命令,此函数根据当前液晶屏操作位置自动片选,参数为命令

void LCDWriteData(unsigned char ucData);//向LCD写入数据,此函数根据当前液晶屏操作位置自动片选,参数为数据

void SwitchPos();//坐标转换函数,将可视坐标转换成存储器物理地址坐标

void LCDMoveNextPos();// 将可视坐标移动到下一个位置

81.

82.

83.

84.

85.

86.

87.

88.

89.

90.

91.

92.

93.

94.

95.

96.

97.

98.

99.

100.

101.

102.

103.

104.

105.

106.

107.

108.

109.

110.

111.

112.

113.

114.

115.

116.

117.

118.

119.

120.

121.

122.

123.

124.

void DisplayByte(unsigned char ucData);//向LCD写一个字节显示到液晶屏上

void LCDFill(unsigned char FillData);//整屏填充数据

void LocatePos(unsigned char XPos,unsigned char YPos);//定位液晶屏可视坐标,范围:X:0-127,y:0-63(每次按8递增)

void LCDInit();//初始化

unsigned char RDState(unsigned char ucACT);//读取控制器状态,返回一个字节信息

unsigned char RDData(unsigned char ucACT);//读数据,参数为片选

unsigned char LCDReadData();//从LCD读取数据,此函数自动根据液晶屏当前操作位置进行片选

/////////////////////////////////////////////////////////////////////////////////////////////

void LocatePos(unsigned char XPos,unsigned char YPos)

{

if (0x00

{

LCD_CurrentX=XPos;

}

if ((0x00

{

LCD_CurrentY=YPos;

}

}

//////////////////////////////////////////////////////////////////////////////////////////////

void LCDInit()//初始化

{

SendCMD(LCD_ACT_CS1,LCD_CMD_ON);//开启左边的第一个LCD控制器

SendCMD(LCD_ACT_CS2,LCD_CMD_ON);//开启右边的第二个LCD控制器

SendCMD(LCD_ACT_CS1,LCD_CMD_STARTLINE);//设置第一个LCD控制器显示初始行

SendCMD(LCD_ACT_CS2,LCD_CMD_STARTLINE);//设置第二个LCD控制器显示初始行

}

//////////////////////////////////////////////////////////////////////////////////////////////

void LCDFill(unsigned char FillData)//填充液晶屏屏幕,一般用于清空数据或者测试液晶屏

{

for(LCD_CurrentX=LCD_LEFT,LCD_CurrentY=LCD_TOP;1;)

{

DisplayByte(FillData);//显示数据

if ((LCD_CurrentX==LCD_LEFT)&&(LCD_CurrentY==LCD_TOP))//当达到右下角坐标清0,退出填充显示

{

break;

}

}

}

//////////////////////////////////////////////////////////////////////////////////////////////

void DisplayByte(unsigned char ucData)//在液晶屏显示一个字节的数据

{

125.

126.

127.

128.

129.

130.

131.

132.

133.

134.

135.

136.

137.

138.

139.

140.

141.

142.

143.

144.

145.

146.

SwitchPos();//坐标转换,将可视坐标转换为物理存储器地址

LCDWriteData(ucData);//传输显示数据

LCDMoveNextPos();//坐标向后移动一个

}

//////////////////////////////////////////////////////////////////////////////////////////////

void LCDMoveNextPos()//后移一个坐标

{

LCD_CurrentX++;//向后移动一列,一共0-63列

if (LCD_CurrentX>LCD_RIGHT)//当达到最后一列时,初始到最左边一列,并且下移一行

{

LCD_CurrentX=LCD_LEFT;

LCD_CurrentY+=8;

if (LCD_CurrentY>LCD_BOTTOM)//移到最后一行时,初始到第一行

{

LCD_CurrentY=LCD_TOP;

}

}

}

//////////////////////////////////////////////////////////////////////////////////////////////

void SwitchPos()

{

LCDWriteCMD(LCD_CMD_COL|(LCD_CurrentX&0x3f));//列转换,范围0-127,当0-63时默认值,当超过63,转换为第二片控制器的0-63

147.

148.

149.

150.

151.

152.

153.

154.

155.

156.

157.

158.

159.

160.

161.

162.

163.

164.

165.

166.

167.

168.

LCDWriteCMD(LCD_CMD_PAGE|((LCD_CurrentY/8)&0x07));//页转换,范围0-63,以8递增,将液晶屏分为8页

}

//////////////////////////////////////////////////////////////////////////////////////////////

void LCDWriteData(unsigned char ucData)//向LCD写数据,此函数自动判断写哪一块控制器

{

if (LCD_CurrentX<0x40)//当大于63列,就写到第二片控制器上,否则第一片

{

SendData(LCD_ACT_CS1,ucData);

}

else

{

SendData(LCD_ACT_CS2,ucData);

}

}

//////////////////////////////////////////////////////////////////////////////////////////////

unsigned char LCDReadData()//从LCD读取数据,根据当前可视坐标选择控制器

{

unsigned char ucData;

if(LCD_CurrentX<0x40)

{

ucData=RDData(LCD_ACT_CS1);//从一控制器读取2遍

ucData=RDData(LCD_ACT_CS1);

169.

170.

171.

172.

173.

174.

175.

176.

177.

178.

179.

180.

181.

182.

183.

184.

185.

186.

187.

188.

189.

190.

191.

192.

193.

194.

195.

196.

197.

198.

199.

200.

201.

202.

203.

204.

205.

206.

207.

208.

209.

210.

211.

212.

213.

}

else

{

ucData=RDData(LCD_ACT_CS2);//从二控制器读取2遍

ucData=RDData(LCD_ACT_CS2);

}

return ucData;

}

//////////////////////////////////////////////////////////////////////////////////////////////

void LCDWriteCMD(unsigned char ucCMD)//向LCD写命令,自动识别控制端

{

if(LCD_CurrentX<0x40)

{

SendCMD(LCD_ACT_CS1,ucCMD);

}

else

{

SendCMD(LCD_ACT_CS2,ucCMD);

}

}

//////////////////////////////////////////////////////////////////////////////////////////////

unsigned char RDData(unsigned char ucACT)//读取数据,每次读取一个字节

{

unsigned char ucData;

LCD_DS=0xFF;

CheckBusy(ucACT);//等待LCD空闲

LCDRS=1;//操作数据

LCDWR=1;//读取命令

if(ucACT==0x01)

{

LCDCS1=1;//片选

LCDEN=1;//开启LCD

_nop_();

ucData=LCD_DS;//读取

LCDEN=0;//关闭LCD

LCDCS1=0;//片选结束

}

else

{

LCDCS2=1;

LCDEN=1;

_nop_();

ucData=LCD_DS;

LCDEN=0;

LCDCS1=0;

214.

215.

216.

217.

218.

219.

220.

221.

222.

223.

224.

225.

226.

227.

228.

229.

230.

231.

232.

233.

234.

235.

236.

237.

238.

239.

240.

241.

242.

243.

244.

245.

246.

247.

248.

249.

250.

251.

252.

253.

254.

255.

256.

257.

258.

}

return ucData;

}

//////////////////////////////////////////////////////////////////////////////////////////////

void SendData(unsigned char ucACT,unsigned char ucData)//向LCD发送数据

{

CheckBusy(ucACT);

LCD_DS=ucData;//D0-D7数据口发送数据

LCDRS=1;//数据操作

LCDWR=0;//写命令

if (ucACT==0x01)

{

LCDCS1=1;

LCDEN=1;

_nop_();

LCDEN=0;

LCDCS1=0;

}

else

{

LCDCS2=1;

LCDEN=1;

_nop_();

LCDEN=0;

LCDCS2=0;

}

}

//////////////////////////////////////////////////////////////////////////////////////////////

void SendCMD(unsigned char ucACT,unsigned char ucCMD)//向LCD下命令

{

CheckBusy(ucACT);

LCD_DS=ucCMD;

LCDRS=0;//指令操作

LCDWR=0;//写操作

if (ucACT==0x01)

{

LCDCS1=1;

LCDEN=1;

_nop_();

LCDEN=0;

LCDCS1=0;

}

else

{

LCDCS2=1;

259.

260.

261.

262.

263.

264.

265.

266.

267.

268.

269.

270.

271.

272.

273.

274.

275.

276.

277.

278.

279.

280.

281.

282.

283.

284.

285.

286.

287.

288.

289.

290.

291.

292.

293.

294.

295.

296.

297.

298.

299.

300.

301.

302.

303.

LCDEN=1;

_nop_();

LCDEN=0;

LCDCS2=0;

}

}

//////////////////////////////////////////////////////////////////////////////////////////////

void Delay(unsigned int uiTime)//延时

{

unsigned int i,j;

for(i=0;i

{

for(j=0;j<10;j++)

{

;

}

}

}

//////////////////////////////////////////////////////////////////////////////////////////////

unsigned char RDState(unsigned char ucACT)//读取LCD状态

{

unsigned char ucData=0xFF;

LCDRS=0;//命令操作

LCDWR=1;//读取状态

if (ucACT==0x01)

{

LCDCS1=1;

LCDEN=1;

_nop_();

ucData=LCD_DS;//读取数据

LCDEN=0;

LCDCS1=0;

}

else

{

LCDCS2=1;

LCDEN=1;

_nop_();

ucData=LCD_DS;

LCDEN=0;

LCDCS2=0;

}

return ucData;

}

//////////////////////////////////////////////////////////////////////////////////////////////

304.

305.

306.

307.

308.

309.

310.

311.

void CheckBusy(unsigned char ucACT)

{

while((RDState(ucACT)&0x80)==0x80);//直到读取的状态数据中D7位为0时退出等待,D7位是忙标志位

}

/////////////////////////////////////////////////////////////////////////////////////////////


本文标签: 数据 坐标 控制器 液晶屏