21
Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG Trần Thừa – 2010 72 BÀI 2: GIAO TIẾP VỚI LED 7 ĐOẠN VÀ LED MA TRẬN ĐƠN SẮC PHƯƠNG PHÁP MỞ RỘNG PORT XUẤT I. Giao tiếp với led 7 đoạn. 1. Giới thiệu led 7 đoạn. Led 7 đoạn là linh kiện chuyên dùng để hiển thị. Cấu tạo của nó bao gồm 8 led nối chung cathode (cực âm) gọi là cathode chung hoặc anode (cực dương) gọi là anode chung. Hình 3. Led 7 đoạn Các đoạn được đặt tên từ a đến g, riêng led thứ 8 đặt tên là dp (dot point). Led 7 đoạn hiển thị ký tự bằng cách bật sáng các đoạn cần thiết, các tổ hợp của các đoạn bật sáng được quy ước thành mã hiển thị của led 7 đoạn. Bộ mã hiển thị của led 7 đoạn thông thường là 16 ký tự trong hệ thống số hex. Tuy nhiên, nếu cần dùng 1 ký tự đặt biệt nào đó, ta vẫn có thể tạo ra mã hiển thị của led 7 đoạn một cách đơn giản. Trong MikroC đã tích hợp sẵn công cụ tạo mã hiển thị cho 2 loại led 7 đoạn cathode chung và anode chung. Công cụ này nằm trong menu Tools.

Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

  • Upload
    spy004

  • View
    3.432

  • Download
    2

Embed Size (px)

Citation preview

Page 1: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 72

BÀI 2: GIAO TIẾP VỚI LED 7 ĐOẠN

VÀ LED MA TRẬN ĐƠN SẮC

PHƯƠNG PHÁP MỞ RỘNG PORT XUẤT

I. Giao tiếp với led 7 đoạn.

1. Giới thiệu led 7 đoạn.

Led 7 đoạn là linh kiện chuyên dùng để hiển thị. Cấu tạo của nó bao gồm 8 led nối chung cathode (cực âm) gọi là cathode chung hoặc anode (cực dương) gọi là anode chung.

Hình 3. Led 7 đoạn

Các đoạn được đặt tên từ a đến g, riêng led thứ 8 đặt tên là dp (dot point). Led 7 đoạn hiển thị ký tự bằng cách bật sáng các đoạn cần thiết, các tổ hợp của các đoạn bật sáng được quy ước thành mã hiển thị của led 7 đoạn. Bộ mã hiển thị của led 7 đoạn thông thường là 16 ký tự trong hệ thống số hex. Tuy nhiên, nếu cần dùng 1 ký tự đặt biệt nào đó, ta vẫn có thể tạo ra mã hiển thị của led 7 đoạn một cách đơn giản.

Trong MikroC đã tích hợp sẵn công cụ tạo mã hiển thị cho 2 loại led 7 đoạn cathode chung và anode chung. Công cụ này nằm trong menu Tools.

Page 2: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 73

Bảng mã hiển thị led 7 đoạn loại anode chung:

Bảng mã hiển thị led 7 đoạn loại cathode chung:

Số a b c d e f g dp Mã hex

0 0 0 0 0 0 0 1 1 0x03

1 1 0 0 1 1 1 1 1 0x9F

2 0 0 1 0 0 1 0 1 0x25

3 0 0 0 0 1 1 0 1 0x0D

4 1 0 0 1 1 0 0 1 0x99

5 0 1 0 0 1 0 0 1 0x49

6 0 1 0 0 0 0 0 1 0x41

7 0 0 0 1 1 1 1 1 0x1F

8 0 0 0 0 0 0 0 1 0x01

9 0 0 0 0 1 0 0 1 0x09

Số dp g f e d c b a Mã hex

0 1 1 0 0 0 0 0 0 0xC0

1 1 1 1 1 1 0 0 1 0xF9

2 1 0 1 0 0 1 0 0 0xA4

3 1 0 1 1 0 0 0 0 0xB0

4 1 0 0 1 1 0 0 1 0x99

5 1 0 0 1 0 0 1 0 0x92

6 1 0 0 0 0 0 1 0 0x82

7 1 1 1 1 1 0 0 0 0xF8

8 1 0 0 0 0 0 0 0 0x80

9 1 0 0 1 0 0 0 0 0x90

Số a b c d e f g dp Mã hex

0 1 1 1 1 1 1 0 0 0xFC

1 0 1 1 0 0 0 0 0 0x60

2 1 1 0 1 1 0 1 0 0xDA

3 1 1 1 1 0 0 1 0 0xF2

4 0 1 1 0 0 1 1 0 0x66

5 1 0 1 1 0 1 1 0 0xB6

6 1 0 1 1 1 1 1 0 0xBE

7 1 1 1 0 0 0 0 0 0xE0

8 1 1 1 1 1 1 1 0 0xFE

9 1 1 1 1 0 1 1 0 0xF6

Số dp g f e d c b a Mã hex

0 0 0 1 1 1 1 1 1 0x3F

1 0 0 0 0 0 1 1 0 0x06

2 0 1 0 1 1 0 1 1 0x5B

3 0 1 0 0 1 1 1 1 0x4F

4 0 1 1 0 0 1 1 0 0x66

5 0 1 1 0 1 1 0 1 0x6D

6 0 1 1 1 1 1 0 1 0x7D

7 0 0 0 0 0 1 1 1 0x07

8 0 1 1 1 1 1 1 1 0x7F

9 0 1 1 0 1 1 1 1 0x6F

a là MSB, dp là LSB

a là LSB, dp là MSB a là MSB, dp là LSB

a là LSB, dp là MSB

Page 3: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 74

2. Giao tiếp với led 7 đoạn

Có 2 phương pháp chính:

a. Phương pháp chốt

Dữ liệu cần hiển thị được đưa độc lập đến từng led . Vì thế ưu điểm của nó là lập trình rất đơn giản, chúng ta chỉ cần ghi mã hiển thị ra PORT giao tiếp. Tuy nhiên, nhược điểm lớn nhất của phương pháp này là tốn rất nhiều PORT điều khiển.

U1

COMMON CATHODE

e1 d2

E1

3

c4

dp5

b6 a7

E2

8

f9

g10

R1R2

8x330

R3R4R5R6R7R8

PO

RT

Hình 4. Minh họa phương pháp chốt

b. Phương pháp quét

Các chân dữ liệu tương ứng của các led được nối với nhau để nhận dữ liệu từ 1 PORT. Tất cả các led nhận được dữ liệu giống nhau nhưng chỉ có 1 led được chọn để bật sáng. Ta tuần tự cấp dữ liệu của led thứ nhất đồng thời chỉ bật sáng led này, sau đó lại cấp dữ liệu của led tiếp theo đồng thời bật led tiếp theo. Cứ như vậy mà lặp lại với tần số lớn hơn 24 lần/s cho mỗi led, do hiện tượng lưu ảnh ở mắt người nên chúng ta có cảm giác các led hiển thị số liệu khác nhau cùng 1 lúc.

Phương pháp này có ưu điểm là ít tốn chân vi điều khiển và có thể điều khiển nhiều led.

Hình 5. Sơ đồ module led 7 đoạn

ab

U1

CA

e1 d2

E1

3

c4

dp5

b6 a7

E2

8

f9

g10

cdefgdp

J1

DATA PORT

12345678910

abcdefgdp

R17

8 x 330

R18R19R20R21R22R23R24

U2

CA

e1 d2

E1

3

c4

dp5

b6 a7

E2

8

f9

g10

U3

CA

e1 d2

E1

3

c4

dp5

b6 a7

E2

8

f9

g10

U4

CA

e1 d2

E1

3

c4

dp5

b6 a7

E2

8

f9

g10

cba

fed

dpg

VCC

J2

CONTROL PORT

12345678910

Q1c1815

Q2c1815

Q3c1815

Q4c1815

VCC

R13

8k2

R14

8k2

ab

R15

8k2

cd

R16

8k2

efgdp

abcdefgdp

Page 4: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 75

Lưu đồ giải thuật hàm quét led 7 đoạn:

Hàm quét led phải được gọi ra liên tục trong thân hàm main, các tác vụ khác không được trì hoãn quá lâu vì như vậy sẽ làm việc quét led gián đoạn gây nhấp nháy led.

Thực hành:

Yêu cầu 1: Hãy soạn thảo và biên dịch chương trình với yêu cầu hiển thị 1 số có 4 chữ số ví dụ 2010.

Chương trình gợi ý:

Bai2_1_A : Thực hành quét led. Sử dụng file mô phỏng BAI2_1.dsn

#define CONTROL PORTB

#define DATA PORTC

char i ;

Delay 5ms

Vào

Đọc dữ liệu cần xuất (dạng BCD)

Đưa dữ liệu led 1 ra PORT DATA

Bật led 1 qua PORT CONTROL

Đưa dữ liệu led 2 ra PORT DATA

Bật led 2 qua PORT CONTROL

Tắt led 1 qua PORT CONTROL

Tắt led 2 qua PORT CONTROL

Bật led n qua PORT CONTROL

Đưa dữ liệu led n ra PORT DATA

Tắt led n qua PORT CONTROL

Delay 5ms

Delay 5ms

Ra

Page 5: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 76

char temp[4];

// MA LED 7 DOAN CATHODE CHUNG

char seven_seg_code[]={0x3f,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

// HAM TACH CAC KY SO TRONG CHU SO CAN HIEN THI

void Num2Digit(int number){

temp[3]=number/1000;

temp[2]=(number%1000)/100;

temp[1]=((number%1000)%100)/10;

temp[0]=((number%1000)%100)%10;

return;

}

// HAM QUET LED 7 DOAN

void Seven_Seg_Scan(){

for (i=0;i<=3;i++){

// TRA CUU KY SO CHUYEN THANH MA LED

DATA=seven_seg_code[temp[i]];

CONTROL=~0x08>>i;

delay_ms(5);

CONTROL=0xFF;

}

}

//CHUONG TRINH CHINH

void main(){

DDRC=0xFF; //CAU HINH PORT

DDRB=0xFF;

//CHUYEN DOI DU LIEU HIEN THI

Num2Digit(1234);

while(1){

//GOI HAM QUET LED

Seven_Seg_Scan();

}

}

Trong chương trình trên, hàm Num2Digit chịu trách nhiệm tách các ký số của 1 số có 4 chữ số. Sau đó, trong hàm quét led, các ký số này sẽ được dùng để tra cứu mã led 7 đoạn tương ứng được khai báo trong mảng seven_seg_code.

Page 6: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 77

Thử thay đổi thời gian trì hoãn trong hàm quét led từ 5ms thành 500ms để hiểu rõ nguyên tắc quét led.

Yêu cầu 2: Hãy viết chương trình kết hợp dùng phím đơn và quét led 7 đoạn, chương trình có khả năng khi ấn phím 1 thì tăng giá trị hiển thị 1 đơn vị, ấn phím 2 thì giảm 1 đơn vị.

Chương trình tham khảo:

Bai2_1_B : Chương trình kết hợp quét led và chống dội phím. Sử dụng file mô phỏng BAI2_1.dsn

#define CONTROL PORTB

#define DATA PORTC

char key, pr, flag, i, j;

unsigned int number;

char temp[4];

// MA LED 7 DOAN CATHODE CHUNG

char seven_seg_code[]={0x3f,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

// HAM TACH CAC KY SO TRONG CHU SO CAN HIEN THI

void Num2Digit(unsigned int in_number){

temp[3]=in_number/1000;

temp[2]=(in_number%1000)/100;

temp[1]=((in_number%1000)%100)/10;

temp[0]=((in_number%1000)%100)%10;

return;

}

// HAM QUET LED 7 DOAN

void Seven_Seg_Scan(){

for (i=0;i<=3;i++){

// TRA CUU KY SO CHUYEN THANH MA LED

DATA=seven_seg_code[temp[i]];

CONTROL=~0x08>>i;

delay_ms(1);

CONTROL=0xFF;

}

}

//HAM DOC PHIM - TRA VE VI TRI PHIM DUOC AN - MUC TAC DONG PHIM LA THAP

char Button_Read(){

if(Button(&PINA,0,1,0)) return 1;

if(Button(&PINA,1,1,0)) return 2;

return 0;

}

Page 7: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 78

//HAM DOC PHIM VA CHONG DOI

char Button_Read_Debounce(){

char temp;

temp=Button_Read();

if(temp==0){

if(pr==1){

pr=0;

return;

}

else {

flag=1;

return;

}

}

else{

delay_ms(5);

temp=Button_Read();

if(temp==0) return;

else{

pr=1;

return temp;

}

}

}

//CHUONG TRINH CHINH

void main(){

DDRA=0x00;

DDRB=0xFF;

DDRC=0xFF;

while(1){

Num2Digit(number);

Seven_Seg_Scan();

key= Button_Read_Debounce();

if((pr==1)&&(flag==1)){

flag=0;

switch(key){

case 1:number++;

// GIOI HAN GIA TRI TRONG 4 CHU SO

if(number==10000) number=0;

break;

Page 8: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 79

case 2:number--;

// GIOI HAN GIA TRI TRONG 4 CHU SO

if(number>=9999) number=9999;

break;

}

}

}

}

Trong chương trình tham khảo trên, các hàm delay của chương trình chống dội cũng như quét led đều giảm tối thiểu để đảm bảo tần số quét đủ để đánh lừa thị giác của chúng ta. Tuy nhiên, việc giảm delay có thể làm cho hàm chống dội không còn tốt nữa. Mặt khác, đây chỉ mới là chương trình đơn giản với 2 chức năng chỉ khai thác được 1 phần nhỏ tài nguyên vi điều khiển. Vì vậy cần cải tiến chương trình để vi điều khiển xử lý nhịp nhàng giữa chống dội phím và quét led. Ta sẽ dùng phương pháp sử dụng ngắt được trình bày ở các chương sau để khắc phục nhược điểm của hàm delay.

c. Phương pháp quét led 7 đoạn có sử dụng IC chốt.

Đây là 1 hướng phát triển của phương pháp quét led 7 đoạn, phương pháp này sử dụng thêm các IC số để mở rộng khả năng điều khiển các led 7 đoạn với số chân vi điều khiển sử dụng là tối thiểu.

Mô tả:

+IC 74595 là IC ghi dịch 8 bit có chốt, dữ liệu được cấp vào chân số 14, mỗi khi có xung clock tác động vào chân 11 thì dữ liệu sẽ dịch từ QA đến QH, tuy nhiên dữ liệu này chưa xuất hiện ở ngã ra mà phải chờ 1 xung tác động vào chân 12 để chốt dữ liệu khi đó dữ liệu từ QA đến QH sẽ xuất hiện ở ngõ ra. Chân 9 là ngã ra xuất dữ liệu nối tiếp cho IC phía sau, dữ liệu ở chân 9 là dữ liệu ngã vào đã dịch đi 8 bit.

+Để thực hiện phương pháp quét này, ta cần ít nhất 2 IC 74595 và 6 chân vi điều khiển. Mỗi IC được điều khiển bởi 3 chân vi điều khiển để nhận dữ liệu nối tiếp và chuyển thành dữ liệu song song xuất ra led và các transistor đóng mở.

+IC 74595 thứ nhất sẽ tạo xuất mã hiển thị do vi điều khiển cung cấp

+IC 74595 thứ hai sẽ xuất mã điều khiển cũng do vi điều khiển cung cấp, do IC này có 8 bit dữ liệu nên điều khiển được 8 led 7 đoạn, nhưng do khả năng mở rộng IC số là vô hạn nên số lượng led điều khiển được sẽ rất lớn, tùy vào khả năng cấp dòng của tầng đệm và tần số quét của vi điều khiển.

Sau đây là sơ đồ thí nghiệm của module led 7 đoạn gồm 8 led 7 đoạn anode chung và mắc chung đường dữ liệu.

Page 9: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 80

Hình 6. Sơ đồ module led 7 đoạn mở rộng

Lưu ý, vì tầng đệm trong sơ đồ dùng IC ULN2803 là IC lái dòng (mỗi đường cấu tạo như 1 transistor NPN – ngã vào 1 thì ngã ra 0, ngã vào 0 thì ngã ra xem như để hở) nên mã led phải dùng loại cathode chung.

Để xây dựng hàm xuất dữ liệu 8 bit bằng IC 74595 các bạn có thể tham khảo các bước sau:

+Bước 1: Lấy bit thứ 8 của dữ liệu xuất ra chân của vi điều khiển nối vào chân SDI (chân 14) của IC 74595.

+Bước 2: Tạo xung đồng hồ tại chân của vi điều khiển nối vào chân SRCLK(chân 11) của IC 74595.

Thực hiện lại bước 1 và 2 nhưng lấy các bit dữ liệu có thứ tự (trọng số) thấp dần. Sau 8 lần thực hiện thì toàn bộ 8 bit dữ liệu đã dịch vào IC 74595.

U1

74HC595

SDO9

CLR10

G13

SDI14

SRCLK11

RCLK12

QA15

QB1

QC2

QD3

QE4

QF5

QG6

QH7

U2

74HC595

SDO9

CLR10

G13

SDI14

SRCLK11

RCLK12

QA15

QB1

QC2

QD3

QE4

QF5

QG6

QH7

U3

7Seg

e1 d2

E1

3

c4

pt5

b6 a7

E2

8

f9

g10

R7 8.2K

U4

7Seg

e1 d2

E1

3

c4

pt5

b6 a7

E2

8

f9

g10

R8 8.2K

U5

7Seg

e1 d2

E1

3

c4

pt5

b6 a7

E2

8

f9

g10

U6

7Seg

e1 d2

E1

3

c4

pt5

b6 a7

E2

8

f9

g10

VCC

U7

7Seg

e1 d2

E1

3

c4

pt5

b6 a7

E2

8

f9

g10

U8

7Seg

e1 d2

E1

3

c4

pt5

b6 a7

E2

8

f9

g10

VCC

LE

D1

U9

ULN2803

COM10

IN11

IN22

IN33

IN44

IN55

IN66

IN77

IN88

OUT118

OUT217

OUT316

OUT415

OUT514

OUT613

OUT712

OUT811

VCC

LE

D4

Q9PNP BCE

LED7

LE

D5

Q10PNP BCE

LE

D6

Q11PNP BCE

LED8

Q12PNP BCE

VCC

VCC VCC VCC VCC

R1 8.2K

R9

10K

A

R2 8.2K

BC

R3 8.2K

DE

R4 8.2K

FGDP

R5 8.2KR6 8.2K

SRCLK_2

SDI_2

RCLK_2

SRCLK_1

R10

10K

SDI_1

RCLK_1

Q5PNP BCE

U10

7Seg

e1 d2

E1

3

c4

pt5

b6 a7

E2

8

f9

g10

U11

7Seg

e1 d2

E1

3

c4

pt5

b6 a7

E2

8

f9

g10

LE

D7

LE

D8

A

A

BC

BC

DEF

DEF

GDP

GDP

A

Q6PNP BCE

BCDEFGDP

Q7PNP BCE

Q8PNP BCE

SRCLK_1SDI_1RCLK_1

VCC

ABCDEFGDP

J1

PORT

12345678910

ABCDEFGDP

ABCDEFGDP

ABCDEFGDP

LE

D2

LED1

SRCLK_2SDI_2RCLK_2

LED2

LE

D3

LED3LED4

VCC

LED5

ABCDEFGDP

VCC

LED6

VCC

Page 10: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 81

+Bước 3: Tạo xung đồng hồ tại chân của vi điều khiển nối vào chân RCLK (chân 12) của IC 74595.

Sau đây là lưu đồ giải thuật xuất dữ liệu ra IC 74595:

Ví dụ: Viết chương trình hiển thị dãy số gồm 8 chữ số bất kỳ ra 8 led 7 đoạn với cách bố trí như sơ đồ hình 6.

Ta dùng dãy IC 74595 thứ nhất để xuất dữ liệu là mã led. Dùng dãy IC 74595 thứ 2 để xuất dữ liệu chọn led.

Do dãy IC 74595 được mắc nối tiếp nên khi xuất dữ liệu phải sắp xếp sao cho dữ liệu của IC cuối dãy được xuất trước

Bai2_2_A : Chương trình quét led bằng phương pháp mở rộng PORT xuất. Sử dụng file mô phỏng BAI2_2.dsn

#define clk1 PORTC0_bit

#define lat1 PORTC2_bit

#define sdo1 PORTC1_bit

#define clk2 PORTC3_bit

#define lat2 PORTC5_bit

#define sdo2 PORTC4_bit

#define iport PORTC

Lấy 1 bit của dữ liệu đưa vào chân SDI

Tạo xung clock cấp vào chân SRCLK

Vào

Đủ 8 lần hay chưa?

Tạo xung clock cấp vào chân RCLK

Thoát

Chưa

Đủ

Page 11: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 82

char seven_seg_code[]={0x3f,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

//char temp[8]={1,2,3,4,5,6,7,8}; // MẢNG CHỨA GIÁ TRỊ CẦN HIỂN THỊ

char temp[9]="12345678"; // MẢNG CHỨA GIÁ TRỊ CẦN HIỂN THỊ

char i;

//HÀM GHI DỮ LIỆU VÀO IC 74595

void Ic74595_Write(char dat, char ic, char bits){

signed char func_count; //BIẾN ĐẾM

if(ic==1){ //CHỌN GHI VÀO DÃY IC THỨ NHẤT

for(func_count=bits-1;func_count>=0;func_count--){

sdo1=(dat>>func_count)&0x01; // LẤY TỪNG BIT

clk1=1; //TẠO XUNG DỊCH

clk1=0;

}

lat1=1; //TẠO XUNG CHỐT

lat1=0;

}

if(ic==2){ // CHỌN GHI VÀO IC THỨ HAI ĐỘ RỘNG 8 BIT

for(func_count=bits-1;func_count>=0;func_count--){

sdo2=(dat>>func_count)&0x01; // LẤY TỪNG BIT

clk2=1; //TẠO XUNG DỊCH DỮ LIỆU

clk2=0;

}

lat2=1; //TẠO XUNG CHỐT DỮ LIỆU

lat2=0;

}

}

// HÀM QUÉT LED 7 ĐOẠN

void Seven_Seg_Scan(char leds){

if(i++>=leds) i= 0; // MỖI LẦN GỌI HÀM CHỈ QUÉT 1 LED CÓ THỨ TỰ TĂNG DẦN

// XÓA ĐỊA CHỈ LED

Ic74595_Write(0xFF,2,8);

// TRA CỨU MẢNG CHỨA MÃ LED VÀ GHI VÀO IC(DÃY IC) 74595 THỨ NHẤT

Ic74595_Write(seven_seg_code[temp[i]-48],1,8);

// GHI DỮ LIỆU ĐIỀU KHIỂN(ĐỊA CHỈ LED) VÀO IC(DÃY IC) 74595 THỨ 2

Ic74595_Write(~(0x01<<i),2,8);

delay_ms(1);

}

void main(){

DDRC=0xff;

Page 12: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 83

while(1){

Seven_Seg_Scan(8);

}

}

Mảng chứa giá trị cần hiển thị là 1 chuỗi ký tự, vì vậy khi dùng từng ký

số để tra cứu vào mảng chứa mã led, ta phải chuyển từ mã ASCII ra số nguyên(trừ đi 48 đơn vị).

Hàm quét led có đặc điểm, mỗi lần quét led chỉ quét 1 led, lần tiếp theo sẽ quét led kế tiếp, mục đích là để thời gian thực thi hàm không quá lâu. Tuy nhiên, số lần gọi hàm phải dày hơn chương trình quét 1 lần tất cả led.

Trên đây chỉ là một hướng làm tiết kiệm chân IO vào ứng dụng quét led. Có rất nhiều phương pháp khác nhau để kết hợp vi điều khiển và IC số, các bạn có thể tự tìm hiểu thêm với nguyên lý quét led như trên. II. Giao tiếp với led ma trận .

1. Led ma trận Led ma trận là linh kiện hiển thị, cũng như led 7 đoạn, led ma trận hiển

thị ký tự bằng tổ hợp các phần tử, mỗi phần tử là 1 led gọi là 1 điểm (dot). Ma trận led được sử dụng trong bài này là loại 8x8. Nó bao gồm 64 led,

mỗi 8 led nối chung cathode với nhau thành 1 cột, mỗi 8 led nối chung anode với nhau thành 1 hàng. Tổng cộng có 8 hàng và 8 cột.

Hình 7. Cấu tạo led ma trận Do các led không độc lập nhau nên phương pháp duy nhất để hiển thị ký

tự là phương pháp quét. Phương pháp quét led ma trận chủ yếu có 2 loại quét cột và quét hàng.

Page 13: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 84

+Quét cột là cấp dữ liệu cho từng cột kết hợp với việc chọn cột để hiển thị dữ liệu tương ứng.

+Quét hàng là cấp dữ liệu cho từng hàng kết hợp với việc chọn hàng để hiển thị dữ liệu tương ứng.

Như đã nghiên cứu ở phần led 7 đoạn, để mở rộng khả năng điều khiển led, ta sẽ dùng IC 74595 để cung cấp dữ liệu hiển thị và dữ liệu điều khiển.

Phương pháp quét được trình bày trong bài viết này là phương pháp quét hàng, phương pháp quét cột các bạn có thể tự phát triển.

Sau đây là sơ đồ module led ma trận:

Hình 8. Sơ đồ module led ma trận

Page 14: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 85

TẠO DỮ LIỆU CHO LED MA TRẬN Dữ liệu của led ma trận không cố định, nó phụ thuộc vào hình ảnh muốn

hiển thị và phương pháp quét. Ta có thể dùng 1 chương trình tạo mã led ma trận thông dụng để không phải mất công tính toán nhiều. Trong khuôn khổ tài liệu này, tôi xin giới thiệu phần mềm LCD font maker V3.9.

Đối với phần mềm này, chúng ta có thể tạo mã cho mọi loại led ma trận có kích thước không giới hạn.

Hình 9. Giao diện chương trình.

Các bước thực hiện tạo mã led ma trận.

Bước 1: Bấm vào nút để chọn font chữ nếu muốn hiển thị tin nhắn, kích cỡ chữ phải bằng 8 vì chiều cao ma trận led là 8. Font chữ nên chọn là Time New Roman vì nó đơn giản, phù hợp với kích cỡ ma trận nhỏ.

Bước 2: Bấm vào thẻ Character input, mục Output size bỏ check tại Auto set, chọn Width là 32 (mỗi led ma trận có chiều rộng 8 bit, 4 led ma trận ghép lại là 32 bit) và chọn Height là 8 (mỗi led ma trận có chiều cao 8 bit). Sau khi chọn xong ta có 1 vùng trống kích thước 32x8, ta có thể tùy ý vẽ 1 hình dạng bất kỳ bằng việc bấm chuột trái vào vùng này.

Bước 3: Nếu muốn hiển thị tin nhắn thì ta gõ tin nhắn vào ô Char input. Sau đó dùng các tọa độ tại mục Offset để di chuyển tin nhắn vào vị trí cần thiết. Ngoài ra có thể sử dụng các công cụ trong menu bên trái để chỉnh sửa hiển thị.

Page 15: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 86

Bước 4: Sau khi chuẩn bị xong hình ảnh muốn hiển thị, ta chọn phương

pháp quét cho phù hợp. Ta bấm vào nút Trong bài này, ta dùng phương pháp quét cột và dữ liệu xuất ra theo ưu

tiên bit có trọng số lớn thì xuất trước nên ta chọn mục “Monochrome LCD font, Horizontal scan, Little endian order” trong thẻ Font Format như hình 10.

Hình 10. Cấu hình xuất code

Sau khi chọn xong bấm OK.

Bước 5: Xuất dữ liệu, ta bấm vào nút , ở thẻ One font data output ta sẽ nhận được 1 dãy mã hex. Gồm 32 phần tử được sắp xếp như sau:

Dữ liệu hàng 1 của led 1, dữ liệu hàng 1 của led 2… dữ liệu hàng 1 của led 4, dữ liệu hàng 2 của led 1,… dữ liệu hàng 2 của led 4,… dữ liệu hàng 4 của led 4.

Như vậy dữ liệu đã được sắp xếp sẵn theo hàng ngang, ta sẽ lấy 32 phần tử này bỏ vào 1 mảng để tiện cho việc truy xuất, khi xuất dữ liệu chỉ cần xuất lần lượt ra các IC 74595.

Các bước thực hiện quét led ma trận theo module hình 9.

Bước 1: Dùng hàm xuất dữ liệu cho dãy IC74595 thứ nhất (Ic74595_Write) xuất theo thứ tự giảm dần dữ liệu hàng của các led từ 4 đến 1(phần tử 3 đến phần tử 0 của mảng). Bước 2: Dùng hàm xuất dữ liệu cho dãy IC 74595 thứ 2 xuất dữ liệu chọn hàng 1 cho tất cả các led Bước 3: Dùng hàm xuất dữ liệu cho dãy IC 74595 thứ 2 xuất dữ liệu trống để tắt tất cả các led.

Lặp lại các bước từ 1 đến 3 với các dữ liệu hàng và dữ liệu chọn hàng tăng dần (các phần tử của mảng dữ liệu hàng xuất theo thứ tự: 3-0, 7-4, 11-8,15-12, 19-16, 23-20, 27-24, 31-28)

Page 16: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 87

Sau đây là lưu đồ giải thuật.

Sau đây là ví dụ về việc xuất dữ liệu ra led ma trận: Yêu cầu: xuất dữ liệu bất kỳ ra 4 led ma trận có kích thước 32x8.

Bai2_3_A : Xuất dữ liệu ra led ma trận. Sử dụng file mô phỏng BAI2_3.dsn

#define sclk1 PORTC0_bit

#define dat1 PORTC1_bit

#define lclk1 PORTC2_bit

#define sclk2 PORTC3_bit

#define dat2 PORTC4_bit

#define lclk2 PORTC5_bit

char i,j,s;

char temp[2];

unsigned char BitmapData[]= {

0x07,0xDC,0x71,0xDC,0xB2,0x89,0x88,0x88,0x4A,0x52,0x04,0x89,0x0A,0x52,0x04,0x89,

0x12,0x21,0x04,0x89,0xA2,0x20,0x04,0x89,0x42,0x20,0x88,0x88,0x07,0x70,0x70,0x70,

};

//HAM GHI DU LIEU VAO IC 74595

void Ic74595_Write(char dat,char ic,char bits){//bits LÀ BIẾN CHỈ ĐỘ RỘNG DỮ LIỆU

signed char fc; //BIẾN ĐẾM

if(ic==1){ //CHỌN XUẤT RA IC 74595 THỨ NHẤT

Vào

Xuất dữ liệu led 4 – 1 hàng i ra IC 74595

Xuất dữ liệu bật bật hàng i

Xuất dữ liệu tắt tất cả các led

Đủ 8 hàng chưa?

Chưa

Tăng i

Đủ

Ra

Page 17: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 88

for(fc=bits-1;fc>=0;fc--){

dat1=(dat>>fc)&0x01; // TẠO DỮ LIỆU NỐI TIẾP

sclk1=1; //TẠO XUNG DỊCH

sclk1=0;

}

lclk1=1; //TẠO XUNG CHỐT

lclk1=0;

}

if(ic==2){ //CHỌN XUẤT RA IC 74595 THỨ HAI

for(fc=bits-1;fc>=0;fc--){

dat2=(dat>>fc)&0x01; // TẠO DỮ LIỆU NỐI TIẾP

sclk2=1; //TẠO XUNG DỊCH

sclk2=0;

}

lclk2=1; //TẠO XUNG CHỐT

lclk2=0;

}

}

void Ledmatrix_Out(char dat){

signed char i,j,k;

for(i=0;i<=7;i++){

for(j=3;j>=0;j--){

Ic74595_Write(BitmapData[(j+4*i)],1,8); //XUẤT DỮ LIỆU HÀNG

}

Ic74595_Write(0x01<<i,2,8); //XUẤT DỮ LIỆU CỘT

delay_ms(1);

Ic74595_Write(0x00,2,8); //XÓA DỮ LIỆU CỘT

}

}

void main(){

DDRC=0xff;

while(1){

Ledmatrix_Out(BitmapData);

}

}

Để tạo các hiệu ứng, tùy vào quy luật chuyển động của hiệu ứng mà ta phát triển các hàm hỗ trợ, để tạo thời gian trì hoãn cho mỗi thao tác, ta có thể dùng vòng lặp để quét liên tục.

Sau đây là chương trình với 1 số hiệu ứng đơn giản.

Page 18: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 89

Yêu cầu : Viết chương trình dịch hiển thị xoay vòng từ trái sang phải và từ trên xuống dưới. Chương trình thao khảo :

Bai2_3_B : Cuộn dữ liệu hiển thị

#define sclk1 PORTC0_bit

#define dat1 PORTC1_bit

#define lclk1 PORTC2_bit

#define sclk2 PORTC3_bit

#define dat2 PORTC4_bit

#define lclk2 PORTC5_bit

char i,j,s;

char Dmem[32];

unsigned char BitmapData[]= {

0x00,0x00,0x00,0x00,

0x36,0x36,0x36,0x36,

0x49,0x49,0x49,0x49,

0x41,0x41,0x41,0x41,

0x41,0x41,0x41,0x41,

0x22,0x22,0x22,0x22,

0x14,0x14,0x14,0x14,

0x08,0x08,0x08,0x08,

};

//HAM GHI DU LIEU VAO IC 74595

void Ic74595_Write(char dat, char ic, char bits){

signed char fc; //BIEN DEM

if(ic==1){ //CHON GHI VAO IC 74595 THU NHAT

for(fc=bits-1;fc>=0;fc--){

dat1=(dat>>fc)&0x01; // TAO DU LIEU NOI TIEP

sclk1=1; //TAO XUNG DICH

sclk1=0;

}

lclk1=1; //TAO XUNG CHOT

lclk1=0;

}

if(ic==2){ //CHON GHI VAO IC 74595 THU HAI

for(fc=bits-1;fc>=0;fc--){

dat2=(dat>>fc)&0x01; // TAO DU LIEU NOI TIEP

sclk2=1; //TAO XUNG DICH

Page 19: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 90

sclk2=0;

}

lclk2=1; //TAO XUNG CHOT

lclk2=0;

}

}

void Dmemloop_vertical(){

char temp,i,j,k;

for(i=0;i<=3;i++){

temp=Dmem[28+i];

for (j=0;j<=6;j++){

Dmem[28+i-4*j]=Dmem[24+i-4*j];

}

Dmem[0+i]=temp;

}

}

void Dmemloop_horizal(){

char i,j;

char temp[4];

for(i=0;i<=7;i++){

for(j=0;j<=3;j++){ // SAO LUU BIT MSB

temp[j]=Dmem[j+4*i]>>7;

}

for(j=0;j<=3;j++){ // DICH TAT CA DU LIEU HANG DI 1 BIT

Dmem[j+4*i]=Dmem[j+4*i]<<1;

}

Dmem[0+4*i]=Dmem[0+4*i]|temp[3];

Dmem[1+4*i]=Dmem[1+4*i]|temp[0];

Dmem[2+4*i]=Dmem[2+4*i]|temp[1];

Dmem[3+4*i]=Dmem[3+4*i]|temp[2];

}

}

void Ledmatrix_Out(char dat[],long time){

signed char i,j;

long k;

for(k=0;k<=time/8;k++){

for(i=0;i<=7;i++){

for(j=3;j>=0;j--){

Ic74595_Write(dat[(j+4*i)],1,8); //GHI DU LIEU HANG

}

Page 20: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 91

Ic74595_Write(0x01<<i,2,8);

delay_ms(1);

Ic74595_Write(0x00,2,8); //XOA DU LIEU DIEU KHIEN HANG

}

}

}

void main(){

DDRC=0xff;

for(i=0;i<=31;i++){

Dmem[i]=BitmapData[i];

}

while(1){

for(i=0;i<=7;i++){

Ledmatrix_Out(Dmem,100);

Dmemloop_vertical();

}

for(i=0;i<=15;i++){

Ledmatrix_Out(Dmem,100);

Dmemloop_horizal();

}

}

}

Việc tạo hiệu ứng trong ví dụ trên thực chất là biến đổi giá trị hiển thị

thông qua một mảng chứa giá trị tạm thời (Dmem). Các thao tác byte và bit được hình thành dựa trên quy luật thay đổi cần thiết của hiệu ứng.

Ngoài ra, ta có thể tạo hiệu ứng hiển thị bằng cách can thiệp vào quá trình ghi dữ liệu xuất qua IC 74595.

Dữ liệu dành cho việc hiển thị cho led ma trận là rất lớn nên chiếm dụng nhiều Flash ROM để lưu trữ và nhiều RAM khi xử lý hiển thị.

Trong 2 phần quét led 7 đoạn và quét led ma trận, tôi đã giới thiệu hàm xuất dữ liệu bằng IC 74595. Hàm này thực chất là 1 dạng chuyển dữ liệu nối tiếp thành song song. MikroC cung cấp cho ta 1 hàm tương tự nằm trong thư viện Software SPI Library, thư viện này gồm có 2 hàm :

Soft_SPI_Init : Hàm khởi tạo giao tiếp Soft_SPI_Read : Hàm đọc dữ liệu, hàm này phải dùng với IC có chức

năng ngược với IC 74595 là nhận dữ liệu song song, xuất dữ liệu nối tiếp.

Soft_SPI_Write : Hàm ghi dữ liệu

Page 21: Lap Trinh Avr Voi c Www.eeelabs.org Chuong4 Bai2

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Trần Thừa – 2010 92

Ngoài ra, vi điều khiển AVR còn hỗ trợ truyền thông nối tiếp bằng phần cứng. Một số chân nhập xuất có nhiệm vụ riêng là hỗ truyền nhận dữ liệu nối tiếp. MikroC cung cấp cho ta các hàm để điều khiển quá trình nhập xuất được hỗ trợ bởi phần cứng của AVR, các hàm này nằm trong thư viện SPI library.

Các bạn có thể tham khảo thêm cách sử dụng và cấu hình các hàm này trong phần Help của MikroC.

Cũng như công việc quét led 7 đoạn, việc quét led ma trận vẫn gặp phải vấn đề chớp nháy khi xử lý chung với phím hoặc 1 ngoại vi khác cần thời gian xử lý dài và không cố định vì việc quét led đòi hỏi hàm quét led phải được gọi ra liên tục và đều đặn. Ở bài sau, tôi sẽ trình bày cách khắc phục hiện tượng trên.

Lưu ý: Các file mô phỏng chỉ nhằm mục đích minh họa các ví dụ, không có giá trị sử dụng thực tế. Một vài gợi ý để cải tiến hoạt động của mạch cho phù hợp với thực tế.

+Trong thực tế, led ma trận thường nhận dữ liệu hiển thị(dữ liệu hàng) vào các chân anode chung, khi đó ta phải cấp dòng cho từng hàng chứ không phải nhận dòng vì vậy ULN2803 sẽ thay bằng loại IC thúc dòng hoặc đơn giản hơn là dùng 8 transistor PNP đệm dòng cho IC 74595. Lúc này, dữ liệu điều khiển và dữ liệu hiển thị cũng phải lấy đảo từng bit để hiển thị cho phù hợp.

+Việc xuất dữ liệu điều khiển (xuất địa chỉ) bằng IC 74595 hầu như ít sử dụng . Thay vào đó người ta thường dùng IC giải mã “n đường sang 2n đường” mà trong trường hợp này có thể dùng IC 74138. Khi đó dữ liệu điều khiển là 3 bit tạo địa chỉ cho IC 74138 (tuần tự từ 0-7).

+Tuy cách xuất dữ liệu như trình bày ở trên có thể mở rộng ra khá nhiều led ma trận mà không tốn thêm chân I/O, nhưng không nên điều khiển cùng lúc quá nhiều led ma trận. Lý do thứ nhất là cần đảm bảo tần số quét cũng như lưu ý đến độ trễ truyền của các IC để các led không bị nhấp nháy, thứ 2 là tốn nhiều bộ nhớ. Nên thiết kế các module điều khiển led riêng biệt.