Thứ Hai, 3 tháng 12, 2018

Biến và hằng trong trình biên dịch CCS cho Pic


1.Biến và hằng số:
Biến để lưu trữ một giá giá trị mà giá trị có thể thay đổi, hằng số là một giá trị cố định . Biến và hằng với nhiều loại và và chiếm kích thước vùng nhớ khác nhau. Bài này chúng ta cùng đi tìm hiểu các kiểu biến và hằng.
1.1 Kiểu biến:
Biến và hằng số được lưu trữ bên trong bộ nhớ có giới hạn của vi điều khiển, và chương trình biên dịch cần biết số lượng bộ nhớ cần để cấp cho mỗi biến mà không làm lãng phí không gian bộ nhớ một cách không cần thiết. Do vậy người lập trình cần phải khai báo biến, chỉ định cả hai thông số đó là kích cỡ và kiểu dữ liệu cần lưu trữ. Điều quan trọng là hiểu được kích cỡ của mỗi kiễu dữ liệu của chương trình biên dịch mà bạn đang sử dụng bởi vì không phải tất cả các chương trình biên dịch quy định kích cỡ của kiểu biến giống nhau.   
 Các kiểu biến mặt định trong chương trình CCS
KiểuKích cỡUnsigned (Không dấu)Signed (Có dấu)
int1  Số 1 bit = true hay false ( 0 hay 1)0 đến 1 Không có
int8Số nguyên 1 byte ( 8 bit)
0 đến 255
-128 đến 127 
int16Số nguyên 16 bit0 đến 65535 -32768 đến 32767 
int32Số nguyên 32 bit0 đến 4294967295 -2147483648 đến 2147483647 
int48Số nguyên 48 bit
0 đến
281474976710655
-140737488355328 đến
140737488355327
int64Số nguyên 64 bitKhông Có-9223372036854775808 đến
9223372036854775807
float32Số thực 32 bit  -1.5 x 1045  đến  3.4 x 1038
 Bảng tương ứng giữa kiểu biến tiêu chuẩn của C với kiểu mặt định của trình biên dịch CCS
Kiểu tiêu chuẩn của CKiểu mặt định của trình biên dịch CCS
shortint1
charunsigned int8
intint8
longint16
long longint32
floatfloat32
double Không có
 Theo mặt định của chương trình biên dịch , kiểu short là 1 bit, int là 8 bit, long là 16 bit. Ta muốn thay đổi kích thước bằng lệnh tiền xữ lý #TYPE
Ví dụ: #TYPE SHORT=8, INT=16, LONG=32
1.2 Phạm vi biến (Variable scope)
Biến cục bộ: Là biến trong phạm vi một hàm và chỉ có thể được sử dụng trong hàm ấy. Biến cục bộ không có hiệu lực ở ngoài phạm vi của hàm mà ở đó nó được khai báo và sẽ được giải phóng khi kết thúc hàm.
Biến toàn cục: Là biến được khai báo ở ngoài tất cả các hàm và có thể được sử dụng ở phạm vi toàn bộ chương trình. Biến này có hiệu lực ở tất cả các hàm trong chương trình và thường được khai báo ở đầu chương trình. Biến toàn cục lưu giữ giá trị của nó trong suốt thời gian chương trình được thực thi.
Ví dụ biến cục bộ và biến toàn cục:
unsigned char globey; // biến toàn cục

void function_z( void) // đây là một hàm có thể được gọi từ hàm main 
{
unsigned int tween; // biến cục bộ của hàm function_z
tween=12; // hợp lệ bởi vì nó sử dụng trong hàm mà nó được khai báo
globey =47;// hợp lệ bởi vì đây là biến toàn cục
main_loc = 12; // không hợp lệ và tạo ra một lỗi vì nó là biến cục bộ của hàm main
}
void main()
{
unsined char main_loc; // khai báo biến cục bộ của hàm main
globey = 34; // hợp lệ bởi vì đây là biến toàn cục
tween = 12; // không hợp lệ và tạo ra một lỗi vì nó là biến cục bộ của hàm function_z
 while(1);
}

1.3 Hằng số (Constants)
Hằng số là biến có giá trị không thay đổi trong suốt quá trình thực thi chương trình. Hằng số có thể mang các kiểu dữ liệu khác nhau như số nguyên, số thực, kiểu ký tự hay luận lý, con trỏ, vân vân... như các biến thông thường ngoại trừ giá trị của chúng không thể biến đổi sau khi được định nghĩa.

Số nguyên

Số nguyên có thể được định nghĩa là số thập phân, số cơ số 8 (octal) hay cơ số 16 (hexa). Số thập phân được biểu diễn như cách chúng ta dùng hằng ngày, số cơ số 8 được bắt đầu bằng ký tự 0 (zero) và số cơ số 16 được bắt đầu bằng 0x. Cũng tương tự như các biến kiểu nguyên, các giá trị hằng số mặc định là kiểu integer (int), có thể định nghĩa chúng theo kiểu long hay unsigned bằng cách thêm vào phía sau giá trị các ký tự u hoặc U (unsigned), l hoặc L (long). Ví dụ:

53         // decimal, int
0357       // octal
0xa2c      // hexadecimal
789u       // unsigned int
2512l      // long
82ul       // unsigned long
34lU       // unsigned long
Các ký tự u và l có thể viết in hoặc thường.

Số thực


Số thực có thể được biểu diễn bằng dấu thập phân (dấu chấm), dùng chữ e hoặc cả hai. Kiểu mặc định của số thực là double, tuy nhiên số thực có thể được khai báo theo kiểu float hoặc long double bằng các ký tự f hoặc F, l hoặc L ở phía sau giá trị. Ví dụ:
5.23       // double
3.23e8     // 3.23 x 10^8
6.75e-5f   // float, 6.75 x 10^-5
6.75e-5L   // long double, 6.75 x 10^-5

Ký tự và chuỗi


Ký tự được biểu diễn bằng dấu nháy đơn ('a') bao quanh một ký tự trong khi đó chuỗi được biểu diễn bằng dấu nháy đôi ("chuỗi ký tự"). Ký tự và chuỗi cũng có thể biểu diễn các ký tự đặc biệt như sang dòng mới (\n) hoặc tab (\t). Những ký tự đặc biệt này được mở đầu bằng dấu gạch chéo ngược (\).
Mã gạch chéo ngược Ý nghĩa
\nnewline, dòng mới
\rcarriage return, trở về
\ttab ngang
\v tab dọc
\bbackspace, xóa lùi
\fform feed (page feed)
\aalert (beep)
\'single quote (')
\"double quote (")
\?question mark (?)
\\backslash (\)











Khai báo hằng số

Hằng số có thể được khai báo bằng hai cách, dùng const phía trước câu lệnh khai báo biến thông thường hoặc định nghĩa tiền xử lý (#define) theo cú pháp #define <tên> <giá trị>
ví dụ:
#include <pic16f877a.h>
#define PI 3.14159
void main(void)
{
const double bankinh = 7.0;
double chuvi;

chuvi = 2 * PI * bankinh;
while(1);
 
}


- Biến PI là hằng số và được định nghĩa bằng #define. Tiền xử lý #define nằm ở vị trí đầu chương trình nhằm định nghĩa các giá trị hằng số.
- Biến bankinh là biến cục bộ kiểu số thực được định nghĩa bằng const trong hàm main()

Lưu ý rằng ở cuối câu lệnh định nghĩa tiền xử lý #define không có dấu chấm phẩy (;).
1.3 Phân lớp lưu trữ :
Biến có thể khai báo trong ba phân lớp lưu trữ: auto, static, và register. Auto, hoặc automatic là phân lớp mặt định, do vậy khi khai báo
int value_1 ;
hoặc
auto int value_1;
Là giống nhau
 Automatic:
Một biến cục bộ phân lớp automatic không được khởi tạo giá trị ban đầu khi cấp phát bộ nhớ, vì vậy người lập trình nên đảm bảo dữ liệu có giá trị trước khi sử dụng. Vùng không gian bộ nhớ sẻ được giải phóng khi thoát khỏi hàm, nghĩa là giá trị sẽ bị mất và khi quay trở lại hàm thì giá trị đó không tồn tại. Biến lớp automatic được khai báo như phía dưới
       auto int value_1;
      hoặc
int value_1 ;
Static:
Một biến cục bộ static chỉ có phạm vị trong hàm mà nó định ngĩa (không thể truy xuất từ các hàm khác), nhưng nó được cấp phát trong vùng nhớ toàn cục.  Biến static được khởi tạo giá trị ban đầu bằng 0 khi lần đầu tiên hàm được gọi, và và giá trị lưu trong biến không mất đi khi thoát khỏi hàm. Và ta có thể sử dụng giá trị này mỗi khi hàm được gọi lại.
static int value_2;

Register:
Biến cục bộ register gần giống như biến automatic. Sự khác biệt đó là chương trình biên dịch sẽ sử dụng thanh ghi của vi điều khiển như là một biến để giảm số chu kỳ máy yêu cầu khi truy cập biến. Có rất ít thanh ghi khi so sánh với bộ nhớ tổng trong một máy điển hình. Do vậy phân lớp này sử dụng một cách tiết kiệm . Trong chương trình biến dịch CCS không hỗ trợ phân lớp này nhưng vẫn có thể khai báo.
1.3 Ép kiểu (Type casting) 
Bạn có thể ép kiểu , thường là tiết kiệm ram , hay muốn tiết kiệm thời gian tính , . . ..

VD : 
Int8 a =8 , b=200; 
Int16 c ; 
C= ( int16) a * b ; // c= 1600 , a chuyển sang 16 bit , 16bit*8bit tự động chuyển sang 16 bit , kết quả là 16 bit trong c , lưu ý biến a , b vẫn là 8 bit .


8bit * 8bit -> phép nhân là 8 bit , KQ là 8 bit
16bit * 8 bit -> phép nhân là 16 bit , KQ là 16 bit 

32bit * 16 bit -> phép nhân là 32 bit , KQ là 32 bit 
16bit * 16 bit -> phép nhân là 16 bit , KQ là 16 bit 
. . . v . v . . . 
Có thể ép kiểu kết quả : VD : 16b * 8b ->16bit , nếu gán vào biến 8 bit thì KQ sẽ cắt bỏ 8 bit cao .


Giao tiếp với LCD


1. Sơ đồ chân của text LCD
giao tiếp lcd
Tên chân và chức năng:
Thứ TựTênChức năng
1Vss (GND)0 V
2Vdd (VCC)5 VDC
3VeeĐiều chỉnh độ tương phản, nguồn từ 0-5VDC
4RSLựa chọn thanh ghi (Thanh ghi lệnh và thanh ghi dữ liệu)
RS=0 : Thanh ghi lệnh (khi ghi) tức là data trên chân D0-D7 là lệnh
RS=1 : Thanh ghi dữ liệu (Khi ghi và đọc): tức là data trên chân D0-D7 là dữ liệu
5R/WR/W=0 : Ghi dữ liệu (vi điều khiển ->LCD)
R/W=1 : Đọc dữ liệu (LCD-> Vi điều khiển)
6EE=0 : Vô hiệu hóa LCD
E=1 : LCD hoạt động
E chuyển từ 1->0: Bắt đầu ghi/ đọc LCD
7D0 Chân dữ liệu bit 0
8D1 Chân dữ liệu bit 1
9D2 Chân dữ liệu bit 2
10D3 Chân dữ liệu bit 3
11D4 Chân dữ liệu bit 4
12D5 Chân dữ liệu bit 5
13D6 Chân dữ liệu bit 6
14D7 Chân dữ liệu bit 7
16A Cực dương led nền LCD
17K Cực âm led nền LCD
IC lái LCD HD4478U
Trong các text LCD loại 1 dòng và hai dòng trên thị trường hiện nay thường tích hợp chip lái HD44780U hoặc chip tương thích với chíp lái này.

 Sơ đồ khối của HD4478U
Thanh ghi trong HD4478U:
HD4478U có hai thanh ghi 8 bit: Thanh ghi lệnh (IR) và thanh ghi dữ liệu (DR)
Thanh ghi IR lưu trữ mã lệnh: Như xóa hiện thị và dịch con trỏ, và chứa thông tin địa chỉ cho vùng RAM dữ liệu hiển thị (DDRAM) và vùng RAM tạo ký tự CGRAM. IR chỉ có thể ghi từ vi điều khiển.
Thanh ghi DR dùng để lưu trữ tạm thời dữ liệu để ghi đến DDRAM hoặc CGRAM và dữ liệu lưu trữ tạm thời có thể đọc từ DDRAM hoặc CGRAM. Dữ liệu được ghi đến thanh ghi DR, dữ liệu đó sẽ tự động được truyền đến DDRAM hoặc CGRAM một cách tự động. Thanh ghi DR cũng là vùng lưu trữ dữ liệu tạm thời khi ta muốn đọc dữ liệu DDRAM hoặc CGRAM. Khi các thông tin về địa chỉ được ghi đến thanh ghi IR, dữ liệu được từ DDRAM hoặc CGRAM được đọc và lưu trữ vào DR một cách tự động bởi LCD. Khi đó ta tiến hành đọc dữ liệu lưu trữ ở thanh ghi DR. Sau khi đọc, dữ liệu trong DDRAM hoặc CGRAM tại địa chỉ kế tiếp được đưa đến thanh ghi DR để sẳn sàng cho lần đọc kế tiếp từ vi điều khiển. Nhờ tín hiệu lựa chọn thanh ghi (RS), khi đó ta thể lựa chọn giữa hai thanh ghi IR và DR 
Cờ bận (BF):
Khi cờ bận =1 , LCD đang bận xử lý, và lệnh tiếp theo sẽ không được chấp nhận. Khi RS=0 và R/W=1, cờ bận được xuất ra chân DB7. Lệnh tiếp theo chỉ có thể được viết sau khi cờ bận =0;
Bộ đếm địa chỉ (AC):
Bộ đếm địa chỉ (AC) sẽ gán địa chỉ đến cả hai DDRAM và CGRAM. Khi địa chỉ của một lệnh được viết đến IR , thông tin địa chỉ được gửi từ IR đến AC . Lựa chọn của một trong hai DDRAM hoặc CGRAM cũng được xác định đồng thời bởi lệnh. 
Sau khi ghi (Hoặc đọc từ) DDRAM hoặc CGRAM, AC sẽ tự động tăng lên 1 hoặc giảm 1. Dữ liệu AC được xuất ra chân DB0 đến DB6 khi RS=0 và R/W =1
Bộ nhớ trong HD44780U
HD44780U có 3 loại bộ nhớ, đó là bộ nhớ RAM dữ liệu cần hiển thị DDRAM (Display Data RAM), bộ nhớ chứa ROM chứa bộ font tạo ra ký tự CGROM (Character Generator ROM) và bộ nhớ RAM chứa bộ font tạo ra các symbol tùy chọn CGRAM (Character Generator RAM). Để điều khiển hiển thị Text LCD chúng ta cần hiểu tổ chức và cách thức hoạt động của các bộ nhớ này:
2.1 DDRAM.
       DDRAM là bộ nhớ tạm chứa các ký tự cần hiển thị lên LCD, bộ nhớ này gồm có 80 ô được chia thành 2 hàng, mỗi ô có độ rộng 8 bit và được đánh số từ 0 đến 39 cho dòng 1; từ 64 đến 103 cho dòng 2. Mỗi ô nhớ tương ứng với 1 ô trên màn hình LCD. Như chúng ta biết LCD loại 16x2 có thể hiển thị tối đa 32 ký tự (có 32 ô hiển thị), vì thế có một số ô nhớ của DDRAM không được sử dụng làm các ô hiển thị. Để hiểu rõ hơn chúng ta tham khảo hình 3 bên dưới

 

Tổ chức của DDRAM.

       Chỉ có 16 ô nhớ có địa chỉ từ 0 đến 15 và 16 ô địa chỉ từ 64 đến 79 là được hiển thị trên LCD. Vì thế muốn hiển thị một ký tự nào đó trên LCD chúng ta cần viết ký tự đó vào DDRAM ở 1 trong 32 địa chỉ trên. Các ký tự nằm ngoài 32 ô nhớ trên sẽ không được hiển thị.

2.2 CGROM.
       CGROM là vùng nhớ cố định chứa định nghĩa font cho các ký tự. Chúng ta không trực tiếp truy xuất vùng nhớ này mà chip HD44780U sẽ tự thực hiện khi có yêu cầu đọc font để hiện thị. Một điều đáng lưu ý là địa chỉ font của mỗi ký tự  vùng nhớ CGROM chính là mã ASCII của ký tự đó. Ví dụ ký tự ‘a’ có mã ASCII là 97, tham khảo tổ chức của vùng nhớ CGROM trong hình 4 bạn sẽ nhận thấy địa chỉ font của ‘a’ có 4 bit thấp là 0001 và 4 bit cao là 0110, địa chỉ tổng hợp là 01100001 = 97.
       CGROM và DDRAM được tự động phối hợp trong quá trình hiển thị của LCD. Giả sử chúng ta muốn hiển thị ký tự ‘a’ tại vị trí đầu tiên, dòng thứ 2 của LCD thì các bước thực hiện sẽ như sau: trước hết chúng ta biết rằng vị trí đầu tiên của dòng 2 có địa chỉ là 64 trong bộ nhớ DDRAM (xem hình 3), vì thế chúng ta sẽ ghi vào ô nhớ có địa chỉ 64 một giá trị là 97 (mã ASCII của ký tự ‘a’). Tiếp theo, chip HD44780U đọc giá trị 97 này và coi như là địa chỉ của vùng nhớ CGROM, nó sẽ tìm đến vùng nhớ CGROM có địa chỉ 97 và đọc bảng font đã được định nghĩa sẵn ở đây, sau đó xuất bản font này ra các “chấm” trên màn hình LCD tại vị trí đầu tiên của dòng 2 trên LCD. Đây chính là cách mà 2 bộ nhớ DDRAM và CGROM phối hợp với nhau để hiển thị các ký tự. Như mô tả, công việc của người lập trình điều khiển LCD tương đối đơn giản, đó là viết mã ASCII vào bộ nhớ DDRAM tại đúng vị trí được yêu cầu, bước tiếp theo sẽ do HD44780U đảm nhiệm.

 

Hình 4. Vùng nhớ CGROM.
2.3 CGRAM.
       CGRAM là vùng nhớ chứa các symbol do người dùng tự định nghĩa, mỗi symbol được có kích thước 5x8 và được dành cho 8 ô nhớ 8 bit. Các symbol thường được định nghĩa trước và được gọi hiển thị khi cần thiết. Vùng này có tất cả 64 ô nhớ nên có tối đa 8 symbol có thể được định nghĩa. 
 
 Các kiểu hiển thị:

3. Mô tả lệnh khi giao tiếp LCD


LệnhRSRWD7D6D5D4D3D2D1D0Thời gian thực thi
Clear display00000000011.64mS
Cursor home000000001x1.64mS
Entry mode set00000001I/DS40uS
Display on/off control0000001DUB40uS
Cursor/Display Shift000001D/CR/Lxx40uS
Function set00001DLNFxx40uS
Set CGRAM address0001CGRAM address40uS
Set DDRAM address001DDRAM address40uS
Read "BUSY" flag (BF)01BFDDRAM address-
Write to CGRAM or DDRAM10D7D6D5D4D3D2D1D040uS
Read from CGRAM or DDRAM11D7D6D5D4D3D2D1D040uS



I/D 1 = Increment (by 1)         R/L 1 = Shift right
    0 = Decrement (by 1)             0 = Shift left
    
S 1 = Display shift on           DL 1 = 8-bit interface
  0 = Display shift off             0 = 4-bit interface
  
D 1 = Display on                 N 1 = Display in two lines
  0 = Display off                  0 = Display in one line
  
U 1 = Cursor on                  F 1 = Character format 5x10 dots
  0 = Cursor off                   0 = Character format 5x7 dots

B 1 = Cursor blink on            D/C 1 = Display shift
  0 = Cursor blink off               0 = Cursor shift

Clear Display (Xóa hiển thị): Xóa hiển thị là viết mã khoảng trắng 20H vào tất cả địa chỉ DDRAM. Khi đó thiết lập bộ đếm địa chỉ bằng 0. Nói cách khác khi đó tất cả các hiển thị sẽ biến mất và con trỏ hoặc nhấp nháy sẽ nằm ở góc trái màn hình (ở dòng đầu tiên nếu là LCD hai dòng).

Cursor Home (Đưa con trỏ về vị trí đầu): Thiết lập bộ đếm địa chỉ bằng 0, và trả hiển thị về trạng thái gốc nếu nó bị dịch. Dữ liệu trong DDRAM không bị thay đổi. Con trỏ hoặc nhấp nháy sẽ nằm ở góc trái màn hình (ở dòng đầu tiên nếu là LCD hai dòng).

Entry Mode Set:

I/D: Tăng (I/D=1) hoặc giảm (I/D=0) địa chỉ DDRAM lên 1 khi mã ký tự được viết đến hoặc đọc từ DDRAM

Con trỏ hoặc nhấp nháy di chuyển sang phải khi tăng lên 1 và sang trái khi giảm đi 1. Giống nhau cho cả việc đọc và viết đến CGRAM.

S: Dịch mục hiển thị sang phải (I/D=0) hoặc sang trái (I/D=1) khi S là 1. Hiển thị sẽ không dịch nếu S=0.
S/CR/L
00Dịch vị trí con trỏ sang trái (AC giảm 1)
01Dịch vị trí con trỏ sang phải(AC tăng 1)
10Dịch mục hiển thị sang trái. Con trỏ theo dịch theo hiển thị
11Dịch mục hiển thị sang phải. Con trỏ theo dịch theo hiển thị

Display On/Off Control (Điều khiển tắt/mở hiển thị):
D: Bật hiển thị khi D=1 và tắt khi D=0. Khi tắt, dữ liệu hiển thị vẫn nằm trong DDRAM, khi muốn hiển thị dữ liệu này ta chỉ cần thiết lập D=1.
C: Con trỏ được hiển thị khi C=1 và không hiển thị khi C=0. Thậm chí khi con trỏ không xuất hiện, chức năng I/D và thông số khác sẽ không thay đổi khi hiển thị dữ liệu được viết. Con trỏ được hiển thị sử dụng 5 dấu chấm của hàng thứ 8 (ký tự 5x8).
B: Ký tự được chỉ thị bởi con trỏ nhấp nháy khi b=1
Set DDRAM Address: lệnh này sẽ set địa chỉ DDRAM AAAAAAA vào bộ đếm địa chỉ
Dữ liệu DDRAM khi đó có thể viết hoặc đọc bởi vi điều khiển
Read Busy Flag and Address (lệnh đọc cờ bận và địa chỉ)
Cờ bận báo LCD đang xử lý lệnh trước đó, và nó sẽ không chấp nhận lệnh tiếp theo cho đến khi BF=0, do vậy phải kiểm tra cờ BF trước khi viết đến LCD. cùng lúc này giá trị của bộ đếm địa chỉ cũng được đọc. Bộ đếm địa chỉ này được sử dụng cho cả hai địa chỉ CG và DDRAM, và giá trị của nó được xác định bởi lệnh trước đó.
Write Data to CG or DDRAM (ghi dữ liệu đến CG hoặc DDRAM)

Các lệnh thường dùng trong giao tiếp với LCD

01H: Xóa toàn bộ nội dung đang hiển thị trên màn hình
02H: Dịch chuyển con trỏ về vị trí đầu màn hình
04H: Dịch con trỏ sang trái màn hình
05H: Dịch màn hình sang phải
06H: Tự động dịch con trỏ sang phải 1 vị trí mỗi khi xuất xong 1 ký tự ra màn hình
07H Dịch màn hình sang trái
08H: Tắt con trỏ, tắt hiển thị
0AH:Tắt hiển thị, bật con trỏ
0CH: Bật hiển thị và tắt cong trỏ
0EH: Bật hiển thị, nhấp nháy con trỏ
0FH: Tắt hiển thị, nhấp nháy con trỏ
10H: Dịch vị trí con trỏ sang trái
14H: Dịch vị trí con trỏ sang phải
18H: Dịch toàn bộ màn hình sang trái
1CH:Dịch toàn bộ màn hình sang phải
0E0H: Bật hiển thị và bật con trỏ
80H: Di chuyển con trỏ về đầu dòng 1
C0H: Di chuyển con trỏ về đầu dòng 2
38H: Giao tiếp 8 bit hiển thị 2 dòng với kích thước font 5x7 
28H: Giao tiếp 4 bit hiển thị 2 dòng với kích thước font 5x7


Kết nối với LCD ở chế độ 4 bit:
 Giao Tiếp LCD

HD44780U có thể nhận dữ liệu ở chế độ vận hành 4 bit hoặc 8 bit khi giao tiếp với vi điều khiển.
Khi sử dụng dao diện dữ liệu 4 bit, chỉ có 4 chân (DB4 đến DB7) được sử dụng để truyền. Các chân DB0 đến BD3 không sử dụng.  Dữ liệu truyền giữa HD4478U và vi điều khiển được chia làm hai lần để hoàn thành truyền dữ liệu. Thứ tự truyền là 4 bit cao truyền trước, 4 bit thấp truyền sau .
Chế độ dữ liệu 8 bit, cả 8 đường dữ liệu (DB0 - DB7) được sử dụng
Trước khi sử dụng LCD ta phải khởi tạo nó theo lưu đồ sau
Trong CCS được tích hợp sẵn thư viện LCD. Để thực hiện giao tiếp các bạn chỉ cần gọi
#include <lcd.c>
Thư viện hỗ trợ các hàm:
lcd_init()  Hàm khởi tạo LCD
lcd_putc(c)  Xuất kí tự lên LCD
lcd_gotoxy(x,y) Đặt ví trí con trỏ( vị trí cần xuất ký tự) tại x của dong y(y=1 hoặc y=2)
lcd_getc(x,y)   Đọc về giá trị tại x của dong y
lcd_cursor_on(int1 on) Bật vị trí con trỏ
lcd_set_cgram_char(w, *p)   Hàm này dùng khi bạn xuất kí tự đặc biệt. Ví dụ chứ có dấu vào CGRAM.
Để xóa nội dung  và đưa con trỏ về đầu dòng bạn xuất ký tự ‘f’. 
Để về đầu dòng của dòng 2: ‘n’.
Về đầu dong của dòng hiện tại: ‘a’.
Để lùi về con trỏ về 1 ví trí so với vị trí hiện tại: ‘b’
Chú ý trước khi  sử dụng bạn phải định nghĩa lại các chân sau cho thư viện:
LCD_ENABLE_PIN
LCD_RS_PIN
LCD_RW_PIN
LCD_DATA4
LCD_DATA5
LCD_DATA6 
LCD_DATA7

4. Tạo một ký tự riêng hoặc hiển có dấu với text LCD bằng cách sử dụng vùng nhớ CGRAM
 Hiển thị LCD có dấu
#include <16f877a.h>
#device *=16 ADC=10
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=12000000)
#define LCD_ENABLE_PIN PIN_C2
#define LCD_RS_PIN PIN_C0
#define LCD_RW_PIN PIN_C1
#define LCD_DATA4 PIN_C3
#define LCD_DATA5 PIN_C4
#define LCD_DATA6 PIN_C5
#define LCD_DATA7 PIN_C6
#include <lcd.c>
void lcd_load_custom_chars(void);
//==========================
void main()
{
lcd_init();
lcd_load_custom_chars();
lcd_gotoxy(1,1);
lcd_putc(0); //HIEN THI MAT CUOI
lcd_gotoxy(2,1); // hang 1 cot 2
printf(lcd_putc, "YTUONGNHANH.VN"); 
lcd_putc(0); // HIEN THI MAT CUOI
lcd_gotoxy(1,2); // hàng 2 cot 1
lcd_putc(3); // hien thi cay hoa
lcd_putc(3); // hien thi cay hoa
lcd_putc(3); // hien thi cay hoa
lcd_putc(3); // hien thi cay hoa
lcd_gotoxy(9,2); // hàng 2 cot 9
lcd_putc(2); // hien thi trái tim
lcd_gotoxy(13,2); // hàng 2 cot 1
lcd_putc(3); // hien thi cay hoa
lcd_putc(3); // hien thi cay hoa
lcd_putc(3); // hien thi cay hoa
lcd_putc(3); // hien thi cay hoa
while(1);
}
/* Bạn chèn đoạn ký tự tạo tại đây, tối đa là 8 ký tự */
/* Gọi ký tự tự tạo bằng hàm lcd_putc(char number) , ví dụ lcd_putc(number0)..... */
const int8 lcd_custom_chars[] =
{
// Char Number 0 mat cuoi
0b00000000,
0b00001010,
0b00000000,
0b00000100,
0b00010001,
0b00001110,
0b00000000,
0b00000000,
//Char Number 1 mat buon
0b00000000,
0b00001010,
0b00000000,
0b00000100,
0b00000000,
0b00001110,
0b00010001,
0b00000000,
// Char Number 2 : Trai tim
0b00001010,
0b00011111,
0b00011111,
0b00001110,
0b00000100,
0b00000000,
0b00000000,
0b00000000,
// Char Number 3 :Cay hoa
0b00001110,
0b00010001,
0b00001110,
0b00000100,
0b00011111,
0b00000100,
0b00011011,
0b00000000,
// Char Number 4 -- Mui ten len
0b00000100,  // .....O..
0b00001110,  // ....OOO.
0b00011111,  // ...OOOOO
0b00000100,  // .....O..
0b00000100,  // .....O..
0b00000100,  // .....O..
0b00000100,  // .....O..
0b00000000,  // ........

// Char Number 5 -- Mui ten xuong
0b00000100,  // .....O..
0b00000100,  // .....O..
0b00000100,  // .....O..
0b00000100,  // .....O..
0b00011111,  // ...OOOOO
0b00001110,  // ....OOO.
0b00000100,  // .....O..
0b00000000,  // ........

// Char Number 6 -- Do C
0b00001100,  // ....OO..
0b00010010,  // ...O..O.
0b00010010,  // ...O..O.
0b00001100,  // ....OO..
0b00000000,  // ........
0b00000000,  // ........
0b00000000,  // ........
0b00000000,  // ........ 
// Char Number 7 -- Khoang Trang
0b00000000,  // ........
0b00000000,  // ........
0b00000000,  // ........
0b00000000,  // ........
0b00000000,  // ........
0b00000000,  // ........
0b00000000,  // ........
0b00000000,  // ........

};
void lcd_load_custom_chars(void)
{
int8 i;
//Thiết lập địa chỉ con trỏ về CGRAM 
lcd_send_byte(0, 0x40); 
// Nạp dữ liệu ký tự tự tạo vào CGRAM .
// Bộ nhớ chỉ chứa tối đa 8 ký tự .
for(i = 0; i < sizeof(lcd_custom_chars); i++)
   {
    lcd_send_byte(1, lcd_custom_chars[i]);
   }
//Thiết lập địa chỉ con trỏ về DDRAM
lcd_send_byte(0, 0x80);
}
Hướng dẫn phần mềm xuất số nhị phân cho các ký tự tự tạo cho màn hình LCD
tạo ký tự riêng cho lcd
Vẽ ký tự riêng muốn hiển thị lên LCD (Lưu ý do màn hình là 5 x7 dot, nên chỉ vẽ trong phần 5 cột (tính từ phải qua) và 7 hàng (tính từ trên xuống)
Nhấn nút Tạo code.
Nhấn nút Ký tự tiếp.
Lặp lại vậy cho đến hoàn thành 8 ký tự (tối đa) hoặc ít hơn.
Copy mảng ký tự vừa tạo vào đoạn code của chúng ta.
Gọi ký tự hiện thị ra LCD và kiểm tra.

Bài đăng mới nhất

Valdes Fernando - Microcontrollers Applications With Pic

Bài đăng phổ biến