1 | #include <avr/io.h>
|
2 | #include <stdio.h>
|
3 | #include <stdlib.h>
|
4 | #include <util/delay.h>
|
5 |
|
6 | #include "board.h"
|
7 | #include "t6963c.h"
|
8 |
|
9 |
|
10 | uchar readstate(void)
|
11 | {
|
12 | uchar lcd_state;
|
13 | DDRL=0x00;
|
14 | DDRC|=(1<<3);
|
15 | DDRC|=(1<<1);
|
16 | PORTC|=(1<<3); // C/D=1
|
17 | PORTC&=~(1<<1); // /RD=0
|
18 | lcd_state=PINL&0xff; // 读取引脚A物理电平
|
19 | _delay_ms(5);
|
20 | _delay_ms(5);
|
21 | PORTC|=(1<<1); // /RD=1
|
22 | return lcd_state;
|
23 | }
|
24 |
|
25 | //判断指令(数据)读写状态
|
26 | void st01(void)
|
27 | {
|
28 | while((readstate()&0x03)!=3)
|
29 | ;
|
30 | }
|
31 |
|
32 | //判断数据自动读状态
|
33 | void st2(void)
|
34 | {
|
35 | while((readstate()&0x04)!=4)
|
36 | ;
|
37 | }
|
38 |
|
39 | //判断数据自动写状态
|
40 | void st3(void)
|
41 | {
|
42 | while((readstate()&0x08)!=8)
|
43 | ;
|
44 | }
|
45 |
|
46 | //指令写入函数
|
47 | void writecode(uchar comd0)
|
48 | {
|
49 | st01();
|
50 | DDRL=0xff; //A口方向为输出
|
51 | PORTL=comd0; //送数据到A口寄存器
|
52 | DDRC|=(1<<0);
|
53 | PORTC&=~(1<<0); // /WR=0
|
54 | _delay_ms(5);
|
55 | PORTC|=(1<<0); // /WR=1
|
56 | }
|
57 |
|
58 | //数据写入函数
|
59 | void writedata(uchar onedata)
|
60 | {
|
61 | st01();
|
62 | DDRC|=(1<<3);
|
63 | PORTC&=~(1<<3); // C/D=0,数据通道
|
64 | DDRL=0xff; //A口方向为输出
|
65 | PORTL=onedata; //送数据到A口寄存器
|
66 | DDRC|=(1<<0);
|
67 | PORTC&=~(1<<0); // /WR=0
|
68 | _delay_ms(5);
|
69 | PORTC|=(1<<0); // /WR=1
|
70 | }
|
71 |
|
72 | //数据自动写入函数
|
73 | void writeauto(uchar onedata)
|
74 | {
|
75 | st3();
|
76 | DDRC|=(1<<3);
|
77 | PORTC&=~(1<<3); // C/D=0,数据通道
|
78 | DDRL=0xff; //A口方向为输出
|
79 | PORTL=onedata; //送数据到A口寄存器
|
80 | DDRC|=(1<<0);
|
81 | PORTC&=~(1<<0); // /WR=0
|
82 | PORTC|=(1<<0); // /WR=1
|
83 | _delay_ms(5);
|
84 | PORTC|=(1<<0); // /WR=1
|
85 | }
|
86 |
|
87 | //一字节参数指令写入函数
|
88 | void oneparameter(uchar onep1,uchar comd1)
|
89 | {
|
90 | writedata(onep1);
|
91 | writecode(comd1);
|
92 | }
|
93 |
|
94 | //两字节参数指令写入函数
|
95 | void twoparameter(uchar twop1,uchar twop2,uchar comd2)
|
96 | {
|
97 | writedata(twop1);
|
98 | writedata(twop2);
|
99 | writecode(comd2);
|
100 | }
|
101 |
|
102 | /***********************************************************
|
103 | 液晶初始化,清屏
|
104 | ***********************************************************/
|
105 |
|
106 | //内置T6963C控制器液晶初始化函数
|
107 | void lcd_init(void)
|
108 | {
|
109 | twoparameter(0x00,0x00,0x40); //文本显示区域首地址0x0000
|
110 | twoparameter(0x20,0x00,0x41); //文本显示区域宽度32字节
|
111 | twoparameter(0x00,0x08,0x42); //图形显示区域首地址0x0800
|
112 | twoparameter(0x20,0x00,0x43); //图形显示区域宽度32字节
|
113 | writecode(0xa7); //光标形状
|
114 | writecode(0x80); //显示方式设置(使用内部CGROM,逻辑或合成)
|
115 | writecode(0x9c); //显示开关(开文本和图形显示方式,禁止光标显示和闪烁)
|
116 | }
|
117 |
|
118 | //清除屏幕(清所有8K存储空间)
|
119 | void lcd_clear(void)
|
120 | {
|
121 | uint cl_count;
|
122 | twoparameter(0x00,0x00,0x24); //设置显示存储器首地址
|
123 | writecode(0xb0); //设置自动写状态
|
124 | for(cl_count=8192;cl_count>0;cl_count--)
|
125 | writeauto(0x00);
|
126 | writecode(0xb2); //关闭自动写状态
|
127 | }
|
128 |
|
129 | /********************************************************
|
130 | 西文字符,汉字,点阵显示函数
|
131 | ********************************************************/
|
132 | //西文字符写入函数
|
133 | //x_asc:0~29; y_asc:0~15
|
134 | void writeasc(uchar x_asc,uchar y_asc,uchar code_asc)
|
135 | {
|
136 | uint address;
|
137 | address=y_asc*32+x_asc;
|
138 | twoparameter((uchar)(address),(uchar)(address>>8),0x24); //设置显示存储器地址
|
139 | oneparameter(code_asc,0xc4); //装入字符代码,写入数据,地址不变
|
140 | }
|
141 |
|
142 | //汉字写入函数
|
143 | //x_hz:0~29; y_hz:0~127
|
144 | void writehz(uchar x_hz,uchar y_hz,uchar code_hz)
|
145 | {
|
146 | uchar i_hz;
|
147 | uint address,addr_hz;
|
148 | address=y_hz*32+x_hz+0x0800; //计算显示存储器地址
|
149 | addr_hz=code_hz*32; //计算汉字字模地址(cctab的下标)
|
150 | for(i_hz=0;i_hz<16;i_hz++) //计数值16
|
151 | {
|
152 | twoparameter((uchar)(address),(uchar)(address>>8),0x24); //设置显示存储器地址
|
153 | //oneparameter(cctab[addr_hz],0xc0); //写入汉字字模左部
|
154 | //oneparameter((cctab[16+addr_hz++]),0xc0); //写入汉字字模右部
|
155 | address+=32; //修改显示存储器地址,显示下一列(共16列)
|
156 | }
|
157 | }
|
158 |
|
159 | //显示一个点函数
|
160 | //x:0~239; y:0~127(消除点)128~255(显示点)
|
161 | void writepoint(uchar x,uchar y)
|
162 | {
|
163 | uchar x_pt,y_pt;
|
164 | uint address;
|
165 | x_pt=x;
|
166 | y_pt=y;
|
167 | address=(y_pt&0x7f)*32+x_pt/8+0x0800; //计算显示存储器地址
|
168 | twoparameter((uchar)(address),(uchar)(address>>8),0x24); //设置显示存储器地址
|
169 | x_pt=(~(x_pt%8))&0x07;
|
170 | y_pt=((y_pt&0x80)>>4)|0xf0;
|
171 | writecode(x_pt|y_pt); //写入数据
|
172 | }
|
173 |
|
174 | //显示矩形框
|
175 | //x:0~239; y:0~127
|
176 | void rectangle(uchar xstar,uchar xend,uchar ystar,uchar yend)
|
177 | {
|
178 | uchar i;
|
179 | ystar+=128; //显示点
|
180 | yend+=128;
|
181 | for(i=xstar;i<=xend;i++) //两水平线
|
182 | {
|
183 | writepoint(i,ystar);
|
184 | writepoint(i,yend);
|
185 | }
|
186 | for(i=ystar;i<=yend;i++) //两垂直线
|
187 | {
|
188 | writepoint(xstar,i);
|
189 | writepoint(xend,i);
|
190 | }
|
191 | }
|
192 |
|
193 |
|
194 | //擦除矩形框
|
195 | //x:0~239; y:0~127
|
196 | void clrrect(uchar xstar,uchar xend,uchar ystar,uchar yend)
|
197 | {
|
198 | uchar i;
|
199 | for(i=xstar;i<=xend;i++) //两水平线
|
200 | {
|
201 | writepoint(i,ystar);
|
202 | writepoint(i,yend);
|
203 | }
|
204 | for(i=ystar;i<=yend;i++) //两垂直线
|
205 | {
|
206 | writepoint(xstar,i);
|
207 | writepoint(xend,i);
|
208 | }
|
209 | }
|
210 |
|
211 |
|
212 | //8*8点阵显示
|
213 | //x:0~239; y:0~127
|
214 | void disp88(uchar x,uchar y)
|
215 | {
|
216 | uchar i,datpt,x_temp,y_temp;
|
217 | y_temp=y;
|
218 | for(i=8;i>0;i--)
|
219 | {
|
220 | //datpt=*ptr0++; //取数据
|
221 | datpt=0;
|
222 | x_temp=x; //重装x值
|
223 | if(datpt&0x80)
|
224 | writepoint(x_temp++,(y_temp+128));
|
225 | else writepoint(x_temp++,y_temp);
|
226 | if(datpt&0x40)
|
227 | writepoint(x_temp++,(y_temp+128));
|
228 | else writepoint(x_temp++,y_temp);
|
229 | if(datpt&0x20)
|
230 | writepoint(x_temp++,(y_temp+128));
|
231 | else writepoint(x_temp++,y_temp);
|
232 | if(datpt&0x10)
|
233 | writepoint(x_temp++,(y_temp+128));
|
234 | else writepoint(x_temp++,y_temp);
|
235 | if(datpt&0x08)
|
236 | writepoint(x_temp++,(y_temp+128));
|
237 | else writepoint(x_temp++,y_temp);
|
238 | if(datpt&0x04)
|
239 | writepoint(x_temp++,(y_temp+128));
|
240 | else writepoint(x_temp++,y_temp);
|
241 | if(datpt&0x02)
|
242 | writepoint(x_temp++,(y_temp+128));
|
243 | else writepoint(x_temp++,y_temp);
|
244 | if(datpt&0x01)
|
245 | writepoint(x_temp++,(y_temp+128));
|
246 | else writepoint(x_temp++,y_temp);
|
247 | y_temp++;
|
248 | }
|
249 | }
|
250 |
|
251 |
|
252 | //16*8点阵显示
|
253 | //x:0~29; y:0~127
|
254 | void disp168(uchar x,uchar y)
|
255 | {
|
256 | uchar i;
|
257 | uint address;
|
258 | address=y*32+x+0x0800; //计算显示存储器地址
|
259 | for(i=8;i>0;i--)
|
260 | {
|
261 | twoparameter((uchar)(address),(uchar)(address>>8),0x24); //设置显示存储器地址
|
262 | //oneparameter(*ptr0++,0xc0); //点阵左部
|
263 | //oneparameter(*ptr0++,0xc0); //点阵右部
|
264 | address+=32; //修改显示存储器地址
|
265 | }
|
266 | }
|
267 |
|
268 |
|
269 | //连续写点阵
|
270 | //x:0~29; y:0~127
|
271 | void dispauto(uchar x,uchar y,uchar line,uchar column)
|
272 | {
|
273 | uchar i,j;
|
274 | uint address;
|
275 | address=y*32+x+0x0800; //计算显示存储器地址
|
276 | for(i=line;i>0;i--) //显示line行
|
277 | {
|
278 | twoparameter((uchar)(address),(uchar)(address>>8),0x24); //设置显示存储器地址
|
279 | writecode(0xb0); //数据自动写状态
|
280 | for(j=column;j>0;j--) //共column列
|
281 | {
|
282 | //writeauto(*ptr0++); //自动写入数据
|
283 | }
|
284 | writecode(0xb2); //关闭自动写状态
|
285 | address+=32; //修改显示存储器地址
|
286 | }
|
287 | }
|