Tải bản đầy đủ (.doc) (39 trang)

Bài thực hành lập trình AVR

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (811.74 KB, 39 trang )

BÀI GIẢNG
VI ĐIỀU KHIỂN AVR
-1-
LỜI NÓI ĐẦU
Với mong muốn nhanh chóng giúp các bạn học viên có thể chủ động và nhanh chóng làm
việc được với vi điều khiển AVR, chúng tôi tổng hợp và biện soạn tài liệu “giáo trình vi
điều khiên AVR”. Giáo trình cung cấp cái nhìn từ chi tiết đến tổng thể những ứng dụng,
và tài nguyên của vi điều khiển AVR.
Đặc điểm của tài liệu này là học viên có thể bắt tay vào thực hành ngay lập tức, đẩy
nhanh quá trình tiếp thu kiến thức và khơi gợi sự đam mê của học viên qua các bài thực
hành.
Chú ý, đây là tài liệu tổng hợp những kiến thức căn bản nhất về vi điều khiển AVR, để có
hiệu quả trong quá trình sử dụng tài liệu cho các mục đích học tập, nghiên cứu, mong độc
giả nên đọc hết các phần lý thuyết mở đầu, sau đó hãy làm các bài thực hành theo đúng
hướng dẫn.
Tập 1 bao gồm Bài 1: Điều khiển I/O, hiển thị LED đơn, Bài 2. Hiển thị LED 7 Thanh.
IC 7447, Bài 3.Hiển thị LCD, Bài 4.Giao tiếp máy tính, chuẩn RS232, Bài 5.Giao tiếp
I2C với DS1307 (nâng cao), Bài 6. ADC và LM35. Đo lường kết nối máy tính. (nâng
cao).
Tập 2 gồm các bài: Bài 7 Timer/ Counter. Bài 8 PWM điều khiển động cơ (nâng cao).
Để tăng hiệu quả, tài liệu này nên sử dụng cùng với bộ giáo trình: Cấu trúc vi điều khiển
AVR, Ngôn ngữ lập trình C cho vi điều khiển, Hướng dẫn sử dụng Codevision, Hướng
dẫn sử dụng proteous, Các linh kiện điện tử cơ bản.
-2-
MỤC LỤC
LỜI NÓI ĐẦU 2
MỤC LỤC 3
Danh sách hình vẽ 3
Bài thí nghiệm số 1. Led đơn, Led 7 thanh, hiển thị tăng giảm theo nút bấm 4
1. Điều khiển Led đơn 4
2. Điều khiển Led 7 thanh hiển thị số từ 0 đến 9999 5


3. Hiển thị tăng giảm giá trị LED 7 thanh sử dụng 2 nút bấm tăng, giảm 12
Lý thuyết về LED ma trận: 15
Bài thí nghiệm số 3: Điều khiển LCD và bàn phím 3x4 21
1. Hiển thị LCD 21
2. Quét ma trận phím 3x4 24
Bài thí nghiệm số 4: Đo nhiệt độ hiển thị LCD theo thời gian thực 29
1. Đo nhiệt độ sử dụng LM35, hiện thị LCD 29
2. IC thời gian thực DS1307 31
Nguyên lý hoạt động của DS1307 31
Bài thí nghiệm số 5: Điều khiển động cơ bước theo 2 nút tăng, giảm 35
Lý thuyết: 35
Danh sách hình vẽ
Hình 1: Sơ đồ nguyên lý của Led đơn 4
Hình 2: Led đơn sáng byte 0xAA 5
Hình 3: Hình ảnh Led 7 thanh 6
Hình 4: Nguyên lý Led 7 thanh 6
Hình 5: Led 7 thanh dương chung 7
Hình 6: Sơ đồ nguyên lý quét LED 7 thanh 8
Hình 7: Bảng sự thật của 74hc154 9
Hình 8: Nguyên lý nút bấm tăng giảm 13
Hình 9: Cấu trúc ma trận LED đơn giản 5x7 15
Hình 10: LED ma trận hiển thị sô 4 16
Hình 11: Hình ảnh thực của LCD 16x2 21
Hình 12: Các chân chức năng của LCD 22
Hình 13: Bảng lệnh của LCD 22
Hình 14: Sơ đồ nguyên lý mạch quét phím 24
Hình 15: Sơ đồ nguyên lý của LM 35 29
Hình 16: Sơ đồ nguyên lý khối thời gian thực 31
Hình 17: Phân loại động cơ bước theo góc quay 35
Hình 18: Cấu trúc motor bước 36

Hình 19: Các dạng chuỗi xung điều khiển motor bước 36
Hình 20: Sơ đồ nguyên lý động cơ bước 37
-3-
Bài thí nghiệm số 1. Led đơn, Led 7 thanh, hiển thị tăng giảm theo nút bấm
Yêu cầu:
- Điều khiển được Led đơn.
- Điều khiển Led 7 thanh hiển thị số từ 0 đến 9999.
- Hiển thị tăng giảm giá trị LED 7 thanh sử dụng 2 nút bấm tăng – giảm
Yêu cầu cụ thể:
1. Điều khiển Led đơn
Mục đích: Giúp sinh viên làm quen với việc điều khiển tín hiệu ra của vi điều
khiển và hiển thị trực quan lên LED đơn.
Bo thí nghiệm được thiết kế với 8 LED đơn sử dụng để kiểm tra tín hiệu đầu ra
của vi điều khiển. Bài thí nghiệm điều khiển LED đơn được đưa ra với mục đích giúp
sinh viên làm quen với khái niệm vào ra của vi điều khiển.
Sơ đồ nguyên lý của khối được thiết kế như sau:
L E D _ 5
D 3
L E D
L E D _ 4
D 7
L E D
D 6
L E D
D 2
L E D
L E D _ 3
L E D _ 8
L E D _ 2
L E D _ 7

D 8
L E D
D 4
L E D
L E D _ 1
D 5
L E D
L E D _ 6
D 1
L E D
Hình 1: Sơ đồ nguyên lý của Led đơn
Nhiệm vụ của sinh viên là hiển thị 1 byte bất kì lên trên Led đơn với quy ước:
• Bit 1: Led sang
• Bit 0: Led tắt
-4-
Thí dụ: Muốn hiển thị 1 byte 0xAA, 8 Led đơn sẽ hiển thị như sau:
Hình 2: Led đơn sáng byte 0xAA
Bài thực hành số 1: Hiển thị lên LED đơn các byte tự động chạy từ 0x00 đến 0xFF với
bước chạy là 0.5s. Khi chạy đến 0xFF sẽ tự động quay trở lại 0x00.
#include <mega128.h>
#include <delay.h>
// Declare your global variables here
void main(void)
{
DDRC = 0xFF;
while (1)
{
for(i = 0; i < 256; i ++)
{
PORTC = i;

delay_ms(500);
}
};
}
2. Điều khiển Led 7 thanh hiển thị số từ 0 đến 9999.
Mục đích: Giúp sinh viên làm quen với việc hiển thị số lên LED 7 thanh.
Lý thuyết về Led 7 thanh:
Led 7 thanh là linh kiện hiển thị các số từ 0 đến 9 và một số ký tự. Ưu điểm của led 7
thanh là phần cứng đơn giản, khoảng các nhìn rõ lớn, có nhiều kích thước. Nên LED 7
thanh hay được dùng để hiển thị các nội dung trên các loại máy trong nhiều lĩnh vực từ
-5-
dân dụng (đồng hồ, lịch vạn niên), các thiết bí đo lường, máy công nghiệp, thương mại
(bảng chứng khoán, bảng tỷ giá…).
LED 7 thanh có 2 loại: Anot chung và Catot chung.
Hình 3: Hình ảnh Led 7 thanh
Hình 4: Nguyên lý Led 7 thanh
Bản chất của LED 7 thanh thực chất là trong mỗi
LED 7 thanh có 8 con LED đơn chung một đầu hoặc
Anot hoặc Catot. Nguyên lý hoạt động của 2 loại này
là tương tự nhau.
-6-
Xét hoạt động của LED 7 thanh Anot chung (dương chung):
Hình 5: Led 7 thanh dương chung
Số/ chữ hiển thị Thanh sáng Thanh tắt Giá trị PORT
0 A,B,C,D,E,F Các thanh còn lại 1100 000
1 B, C Các thanh còn lại 1111 1001
2 A,B,D,E,G Các thanh còn lại 1010 0100

9 A,B,C,D,F,G Các thanh còn lại 1001 0000
A A,B,C,E,F,G Các thanh còn lại 1000 1000

….
-7-
Như vậy, việc hiển thị LED 7 thanh hoàn toàn tương tự việc hiển thị LED đơn, khác biệt
là khi hiển thị số cần lựa chọn các thanh LED sáng tương ứng.
Lý thuyết về quét LED 7 thanh:
Sơ đồ nguyên lý quét LED 7 thanh như sau:
Hình 6: Sơ đồ nguyên lý quét LED 7 thanh
Theo sơ đồ trên, mạch gồm 4 LED 7 thanh được nối chung đường dữ liệu. Như vậy, nếu
các đầu Anode chung được nối với nguồn, 4 LED sẽ hiển thị cùng giá trị. Vì vậy, để có
thể hiển thị được các số với các chữ số khác nhau đòi hỏi phải có thuật toán quét LED.
Thuật toán quét LED được thực hiện như sau:
Giả sử cần hiển thị số có giá trị 1234, tương ứng với LED 1 hiển thị số 1, LED 2 hiển thị
số 2, LED 3 hiển thị số 3, LED 4 hiển thị số 4. Để thưc hiện việc này, ta thực hiện thuật
toán quét LED như sau:
Bước 1: Cho LED 1 sáng số 1 bằng cách bật điều khiển cấp nguồn cho LED 1 và tắt điều
khiển cấp nguồn cho 3 LED còn lại, đồng thời cấp dữ liệu hiển thị của số 1 ra port dữ liệu
chung. Như vậy, thời điểm này, LED 1 sẽ sáng số 1 còn 3 LED còn lại sẽ tắt. Duy trì
trạng thái này trong một thời gian
Bước 2: Tắt điều khiển cấp nguồn của LED 1, cấp dữ liệu sáng số 2 vào port dữ liệu đồng
thời bật điều khiển cấp nguồn cho LED 2. Như vậy, LED 2 sẽ sáng số 2 còn 3 LED còn
lại sẽ tắt. Duy trì trạng thái này trong một thời gian
-8-
L E D _ 5
P G 2
Q 1 3
A 1 0 1 5
R 3 1 1 0 K
L E D _ 1
V C C
L E D _ 2

U 7
7 - S E G x 4
6
8
9
1 2
3
5
1 0
1
2
4
7
1 1
A 1
A 2
A 3
A 4
D B
G
F
E
D
C
B
A
L E D _ 4
V C C
R 3 0 1 0 K
V C C

Q 1 2 A 1 0 1 5
U 2 5
7 4 H C 1 5 4
1
2
3
4
5
6
7
8
9
1 0
1 1
1 3
1 4
1 5
1 6
1 7
2 4
1 2
2 3
2 2
2 1
2 0
1 8
1 9
Y 0
Y 1
Y 2

Y 3
Y 4
Y 5
Y 6
Y 7
Y 8
Y 9
Y 1 0
Y 1 1
Y 1 2
Y 1 3
Y 1 4
Y 1 5
V C C
G N D
A
B
C
D
G 1
G 2
Q 1 0
A 1 0 1 5
L E D _ 3
L E D _ 6
L E D _ 7
V C C
L E D _ 8
R 3 2 1 0 K
V C C

P G 3
Q 1 1 A 1 0 1 5
R 3 3 1 0 K
P G 0
P G 1
Bước 3: Tắt điều khiển cấp nguồn của LED 2, cấp dữ liệu sáng số 3 vào port dữ liệu đồng
thời bật điều khiển cấp nguồn cho LED 3. Như vậy, LED 3 sẽ sáng số 3 còn 3 LED còn
lại sẽ tắt. Duy trì trạng thái này trong một thời gian
Bước 4: Tắt điều khiển cấp nguồn của LED 3, cấp dữ liệu sáng số 4 vào port dữ liệu đồng
thời bật điều khiển cấp nguồn cho LED 4. Như vậy, LED 4 sẽ sáng số 4 còn 3 LED còn
lại sẽ tắt. Duy trì trạng thái này trong một thời gian
Quá trình được lặp đi lặp lại từ bước 1 đến bước 4. Nếu tần số đạt lớn hơn 24Hz (hiệu
ứng 24 hình/giây) thì mắt người sẽ có cảm giác 4 LED sáng liên tục số 1234. Đó là
nguyên tắc của thuật toán quét LED.
Trong nguyên lý trên, IC 74HC154 làm nhiệm vụ giải mã, điều khiển cấp nguồn cho
LED 7 thanh. Bảng sự thật của IC 74HC154 như sau:
Hình 7: Bảng sự thật của 74hc154
-9-
Bài thực hành số 2: Viết hàm hiển thị số tự nhiên n bất kì (thí dụ, n = 1234)
#include <mega128.h>
#include <delay.h>
#define PORT_LED PORTC
#define PORT_Ctr PORTG
unsigned char m[11]= { 0x03,0x9F,0x25,0x0D,0x99, 0x49,0x41,0x1F, 0x01,0x09};
void hienthison(int n)
{
unsigned char ma[4];
ma[0] = n/1000;
ma[1] = (n%1000)/100;
ma[2] = ((n%1000)%100)/10;

ma[3] = ((n%1000)%100)%10;
//LED1
PORT_LED = m[ma[0]];
PORT_Ctr = 0x08;
delay_ms(2);
PORT_Ctr = 0x00;
//LED2
PORT_LED = m[ma[1]];
PORT_Ctr = 0x04;
delay_ms(2);
PORT_Ctr = 0x00;
//LED3
PORT_LED = m[ma[2]];
PORT_Ctr = 0x0C;
delay_ms(2);
PORT_Ctr = 0x00;
//LED4
PORT_LED = m[ma[3]];
PORT_Ctr = 0x02;
delay_ms(2);
PORT_Ctr = 0x00;
}
Void main()
-10-
{
DDRC = 0xFF;
DDRG = 0xFF;
while (1)
{
hienthison(1234);

};
}
Bài thực hành số 3: Sử dụng hàm hiển thị trên để viết chương trình hiển thị số tăng
dần từ 0 đến 9999, đến 9999 thì tự động quay về 0. Bước nhảy là 0.5s
#include <mega128.h>
#include <delay.h>
#define PORT_LED PORTC
#define PORT_Ctr PORTG
unsigned char m[11]= { 0x03,0x9F,0x25,0x0D,0x99, 0x49,0x41,0x1F, 0x01,0x09};
void hienthison(int n)
{
unsigned char ma[4];
ma[0] = n/1000;
ma[1] = (n%1000)/100;
ma[2] = ((n%1000)%100)/10;
ma[3] = ((n%1000)%100)%10;
//LED1
PORT_LED = m[ma[0]];
PORT_Ctr = 0x08;
delay_ms(2);
PORT_Ctr = 0x00;
//LED2
PORT_LED = m[ma[1]];
PORT_Ctr = 0x04;
delay_ms(2);
PORT_Ctr = 0x00;
//LED3
PORT_LED = m[ma[2]];
PORT_Ctr = 0x0C;
-11-

delay_ms(2);
PORT_Ctr = 0x00;
//LED4
PORT_LED = m[ma[3]];
PORT_Ctr = 0x02;
delay_ms(2);
PORT_Ctr = 0x00;
}
Void main()
{
DDRC = 0xFF;
DDRG = 0xFF;
While(1)
{
int i,j;
hienthison(1234);
for(i = 0; i < 10000; i++)
{
for(j = 0; j < 40; j ++)
hienthison(i);
}
}
}
3. Hiển thị tăng giảm giá trị LED 7 thanh sử dụng 2 nút bấm tăng, giảm
Mục đích: Giúp sinh viên làm quen với việc điều khiển đầu ra dựa vào dữ liệu nhận được
từ đầu vào.
Lý thuyết: Lý thuyết về LED 7 thanh đã trình bày ở mục 2. Phần này chỉ trình bày
lý thuyết về nút bấm tăng - giảm.
Phím tăng, giảm được thiết kế với sơ đồ nguyên lý như sau:
-12-

S W _ G I A M
S W 1 9
T a n g
12
3 4
12
3 4
V C C
S W 2 0
G i a m
12
3 4
12
3 4
S W _ T A N G
V C C
R 1 2
1 0 K
R 1 3
1 0 K
Hình 8: Nguyên lý nút bấm tăng giảm
Theo sơ đồ nguyên lý trên, ở trạng thái không bấm nút, giá trị đưa về vi điều khiển có giá
trị 1 (5V), khi bấm nút, giá trị đưa về được nối trực tiếp với GND nên có giá trị 0 (0V).
Như vậy, khi vi điều khiển nhận được giá trị 0 sẽ hiểu là phím vừa được bấm.
Bài thực hành số 4: Viết chương trình hiển thị số bất kì trên LED 7 thanh, mỗi lần
bấm phím giảm thì số giảm 1 đơn vị, bấm phím tăng thì tăng 1 đơn vị.
#include <mega128.h>
#include <delay.h>
#define PORT_LED PORTC
#define PORT_Ctr PORTG

#define Inc PINB.1
#define Dec PINB.2
int number = 1000;
unsigned char m[11]= {0x03,0x9F,0x25,0x0D,0x99, 0x49,0x41,0x1F, 0x01,0x09};
void hienthison(int n)
{
unsigned char ma[4];
ma[0] = n/1000;
ma[1] = (n%1000)/100;
ma[2] = ((n%1000)%100)/10;
ma[3] = ((n%1000)%100)%10;
//LED1
PORT_LED = m[ma[0]];
PORT_Ctr = 0x08;
delay_ms(2);
PORT_Ctr = 0x00;
//LED2
PORT_LED = m[ma[1]];
PORT_Ctr = 0x04;
delay_ms(2);
PORT_Ctr = 0x00;
//LED3
-13-
PORT_LED = m[ma[2]];
PORT_Ctr = 0x0C;
delay_ms(2);
PORT_Ctr = 0x00;
//LED4
PORT_LED = m[ma[3]];
PORT_Ctr = 0x02;

delay_ms(2);
PORT_Ctr = 0x00;
}
bit inc_flag = 0;
bit dec_flag = 0;
void scan_key()
{
if((Inc == 0)&&(inc_flag == 0))
{
inc_flag = 1;
number++;
}
else if(Inc == 1)
{
inc_flag = 0;
}
if((Dec == 0)&&(dec_flag == 0))
{
dec_flag = 1;
number ;
}
else if(Dec == 1)
{
dec_flag = 0;
}
}
void main()
{
DDRC = 0xFF;
DDRG = 0xFF;

while (1)
{
scan_key();
hienthison(number);
}
}
-14-
Bài thí nghiệm số 2. Điều khiển hiển thị LED ma trận
Yêu cầu:
- Hiển thị lần lượt bảng chữ cái lên trên LED ma trận (từ A->Z)
Mục đích: Giúp sinh viên làm quen với màn hình hiển thị LED ma trận.
Lý thuyết về LED ma trận:
Ma trận LED tức là Dot Matrix LED là tập hợp nhiều đèn LED được bố trí thành
dạng ma trận hìn chữ nhật hoặc hình vuông với số cột là b và số hàng là a. Để giảm số
đường điều khiển, trong các ma trận LED, các LED đã được nối với nhau theo hàng và
theo cột. Số lượng LED trên ma trận LED là axb trong khi số lượng ngõ ra bằng tổng số
hàng và cột: a+b. Việc điều khiển 1 ma trận LED kích thước lớn đòi hỏi phải thiết kế một
mạch driver và diều khiển rất phức tạp. Với mục đích giúp bạn đọc làm quen khái niệm
ma trận LED, trong phạm vi bài thí nghiệm chỉ trình bày thao tác với ma trận LED nhỏ
8x8 (hoặc 7x5), thường được dùng để hiển thị các kí tự. Cấu trúc của một ma trận LED
đơn giản nhất là 7x5 như sau:
Hình 9: Cấu trúc ma trận LED đơn giản 5x7
Bên trong ma trận LED là các LED phát sáng. Trong mô hình trên, Cathode của các LED
trên mỗi hàng được nối chung với nhau và ngõ ra chung là các ngõ ra data. Các Athode
-15-
của các LED trên mỗi cột được nối chung tạo thành các đường điều khiển. Để hiển thị
sáng một kí tự bất kì ta có thể tham khảo thí dụ dưới đây (hiển thị số 4).
Hình 10: LED ma trận hiển thị sô 4
Theo hình trên, để hiển thị LED ma trận, tại mỗi thời điểm ta sẽ cho hiển thị một cột của
LED. Mỗi cột được hiển thị trong một khoảng thời gian, sau đó tắt đi để cột khác hiển thị.

Như vậy, nếu tần số đạt 24Hz (hiệu ứng 24 hình/giây) thì mắt người sẽ có cảm giác như
số 4 được hiển thị một cách liên tục.
Bài thực hành số 1: Hiển thị kí tự A tĩnh lên LED ma trận
unsigned char data[8] = {0x18,0x18,0x24,0x24,0x24,0x7E,0x42,0x4},//A
#include <mega128.h>
#include <delay.h>
#include "data.c"
#define PORT_LED PORTC
#define PORT_Ctr PORTG
void display_char(unsigned char * ch)
{
//Hang1
PORT_LED = ~ch[0];
PORT_Ctr = 0x01;
-16-
delay_ms(2);
PORT_Ctr = 0x00;
//Hang2
PORT_LED = ~ch[1];
PORT_Ctr = 0x09;
delay_ms(2);
PORT_Ctr = 0x00;
//Hang3
PORT_LED = ~ch[2];
PORT_Ctr = 0x05;
delay_ms(2);
PORT_Ctr = 0x00;
//Hang4
PORT_LED = ~ch[3];
PORT_Ctr = 0x0D;

delay_ms(2);
PORT_Ctr = 0x00;
//Hang5
PORT_LED = ~ch[4];
PORT_Ctr = 0x03;
delay_ms(2);
PORT_Ctr = 0x00;
//Hang6
PORT_LED = ~ch[5];
PORT_Ctr = 0x0B;
delay_ms(2);
PORT_Ctr = 0x00;
//Hang7
PORT_LED = ~ch[6];
PORT_Ctr = 0x07;
delay_ms(2);
PORT_Ctr = 0x00;
//Hang8
PORT_LED = ~ch[7];
PORT_Ctr = 0x0F;
delay_ms(2);
PORT_Ctr = 0x00;
}
Void main()
{
DDRC = 0xFF;
DDRG = 0xFF;
while (1)
{
display_char(data);

};
}
Bài thực hành số 2: Hiển thị lần lượt các kí tự từ A -> Z lên LED ma trận, bước
chuyển là 2s.
unsigned char data[8*26] =
-17-
{0x18,0x18,0x24,0x24,0x24,0x7E,0x42,0x42,//A
0x78,0x44,0x44,0x78,0x44,0x44,0x44,0x78,//B
0x1E,0x20,0x40,0x40,0x40,0x40,0x20,0x1E,//C
0x78,0x44,0x42,0x42,0x42,0x42,0x44,0x78, //D
0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x7C, //E
0x7C,0x40,0x40,0x7C,0x40,0x40,0x40,0x40, //F
0x1E,0x20,0x40,0x40,0x4E,0x42,0x22,0x1E, //G
0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x42,
0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x38,
0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x70,
0x44,0x48,0x50,0x60,0x60,0x50,0x48,0x44,
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x78,
0xC6,0xC6,0xAA,0xAA,0x92,0x92,0x82,0x82,
0x62,0x62,0x52,0x52,0x4A,0x4A,0x46,0x46,
0x38,0x44,0x82,0x82,0x82,0x82,0x44,0x38,
0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x40,
0x38,0x44,0x82,0x82,0x82,0x8A,0x44,0x3A,
0x78,0x44,0x44,0x44,0x78,0x48,0x44,0x42,
0x3C,0x40,0x40,0x38,0x04,0x04,0x04,0x78,
0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,
0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,
0x89,0x89,0x89,0x55,0x55,0x55,0x22,0x22,
0x44,0x44,0x28,0x10,0x10,0x28,0x44,0x44,

0x44,0x44,0x28,0x28,0x10,0x10,0x10,0x10,
0x7C,0x04,0x08,0x10,0x10,0x20,0x40,0x7C,
};
#include <mega128.h>
#include <delay.h>
#include "data.c"
#define PORT_LED PORTC
#define PORT_Ctr PORTG
unsigned int char_index = 0;
unsigned int timer1_counter = 0;
void display_char(unsigned char * ch)
{
//Hang1
PORT_LED = ~ch[0];
PORT_Ctr = 0x01;
delay_ms(2);
PORT_Ctr = 0x00;

//Hang2
PORT_LED = ~ch[1];
PORT_Ctr = 0x09;
delay_ms(2);
PORT_Ctr = 0x00;

//Hang3
-18-
PORT_LED = ~ch[2];
PORT_Ctr = 0x05;
delay_ms(2);
PORT_Ctr = 0x00;


//Hang4
PORT_LED = ~ch[3];
PORT_Ctr = 0x0D;
delay_ms(2);
PORT_Ctr = 0x00;

//Hang5
PORT_LED = ~ch[4];
PORT_Ctr = 0x03;
delay_ms(2);
PORT_Ctr = 0x00;

//Hang6
PORT_LED = ~ch[5];
PORT_Ctr = 0x0B;
delay_ms(2);
PORT_Ctr = 0x00;

//Hang7
PORT_LED = ~ch[6];
PORT_Ctr = 0x07;
delay_ms(2);
PORT_Ctr = 0x00;

//Hang8
PORT_LED = ~ch[7];
PORT_Ctr = 0x0F;
delay_ms(2);
PORT_Ctr = 0x00;

}
// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
TCCR1B=0x00;
TCNT1H=0xCF;
TCNT1L=0x28;
if(++timer1_counter >= 10)
{
timer1_counter = 0;
if(++char_index >= 26)
{
char_index = 0;
}
}
TCCR1B=0x03;
}
-19-
Void main()
{
DDRC = 0xFF;
DDRG = 0xFF;
TCCR1A=0x00;
TCCR1B=0x03;
TCNT1H=0xCF;
TCNT1L=0x28;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;

OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x00;
OCR1CL=0x00;
TIMSK=0x04;
#asm("sei")
while (1)
{
display_char(data);
};
}
-20-
Bài thí nghiệm số 3: Điều khiển LCD và bàn phím 3x4
Yêu cầu:
- Hiển thị được LCD
- Điều khiển quét ma trận phím, hiển thị LCD
Mục đích: Giúp sinh viên làm quen với công cụ giao tiếp cơ bản LCD và keypad
1. Hiển thị LCD.
Lý thuyết:
Giống như LED 7 thanh, LCD cũng là thiết bị ngoại vi để giao tiếp với người sử dụng.
Khác với LED 7 thanh ở điểm LCD có thể hiển thị được tất cả các kí tự của bảng mã
ASCCI, tuy nhiên chỉ có thể nhìn được ở khoảng cách gần và giá thành lại tương đối cao.
Hình dạng của LCD 16x2 được sử dụng trong bo thí nghiệm như sau:
Hình 11: Hình ảnh thực của LCD 16x2
Các chân chức năng của LCD như sau:
-21-
Hình 12: Các chân chức năng của LCD
Bảng lệnh của LCD
Hình 13: Bảng lệnh của LCD
Bài thực hành số 1: Viết các hàm gửi lệnh và dữ liệu xuống LCD, qua đó hiển thị nội

dung “Bo thí nghiệm vi điều khiển AVR” dịch từ trái qua phải ở hàng trên của LCD
#include <mega128.h>
#include <delay.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x1B ;PORTA
#endasm
#include <lcd.h>
-22-
// Declare your global variables here
unsigned char str[64] = " BO THI NGHIEM VI DIEU KHIEN AVR ";
unsigned char lcd_str[16];
int index = 0;
void display()
{
int j;
index ++;
if(index == 48)
{
index = 0;
}
for(j = index; j < index+15; j ++)
{
lcd_str[j-index] = str[j];
}
lcd_clear();
lcd_puts(lcd_str);
lcd_gotoxy(0,1);
delay_ms(400);
}

Void main()
{
lcd_init(16);
PORTA.3 = 1;
while (1)
{
display();
};
}
-23-
2. Quét ma trận phím 3x4
Việc có nhiều nút nhấn cũng như tiết kiệm được chân vi điều khiển là một bài toán đặt ra
đối với 1 bài tập vi điều khiển lớn. Việc ghép nối giao tiếp với bàn phím với vi xử lý
được ghép nối thành 1 ma trận hay gọi là ma trận phím! Một ma trận n hàng và m cột có
thể ghép với nhau tối đa m*n phím chức năng. Hôm nay tôi post bài này lên cho các pác
tham khảo cách quét ma trận phím đầu vào.
1) Cấu tạo của 1 ma trận phím 3x4
Nói đến ma trận là ai cũng tưởng tưởng đến hàng và cột. Và các pác cũng bít khi đó nó sẽ
có lợi như thế nào khi ghép kiểu ma trận này. Cấu tạo nó được như hình vẽ dưới:
Hình 14: Sơ đồ nguyên lý mạch quét phím
-24-
R O W 1
S W 1 4
B U T T O N _ 4 P I N
1 2
34
1 2
34
V C C
S W 1 2

B U T T O N _ 4 P I N
1 2
34
1 2
34
R O W 1
C O L 1
R O W 3
C O L 2
R O W 4
R O W 2
S W 1 6
B U T T O N _ 4 P I N
1 2
34
1 2
34
S W 1 5
B U T T O N _ 4 P I N
1 2
34
1 2
34
C O L 1
R O W 1
S W 1 0
B U T T O N _ 4 P I N
1 2
34
1 2

34
S W 1 1
B U T T O N _ 4 P I N
1 2
34
1 2
34
C O L 3
R O W 1
S W 9
B U T T O N _ 4 P I N
1 2
34
1 2
34
R O W 3
R O W 3
R O W 2
S W 8
B U T T O N _ 4 P I N
1 2
34
1 2
34
S W 6
B U T T O N _ 4 P I N
1 2
34
1 2
34

S W 7
B U T T O N _ 4 P I N
1 2
34
1 2
34
R O W 3
R 1 9 1 0 K
12
3
4
5
6
7
8
9
C O L 1
R O W 4
C O L 2
C O L 2
S W 5
B U T T O N _ 4 P I N
1 2
34
1 2
34
C O L 3
C O L 3
S W 1 3
B U T T O N _ 4 P I N

1 2
34
1 2
34
C O L 2
C O L 3
R O W 2
C O L 1
R O W 4
R O W 2
R O W 4
Phím bấm được nối thành ma trận 4 hàng x 4cột, các hàng và cột được nối với các chân
cổng vào ra của vi điều khiển Psoc. Khi một phím được bấm, nó sẽ nối một hàng và một
cột tương ứng.Như vậy ta sẽ có 16 nút nhấn mà chỉ mất có 8 chân vi điều khiển còn
muốn tiếp kiệm hơn nữa là các pác dùng còn giải mã 3 >> 8 (74138) hay dùng 74ls154.
(Cái này cũng không cần bit đâu vì bài của mình đâu lớn như thế) nên nối trực tiếp vào
chân vi điều khiển cho nó nhanh. Khi nút 0 được nhấn thì nó nối giữa cột 1 hàng 1. CÒn
nút 1 được nhấn thì cột 2 và hàng 1 được nối hay nút 2 được nhấn thì nối giữa cột 3 và
hàng 1 cứ như vậy đến nút thứ 12.
2) Nguyên lý quét phím
Thuật toán quét phím được sử dụng là lần lượt tìm hàng và tìm cột (hoặc ngược lại) Khi
tìm hàng, các hàng sẽ được đặt làm đầu vào, các cột được đặt làm đầu ra mức thấp. Sau
đó kiểm tra các hàng xem có hàng nào ở mức thấp hay không (có phím nào bấm gây ra
nối với cột hay không). Sau khi xác định được hàng sẽ đặt các cột làm đầu vào, hàng vừa
tìm được làm đầu ra mức thấp. Việc kiểm tra được tiến hành với các cột. Sau khi xác
định được hàng và cột sẽ suy ra phím được bấm.
Nói thế này cũng khó hiểu nhỉ nhưng mà chỉ cần hiểu sơ qua thuật toán quét LED như thế
này:
+ Đầu tiên cho các hàng ở mức 1 và các cột ở mức 0
+ Kiểm tra xem nào hàng nào đựoc nhấn (khi nút được nhấn) tức là đựoc nhận tín hiệu từ

các cột
+ Nếu mà có 1 hàng bất kỳ đựoc nhấn sau đó ta lại chuyển giá trị 0 vào hàng đựoc nhấn
và giá trị 1 vào các cột. Khi đó cột lại nhận nhiệm vụ làm tín hiệu vào. Nếu mà 1 trong
các cột đựoc nhấn (Khi nút được nhấn) trong các trường hợp này thì cho ra các giá trị
tương ứng.
Bài thực hành số 2: Thực hiện quét ma trận phím, hiển thị giá trị phím bấm lên
LCD (thí dụ: ấn phím 1 hiện số 1 lên LCD)
-25-

×