You are on page 1of 122

1

MỤC LỤC

MỤC LỤC 1

DANH MỤC BẢNG BIỂU 4

DANH MỤC HÌNH VẼ 5

DANH MỤC THUẬT NGỮ VIẾT TẮT 8

LỜI MỞ ĐẦU 12

TỔNG QUAN ĐỀ TÀI 13

1. Giới thiệu chung. 13

2. Mục tiêu đề tài. 14

3. Phạm vi và giới hạn nghiên cứu. 14

CHƯƠNG 1: VI ĐIỀU KHIỂN ATMEGA32 16

1.1. Đôi nét về vi điều khiển ATmega32. 16

1.2. Cấu trúc vi điều khiển. 18

1.2.1. Sơ đồ chân của ATmega32............................................................18

1.2.2. Sơ đồ khối của ATmega32.............................................................21

1.2.3. Tổ chức của AVR..........................................................................23

1.2.4. Bộ nhớ chương trình (Program memory)......................................24

1.3. Các thanh ghi chức năng đặc biệt. 29

1.3.1. Status Register (SREG).................................................................30

1.3.2. SP (Stack Pointer)..........................................................................31

1.4. ADC (Analog to Digital Converter). 32

1.4.1. Nguyên lý chuyển đổi từ dữ liệu tương tự sang số (A - D)...........32


2

1.4.2. Chuyển đổi ADC trên AVR...........................................................35

1.5. Ngắt ngoài. 36

1.5.1. Ngắt trên AVR...............................................................................36

1.5.2. Ngắt ngoài.....................................................................................38

1.6. Timer – Counter. 41

1.6.1. Tổng quan các bộ Timer/Counter trên chip ATmega32................41

1.6.2. Sử dụng Timer/Counter.................................................................42

1.7. USART. 44

1.7.1. Cờ và ngắt trong truyền nối tiếp....................................................44

1.7.2. Sơ đồ khối bộ USART...................................................................45

1.8. Giao tiếp TWI – I2C. 46

1.8.1. Nguyên lý truyền thông nối tiếp TWI và I2C................................46

1.8.2. TWI trên AVR................................................................................53

CHƯƠNG 2: CƠ SỞ LÝ THUYẾT XÂY DỰNG MÔ HÌNH 65

2.1. Tổng quan về xử lý ảnh. 65

2.1.1. Khái niệm xử lý ảnh......................................................................65

2.1.2. Các bước cơ bản trong xử lý ảnh..................................................65

2.2. Bộ thư viện OpenCV. 67

2.2.1. Giới thiệu về bộ thư viện OpenCV................................................67

2.2.2. Cấu tạo của OpenCV.....................................................................67

2.3. Một số loại camera thường dùng trong xử lý ảnh. 68

2.4. Giao tiếp máy tính với phần mềm Visual C++ 2008. 72

2.4.1. Tìm hiểu cổng nối tiếp máy tính...................................................72

2.4.2. Vi mạch MAX232.........................................................................77


3

2.4.3. Giao tiếp máy tính với phần mềm Visual C++2008......................78

2.5. Cảm biến OMRON E3S. 80

2.6. Drive điều khiển động cơ dùng MC33886. 81

2.7. Modun led matrix.83

CHƯƠNG 3: XÂY DỰNG MÔ HÌNH HỆ THỐNG 85

3.1. Sơ đồ khối hệ thống. 85

3.2. Nguyên lý hoạt động của mô hình. 86

3.3. Giao diện phần mềm. 87

3.4. Mạch điều khiển. 88

3.4.1. Khối điều khiển trung tâm ATmega32..........................................88

3.4.2. Khối nguồn cung cấp.....................................................................89

3.4.3. Khối Driver điều khiển động cơ....................................................89

3.4.4. Khối modun led matrix.................................................................90

3.4.5. Khối truyền thông RS232..............................................................90

3.4.6. Hình ảnh mạch thực tế...................................................................91

3.5. Lắp ghép mô hình. 88

CHƯƠNG 4: CHẠY THỬ NGHIỆM MÔ HÌNH VÀ ĐÁNH GIÁ, KẾT


LUẬN 93

4.1. Ảnh chạy thực nghiệm mô hình hệ thống 93

4.2. Đánh giá kết quả đạt được. 93

4.3. Hướng phát triển của đề tài. 94

4.4. Kết luận. 95

PHỤ LỤC 97

1. Code chương trình ATmega32: 97

2. Hướng dẫn sử dụng phần mềm Codevision. 117


4

DANH MỤC BẢNG BIỂU

Bảng 1. 1 Chức năng các chân PORT B.........................................................19


Bảng 1. 2 Chức năng các chân PORT C.........................................................20
Bảng 1. 3 Chức năng các chân PORT D.........................................................21
Bảng 1. 4 Reset và vectơ ngắt.........................................................................25
Bảng 1. 5 Giá trị số ngõ ra sau khi giải mã....................................................33
Bảng 1. 6 Các vector ngắt và Reset trên chip Atmega32................................38
Bảng 1. 7 Chức năng của các bit ISC11 và ISC10 dùng cho INT1.................39
Bảng 1. 8 Cách xác định tốc độ baud.............................................................45
Bảng 2. 1 So sánh mức điện áp TTL và RS232...............................................45
5

DANH MỤC HÌNH VẼ

Hình 1.2: Sơ đồ chân Atmega32......................................................................18


Hình 1.1: Hình dạng thực tế Atmega32..........................................................18
Hình 1.3: Sơ đồ khối của Atmega32................................................................23
Hình 1.4:Tổ chức bộ nhớ của AVR.................................................................24
Hình 1.5: Thanh ghi 8 bits..............................................................................26
Hình 1.6: Register file.....................................................................................27
Hình 1.7: Cấu trúc bên trong AVR..................................................................29
Hình 1.8: Các bit trong thanh ghi SREG........................................................30
Hình 1.9: Các bit trong thanh ghi SP..............................................................31
Hình 1.10:Mạch flash ADC với 4 bộ so sánh..................................................33
Hình 1.11: Tín hiệu analog và digital của hàm sin.........................................34
Hình 1.12: Tạo nguồn AVCC từ VCC.............................................................36
Hình 1.13: Ngắt...............................................................................................37
Hình 1.14: Cấu trúc thanh ghi MCUCR.........................................................39
Hình 1.15: Thanh ghi điều khiển ngắt chung GICR.......................................40
Hình 1.16: Cấu trúc thanh ghi GIRF...............................................................40
Hình 1.17: Thiết lập ngắt ngoài......................................................................41
Hình 1.18: Thanh ghi TCCR0 của T/C0.........................................................42
Hình 1.19: Thanh ghi TIMSK của T/C0..........................................................43
Hình 1.20: Sơ đồ khối USART.........................................................................46
Hình 1.21: Mạng TWI (I2C) với nhiều thiết bị và 2 điện trở kéo lên cho SDA,
SCL..................................................................................................................47
Hình 1.22: Lấy mẫu dữ liệu nối tiếp...............................................................48
Hình 1.23: Master tạo ra START, STOP và REPEAT START..........................49
Hình 1.24: Định dạng gói địa chỉ...................................................................51
6

Hình 1.25: Định dạng dữ liệu trong TWI (I2C)..............................................52


Hình 1.26: Phối hợp gói địa chỉ và dữ liệu.....................................................52
Hình 1.27: Thanh ghi TWBR...........................................................................53
Hình 1.28: Thanh ghi TWCR...........................................................................54
Hình 1.29: Thanh ghi TWSR...........................................................................56
Hình 1.30: Thanh ghi TWAR...........................................................................57
Hình 1.31: Quá trình Master truyền dữ liệu...................................................59
Hình 1.32: Quá trình Master nhận dữ liệu.....................................................61
Hình 1.33: Slave nhận dữ liệu.........................................................................62
Hình 1.34: Slave nhận dữ liệu.........................................................................64
Hình 2.1: Sơ đồ quá trình xử lý ảnh................................................................65
Hình 2.2: Các bước cơ bản trong xử lý ảnh....................................................66
Hình 2.3: Sơ đồ khối CMOS camera...............................................................69
Hình 2.4: Sơ đồ khối CCD camera.................................................................69
Hình 2.5: CMOS camera.................................................................................71
Hình 2.6: CCD camera...................................................................................72
Hình 2.7: Các mức điện áp của chuẩn RS232................................................74
Hình 2.8: Mức lôgic và khuôn mẫu khung truyền RS232...............................75
Hình 2.9: Cổng com máy tính thực tế.............................................................77
Hình 2.10: Vi mạch MAX232..........................................................................78
Hình 2.11: Lấy ra công cụ điều khiển cổng com trên Visual C++2008.........78
Hình 2.12: Biểu tượng cổng COM trên Visual C++ 2008..............................79
Hình 2.13: Hình ảnh cảm biến OMRON E3S.................................................80
Hình 2.14 : Sơ đồ nối dây cảm biến OMRON E3S.........................................81
Hình 2.15: Sơ đồ nguyên lý và hình dạng thực tế chip MC33886..................81
Hình 2.16: Sơ đồ khối chip MC33886.............................................................82
Hình 2.17: Sơ đồ ghép nối MC33886 với vi điều khiển..................................82
Hình 2.18: Modun led matrix..........................................................................83
Hình 2.19: Led matrix 8x8 đa sắc...................................................................83
7

Hình 3.1: Sơ đồ khối hệ thống.........................................................................85


Hình 3.2: Giao diện phần mềm điều khiển......................................................87
Hình 3.3: Khối điều khiển trung tâm ATmega32............................................88
Hình 3.4: Khối nguồn cung cấp......................................................................89
Hình 3.5: Khối Driver điều khiển động cơ......................................................89
Hình 3.6: Khối modun matrix.........................................................................90
Hình 3.7: Khối truyền thông RS232................................................................90
Hình 3.8: Hình ảnh mạch điều khiển..............................................................91
Hình 3.9: Modun led matrix............................................................................91
Hình 3.10: Driver điều khiển động cơ............................................................91
Hình 3.11: Mô hình bãi đỗ xe hoàn thiện........................................................92
Hình 4.1: Ảnh chạy thực nghiệm mô hình.......................................................93
8

DANH MỤC THUẬT NGỮ VIẾT TẮT

TỪ VIẾT TỪ ĐẦY ĐỦ NGHĨA TIẾNG VIỆT


TẮT
ACK Ackknowledge Tin báo nhận
ADC Analog to Digital Converter Bộ chuyển đổi tương tự -
số
ALU Arithmetic Logic Unit Đơn vị số học - logic
BCD Binary-Coded Decimal Số thập phân theo mã nhị
phân
CISC Complex Instruction Set Máy tính sử dụng bộ lệnh
Computer tích hợp
COM Compare Output Match Bit quy định dạng ngõ ra
CPU Central Processing Unit Đơn vị xử lý trung tâm
CS Clock Select Bit chọn nguồn xung
nhịp
EEPROM Electricaly Ereasable Bộ nhớ ROM xóa và lập
Programmable ROM trình được bằng điện
GICR General Interrupt Control Thanh ghi điều khiển
Register ngắt chung
GIFR General Interrupt Flag Register Thanh ghi cờ ngắt chung
GPR General Purpose Register Thanh ghi dữ liệu
I2C Inter-Integrated Circuit Chuẩn truyền thông nối
tiếp đa chip chủ
ISR Interrupt Service Routine Trình phục vụ ngắt
LCD Liquid-Crystal Display Màn tinh thể lỏng

LPM Load Program Memory Bộ nhớ nạp chương trình

MCUCR Micro Control Unit Control Thanh ghi điều khiển


Register MCU
NACK Not Acknowledge Tín hiệu không xác nhận
9

P Stop condition Điều kiện kết thúc


PC Program Counter Bộ đếm chương trình
PWM Pulse Width Modulation Điều chế độ rộng xung
R Read Bit Bit đọc
RAM Random Access Memory Bộ nhớ truy cập ngẫu
nhiên
ROM Read Only Memory Bộ nhớ chỉ đọc
RF Register file Thanh ghi tập tin
RISC Reduced Instruction Set Máy tính dùng tập lệnh
Computer rút gọn
Rs Repeat start Bắt đầu lặp lại
RTC Real – time clock Đồng hồ thời gian thực
RXEN Receive Enable Bit cho phép nhận
R/W Read/Write Đọc/ ghi
S START condition Điều kiện bắt đầu
SCL Serial Clock Đường xung nhịp
SDA Serial DATA Đường truyền /nhận dữ
liệu
SLA Slave address Địa chỉ của Slave cần
giao tiếp
SP Stack Pointer Con trỏ ngăn xếp
SPI Serial Peripheral Interface Chuẩn truyền thông nối
tiếp
SRAM Static random-access memory Ram tĩnh
SREG Status Register Thanh ghi trạng thái
T/C Timer/ Couter Bộ định thời/ bộ đếm
TCCR Timer/Counter Control Register Thanh ghi điều khiển
hoạt động T/C
TCNT Timer/Counter Register Thanh ghi chứa giá trị
vận hành T/C
TCCR1A,TC Timer/Counter Control Register Thanh ghi điều khiển
CR1B hoạt động của T/C
TIFR Timer/Counter Interrupt Flag Thanh ghi cờ nhớ cho
Register T/C
10

TIMSK Timer/Counter Interrupt Mask Thanh ghi mặt nạ cho


Register ngắt T/C
TXC Transmit Complete Bit báo truyền thành công
TXEN Transmit Enable Bit cho phép truyền
TWAR TWI Address Register Thanh ghi chứa device
address của chip Slave
TWBR TWI Bit Rate Register Thanh ghi quy định tốc
độ phát xung giữ nhịp
trên đường SCL của
Master
TWCR TWI Control Register Thanh ghi điều khiển
hoạt động của TWI.
TWDR TWI Data Register Thanh ghi dữ liệu chính
TWI
TWEA TWI Enable Acknowledge Bit Bit kích hoạt tín hiệu xác
nhận
TWEN TWI Enable Bit Bit kích hoạt TWI
TWGCE TWI General Call Enable Bit cho phép cuộc gọi
chung
TWI Two-Wire Serial Interface Truyền thông nối tiếp đa
chip chủ
TWIE TWI Interrupt Enable Bit Bit cho phép ngắt TWI
TWINT TWI Interrupt Flag Cờ báo ngắt TWI
TWSR TWI Status Register Thanh ghi trạng thái TWI
TWSTA TWI START Condition Bit Bit tạo điều kiện bắt đầu
TWI
TWSTO TWI STOP Condition Bit Bit tạo điều kiện kết thúc
TWI
TWWC TWI Write Collision Flag Cờ báo bận TWI
UART Universal Asynchronus Receiver Bộ truyền nhận không
Transmitter đồng bộ
UDRE USART Data Register Empty Cờ báo cho biết bộ đệm
đã sẵn sàng nhận dữ liệu
mới
11

USART Universal Synchronous & Bộ truyền nhận nối tiếp


Asynchronous serial Receiver đồng bộ và không đồng
and Transmitter bộ
W WRITE Bit Bit ghi
WGM Waveform Generating Mode Bit chọn mode hay chọn
dạng sóng
12

LỜI MỞ ĐẦU
Ngày nay, với những ứng dụng của khoa học kỹ thuật tiên tiến, thế giới
của chúng ta đã và đang một ngày thay đổi, văn minh và hiện đại hơn. Sự phát
triển của kỹ thuật điện tử đã tạo ra hàng loạt những thiết bị với các đặc điểm
nổi bật như sự chính xác cao, tốc độ nhanh, gọn nhẹ là những yếu tố rất cần
thiết góp phần cho hoạt động của con người đạt hiệu quả cao.

Điện tử đang trở thành một ngành khoa học đa nhiệm vụ. Điện tử đã đáp
ứng được những đòi hỏi không ngừng từ các lĩnh vực công – nông – lâm –
ngư nghiệp cho đến các nhu cầu cần thiết trong hoạt động đời sống hằng
ngày.

Đề tài “Tìm hiểu vi điều khiển AVR và thiết kế mạch ứng dụng trong mô
hình bãi đỗ xe thông minh” mà hiện tại em được giao thực sự là một thử
thách rất lớn, và đó cũng là động lực cho em hoàn thành tốt đề tài để có thể
sớm ứng dụng vào cuộc sống. Hệ thống ra đời giúp rút ngắn thời gian và cách
quản lý bãi gửi xe thủ công như trước đây.

Em xin chân thành cảm ơn các thầy cô giáo trong khoa điện tử và các
thầy cô bên trường CĐ Nghề Công Nghệ Cao HN đã tạo điều kiện cho em có
cơ hội thực hiện tốt đồ án của mình. Đặc biệt là sự hướng dẫn từ Ths.Vũ Thị
Thu Hương và Ts. Ngô Mạnh Tiến người đã trực tiếp hướng dẫn và giúp
em có những định hướng trong suốt quá trình thực hiện đồ án.

Do thời gian còn hạn chế nên cũng không thế tránh được những thiếu
sót trong quá trình thực hiện đồ án. Vì vậy, em mong nhận được ý kiến đóng
góp từ phía các thầy cô cùng các bạn để có thể hoàn thiện hơn đề tài của
mình.
13

Hà Nội, ngày 16 tháng 6 năm 2012.

SV: Lê Đức Hệ

TỔNG QUAN ĐỀ TÀI

1. Giới thiệu chung.

Ngày nay, sự phát triển vượt bậc của khoa học kỹ thuật đã mang lại cho
các ngành kỹ thuật nói chung và ngành điện tử nói riêng một khuôn mặt mới.
Việc ứng dụng các thành tựu khoa học kỹ thuật vào trong lĩnh vực điện tử - tự
động hoá đã mang lại những chuyển biến rõ rệt, góp phần thúc đẩy sự phát
triển mạnh mẽ của nhiều lĩnh vực công nghệ, đáp ứng được các chỉ tiêu về
chất lượng và giá thành sản phẩm ... nâng cao chất lượng cuộc sống.

Với việc sử dụng các vi điều khiển, bộ não của các hệ thống, các công
việc được diễn ra hoàn toàn tự động, rút ngắn thời gian, giảm nhân lực lao
động. Trên thị trường có rất nhiều họ vi điều khiển: họ 8051 của Intel,
68HC11 của Motorola, Z80 của hãng Eilog, PIC của hãng Microchip, H8 của
Hitachi,vv.. và cuối cùng là AVR của hãng Atmel.

AVR là họ Vi điều khiển khá mới trên thị trường cũng như đối với
người sử dụng. Đây là họ VĐK được chế tạo theo kiến trúc RISC (Reduced
Intruction Set Computer) có cấu trúc khá phức tạp. Ngoài các tính năng như
các họ VĐK khác, nó còn tích hợp nhiều tính năng mới rất tiện lợi cho người
thiết kế và lập trình.
Sự ra đời của AVR bắt nguồn từ yêu cầu thực tế là hầu hết khi cần lập
trình cho vi điều khiển chúng ta thường dùng những ngôn ngữ bậc cao HLL
(Hight Level Language) để lập trình ngay cả với loại chip xử lí 8 bit trong đó
ngôn ngữ C là ngôn ngữ phổ biến nhất. Tuy nhiên khi biên dịch thì kích
thước đoạn mã sẽ tăng nhiều so với dùng ngôn ngữ Assembly. Hãng Atmel
nhận thấy rằng cần phải phát triển một cấu trúc đặc biệt cho ngôn ngữ C để
14

giảm thiểu sự chênh lệch kích thước mã đã nói trên. Và kết quả là họ vi điều
khiển AVR ra đời với việc làm giảm kích thước đoạn mã khi biên dịch và
thêm vào đó là thực hiện lệnh đúng đơn chu kỳ máy với 32 thanh ghi tích lũy
và đạt tốc độ nhanh hơn các họ vi điều khiển khác từ 4 đến 12 lần. Vì thế
nghiên cứu AVR là một đề tài khá lý thú và giúp cho sinh viên biết thêm một
họ vi điều khiển vào loại mạnh nhất hiện nay.
Để vi điều khiển hoạt động đúng chức năng của nó là thu thập, xử lý
thông tin, điều khiển thì việc ghép nối với các thiết bị ngoài là điều tất yếu.
Trong đề tài này em có sử dụng một lĩnh vực khoa học khá mới mẻ “ thị giác
máy tính ”. Công nghệ này cho phép thực hiện các quá trình công nghệ không
có sự tham gia của con người giúp giảm thiểu lỗi do con người gây ra
( human error), đảm bảo độ chính xác và tăng năng suất lao động. Do đó, em
quyết định chọn đề tài “Tìm hiểu vi điều khiển AVR và thiết kế mạch ứng
dụng trong mô hình bãi đỗ xe thông minh”.
Nhiệm vụ của đề tài là xây dựng mạch điều khiển mô hình bãi đỗ xe
thông mình, kết hợp với phần mềm nhận dạng ảnh lấy ra được biển số xe. Vi
điều khiển sẽ xử lý các thông tin, xác định có xe vào bến, gửi yêu cầu nhận
dạng lên phần, hiển thị biển số xe vào và tiếp nhận thông tin cho phép xe vào
bến hay không.
2. Mục tiêu đề tài.
- Nghiên cứu về AVR và các vấn đề liên quan như cách sử dụng mạch nạp,
các chương trình phần mềm hỗ trợ lập trình.
- Nghiên cứu phương pháp truyền nhận dữ liệu giữa vi điều khiển và phần
mềm Visual C++2008.
- Lập trình được vi điều khiển vận hành hệ thống nhanh và chính xác. Hệ
thống nhận biết được xe vào bến , hiển thị thông tin xe đến trên modun
led matrix, nâng hạ barie tự động cho phép xe vào bãi đỗ.
3. Phạm vi và giới hạn nghiên cứu.

Do đây là một đề tài lớn có rất nhiều các ứng dụng trong thực tế vì vậy có
rất nhiều phương hướng và cách phát triển. Tuy nhiên trong phạm vi một đề
15

tài tốt nghiệp với những hạn chế về thời gian và công nghệ nên phạm vi đề tài
được giới hạn lại như sau:

- Sử dụng các hàm chuẩn trong bộ thư viện mã nguồn mở OpenCV 2.0 để
xây dựng thuật toán xử lý ảnh.

- Xây dựng phần mềm nhận dạng, xử lý thông tin, gửi xuống vi điều khiển
chấp hành.

- Xây dựng modun led matrix 8x56 hiển thị 3 màu thông tin xe vào và thông
báo của bãi gửi xe.

- Xây dựng mô hình cơ khí bãi đỗ xe gồm các hệ thống cảm biến, barie tự
động, hệ thống camera nhận dạng.
16

CHƯƠNG 1: VI ĐIỀU KHIỂN ATMEGA32

1.1. Đôi nét về vi điều khiển ATmega32.


Vi điều khiển là một lĩnh vực khá lý thú đối với chuyên ngành Điện tử.
Cùng với sự phát triển của ngành điện tử thì nhiều họ vi điều khiển lần lượt
được các hãng sản xuất chip cho ra đời như: Z80 của Zilog, AT89 của Atmel,
PIC của Microchip, AVR của Atmel...

Họ vi điều khiển AVR của Atmel Corp là 1 bước phát triển trên nền của Vi
điều khiển AT89 đã khá quen thuộc. Nếu như AT89 là vi điều khiển có CPU
CISC thì AVR là RISC với kiến trúc Harvard do vậy tốc độ sẽ nhanh hơn (tốc
độ tối đa là 16 triệu lệnh/giây). Ngoài ra AVR cũng tích hợp sẵn ngay trong
chip mạch ADC, PWM,....cũng như hỗ trợ các chuẩn giao tiếp thông dụng
như UART/USART, I2C, 2-wires,... nên việc thiết kế và thực hiện phần cứng
cho những ứng dụng rất thuận tiện, nhanh chóng, nhỏ gọn.

Về ngôn ngữ lập trình cho AVR thì có rất nhiều: assembly, C, Basic,
Pascal…trong đó những phần mềm miễn phí do chính Atmel cung cấp, hay
những hãng khác là rất nhiều avrasm, winasm (hợp ngữ), CodeVision AVR,
Win-GCC (ngôn ngữ C), BASCOM (ngôn ngữ Basic)… Hơn thế việc mô
phỏng, debug cũng được hỗ trợ từ A-Z, nhiều phần mềm simulator, emulator
như: AVR Studio (miễn phí của ATmel), Proteus….

ATmega32 là vi điều khiển chuẩn CMOS 8 bit tiết kiệm năng lượng, được
chế tạo dựa trên cấu trúc AVR RISC (Reduced Instruction Set Computer), đây
là cấu trúc có tốc độ xử lý cao hơn nhiều so với cấu trúc CISC (Complex
Instruction Set Computer). Tần số hoạt động của vi điều khiển AVR bằng với
tần số của thạch anh, trong khi với họ vi điều khiển theo cấu trúc CISC như
17

họ 8051 thì tần số hoạt động bằng tần số thạch anh chia cho 12. Hầu hết các
lệnh được thực thi trong một chu kỳ xung nhịp, do đó ATmega32 có thể đạt
được tốc độ xử lý đến một triệu lệnh mỗi giây (với tần số 1MHz). Đặc điểm
này cho phép người thiết kế có thể tiết kiệm tối đa mức độ tiêu thụ năng
lượng mà vẫn đảm bảo tốc độ xử lý.

Các tính năng của ATmega32:

- Vi điều khiển 8 bit, có tính năng sử dụng cao, công suất thấp.

- Có 131 tập lệnh theo kiến trúc RISC, chủ yếu thực hiện trong 1 chu kì
máy.

- 32x8 thanh ghi đa dụng.

- 16KB bộ nhớ flash có khả năng lập trình được.

- 512 Bytes EEPROM.

- 1K Byte Internal SRAM.

- Nhiều ngõ vào ra (I/O Port) 2 hướng (bi-directional).

- 2 bộ Timer/Counters 8-bit với Separate Prescalers và Compare


Modes.

- 1 Timer/Counter 16-bit với Separate Prescaler, Compare Mode và


-Capture Mode.

- 4 kênh PWM.

- 8 kênh chuyển đổi ADC 10-bit.

- 8 kênh chuyển đổi đơn.

- 7 kênh chuyển đổi vi sai chỉ được đóng gói trong TQFP .
18

- 2 kênh chuyển đổi vi sai có khả năng lập trình, lựa chọn độ lợi 1x,
10x, or 200x.

- Giao diện nối tiếp USART (tương thích chuẩn nối tiếp RS-232).

- Giao diện nối tiếp Two-wire Serial (tương thích chuẩn I2C).

- Giao diện nối tiếp SPI Master và Slave.

- Bộ Watchdog Timer có khả năng lập trình được với bộ dao động trên
chip.

- Bộ so sánh Analog trên chip.

1.2. Cấu trúc vi điều khiển.

1.2.1. Sơ đồ chân của ATmega32.

Hình VI ĐIỀU KHIỂN ATMEGA32.1: Hình


dạng thực tế Atmega32.
19

Hình VI ĐIỀU KHIỂN ATMEGA32.2: Sơ đồ chân Atmega32.

 Mô tả chân linh kiện:


- VCC & GND: Chân cấp nguồn cho vi điều khiển.
- Port A (PA7..PA0)
Được dành riêng cho ngõ vào analog của bộ chuyển đổi ADC.
Ngoài ra Port A còn được dùng như 1 Port vào ra 2 hướng nếu bộ
chuyển đổi ADC không sử dụng. Mỗi chân của Port A được cung cấp
điện trở kéo lên bên trong. Bộ đệm ngõ ra của Port A được điều khiển
cho cả 2 khả năng, sink dòng và source dòng. Khi Port A sử dụng như
ngõ vào, chúng sẽ source dòng nếu điện trở kéo lên bên trong tích cực.

- Port B (PB7..PB0)
Port B được dùng như 1 Port vào ra 2 hướng với điện trở kéo lên
bên trong. Mỗi chân của Port B được cung cấp điện trở kéo lên bên
trong. Bộ đệm ngõ ra của Port B được điều khiển cho cả 2 khả năng,
sink dòng và source dòng. Khi Port B sử dụng như ngõ vào, chúng sẽ
source dòng nếu điện trở kéo lên bên trong tích cực. Ngoài ra, Port B
còn được sử dụng những chức năng khác, được trình bày như trong
bảng 1.1.
20

Bảng 1. 1 Chức năng các chân PORT B.

-Port C (PC7..PC0)
Port C được dùng như 1 Port vào ra 2 hướng với điện trở kéo lên bên
trong. Mỗi chân của Port B được cung cấp điện trở kéo lên bên trong. Bộ đệm
ngõ ra của Port C được điều khiển cho cả 2 khả năng, sink dòng và source
dòng. Khi Port C sử dụng như ngõ vào, chúng sẽ source dòng nếu điện trở
kéo lên bên trong tích cực. Nếu sử dụng giao tiếp JTAG, điện trở kéo lên ở
chân PC5 (TDI), PC3 (TMS) và PC2 (TCK) sẽ tích cực thậm chí có Reset xảy
ra. Port C sử dụng cho giao tiếp JTAG và các tính năng đặc biệt của AVR
được liệt kê ra trong bảng 1.2.

Bảng 1. 2 Chức năng các chân PORT C.

-Port D (PD7..PD0)
Port D được dùng như 1 Port vào ra 2 hướng với điện trở kéo lên bên
trong. Mỗi chân của Port D được cung cấp điện trở kéo lên bên trong. Bộ đệm
ngõ ra của Port D được điều khiển cho cả 2 khả năng, sink dòng và source
dòng. Khi Port D sử dụng như ngõ vào, chúng sẽ source dòng nếu điện trở
21

kéo lên bên trong tích cực. Ngoài ra, Port D còn được sử dụng những chức
năng khác, được trình bày trong bảng 1.3.

Bảng 1. 3 Chức năng các chân PORT D.

Reset: Ngõ vào Reset. Nếu mức Low đặt vào chân này dài hơn độ rộng
xung tối thiểu sẽ reset AVR cho dù không có xung clock.

- XTAL1 & XTAL2: Ngõ vào ra của bộ dao động thạch anh.
- AVCC: Chân nguồn cung cấp cho Port A và bộ chuyển đổi ADC.
Thường được kết nối với Vcc, thậm chí nếu ADC không được sử dụng.
Còn nếu ADC được sử dụng, nên kết nối với Vcc thông qua 1 mạch lọc
thông thấp.
- AREF: Chân điện áp tham chiếu cho bộ chuyển đổi ADC.

1.2.2. Sơ đồ khối của ATmega32.


Phần lõi AVR kết hợp tập lệnh phong phú với 32 thanh ghi đa dụng. Toàn
bộ 32 thanh ghi này đều kết nối trực tiếp với ALU (Arithmetic Logic Unit),
cho phép truy cập 2 thanh ghi độc lập với 1 lệnh thực thi trong 1 chu kỳ xung
nhịp. Cấu trúc đạt được có tốc độ xử lý nhanh gấp 10 lần so với vi điều khiển
CISC thông thường.
22

Với các tính năng đã nêu trên, khi ở chế độ nghỉ (Idle), CPU vẫn cho
phép các chức năng khác hoạt động như: USART, giao tiếp 2 dây, chuyển đổi
A/D, SRAM, bộ đếm/bộ định thời, cổng SPI và các chế độ ngắt. Chế độ
Power-down lưu giữ nội dung các thanh ghi nhưng làm ngừng bộ tạo dao
động, thoát khỏi các chức năng của chip cho đến khi có ngắt ngoài hoặc reset
phần cứng. Trong chế độ Power-save, đồng hồ đồng bộ tiếp tục chạy cho
phép chương trình có thể giữ được sự đồng bộ về thời gian nhưng các thiết bị
còn lại ở trong trạng thái ngủ. Chế độ ADC Noise Reduction dừng CPU và tất
cả các thiết bị còn lại ngoại trừ đồng hồ đồng bộ và ADC, giảm thiểu nhiễu
khi ADC hoạt động. Ở chế độ Standby, bộ tạo dao động chạy trong khi các
thiết bị còn lại ở trạng thái ngủ. Những đặc điểm này cho phép bộ vi điều
khiển khởi động rất nhanh trong chế độ tiêu thụ công suất thấp.

AVR được sản xuất sử dụng công nghệ bộ nhớ cố định mật độ cao của
Atmel. Bộ nhớ On-chip ISP Flash cho phép lập trình lại vào hệ thống thông
qua giao diện SPI bởi bộ lập trình bộ nhớ cố định truyền thống hoặc bởi
chương trình On-chip Boot chạy trên lõi AVR. Chương trình Boot có thể sử
dụng bất cứ giao diện nào để down load chương trình ứng dụng trong bộ nhớ
Flash. Phần mềm trong vùng BootFlash sẽ tiếp tục chạy trong khi vùng
Application Flash được cập nhật, giúp tạo ra thao tác Read-While-Write thực
sự. Nhờ việc kết hợp một bộ 8bit RISC CPU với In-System Self-
Programmable Flash chỉ trong một chip, ATmega32 là một vi điều khiển
mạnh có thể cung cấp những giải pháp có tính linh động cao, giá thành rẻ cho
nhiều ứng dụng điều khiển nhúng. ATmega32 được hỗ trợ đầy đủ với các
công cụ hỗ trợ phát triển cũng như lập trình, bao gồm: trình biên dịch C,
macroassembler, mô phỏng/dò lỗi lập trình, mô phỏng mạch điện và các bộ
kit thí nghiệm.
23

Hình VI ĐIỀU KHIỂN ATMEGA32.3: Sơ đồ khối của Atmega32.


24

1.2.3. Tổ chức của AVR.


Cũng như mọi vi điều khiển khác AVR có cấu trúc Harvard trong đó
đường truyền cho bộ nhớ dữ liệu (data memory bus) và đường truyền cho bộ
nhớ chương trình (program memory bus) được tách riêng. Data memory bus
chỉ có 8 bit và được kết nối với hầu hết các thiết bị ngoại vi, với register file.
Trong khi đó program memory bus có độ rộng 16 bits và chỉ phục vụ cho
instruction registers. Hình 1.4 mô tả cấu trúc bộ nhớ của AVR.

Sơ đồ bộ nhớ:

Hình VI ĐIỀU KHIỂN ATMEGA32.4:Tổ chức bộ nhớ của AVR.


1.2.4. Bộ nhớ chương trình (Program memory).
Là bộ nhớ Flash lập trình được, trong các chip AVR cũ (như AT90S1200
hay AT90S2313…) bộ nhớ chương trình chỉ gồm 1 phần là Application Flash
Section nhưng trong các chip AVR mới chúng ta có thêm phần Boot Flash
setion. Boot section sẽ được khảo sát trong các phần sau, trong bài này khi nói
về bộ nhớ chương trình, chúng ta tự hiểu là Application section. Thực chất,
Application section bao gồm 2 phần: phần chứa các instruction (mã lệnh cho
hoạt động của chip) và phần chứa các vector ngắt (interrupt vectors). Các
vector ngắt nằm ở phần đầu của application section (từ địa chỉ 0x0000) và dài
25

đến bao nhiêu tùy thuộc vào loại chip. Phần chứa instruction nằm liền sau đó,
chương trình viết cho chip phải được load vào phần này.

Bộ nhớ chương trình có địa chỉ từ 0000H tới 0010H được dành cho bảng
véc tơ ngắt.

Bảng 1. 4 Reset và vectơ ngắt.

1.2.5. Bộ nhớ dữ liệu (Data Memory).


Đây là phần chứa các thanh ghi quan trọng nhất của chip, việc lập trình
cho chip phần lớn là truy cập bộ nhớ này. Bộ nhớ dữ liệu trên các chip AVR
có độ lớn khác nhau tùy theo mỗi chip, tuy nhiên về cơ bản phần bộ nhớ này
được chia thành 5 phần.

Phần 1:
26

Là phần đầu tiên trong bộ nhớ dữ liệu, như mô tả trong hình 1.4, phần
này bao gồm 32 thanh ghi có tên gọi là register file (RF), hay General
Purpose Register – GPR, hoặc đơn giản là các Thanh ghi. Tất cả các thanh ghi
này đều là các thanh ghi 8 bits như trong hình 1.5.

Hình VI ĐIỀU KHIỂN ATMEGA32.5: Thanh ghi 8 bits.


Tất cả các chip trong họ AVR đều bao gồm 32 thanh ghi Register File
có địa chỉ tuyệt đối từ 0x0000 đến 0x001F. Mỗi thanh ghi có thể chứa giá trị
dương từ 0 đến 255 hoặc các giá trị có dấu từ -128 đến 127 hoặc mã ASCII
của một ký tự nào đó…Các thanh ghi này được đặt tên theo thứ tự là R0 đến
R31. Chúng được chia thành 2 phần, phần 1 bao gồm các thanh ghi từ R0 đến
R15 và phần 2 là các thanh ghi R16 đến R31. Các thanh ghi này có các đặc
điểm sau:

 Được truy cập trực tiếp trong các instruction.


 Các toán tử, phép toán thực hiện trên các thanh ghi này chỉ cần 1
chu kỳ xung clock.

 Register File được kết nối trực tiếp với bộ xử lí trung tâm – CPU
của chip.

 Chúng là nguồn chứa các số hạng trong các phép toán và cũng là
đích chứa kết quả trả lại của phép toán.

Thanh ghi R0 là thanh ghi duy nhất được sử dụng trong instruction
LPM (Load Program Memory). Các thanh ghi R26, R27, R28, R29, R30 và
R31 ngoài chức năng thông thường còn được sử dụng như các con trỏ
(Pointer register) trong một số instruction truy xuất gián tiếp.
27

Hình VI ĐIỀU KHIỂN ATMEGA32.6: Register file.


Tóm lại 32 thanh ghi của AVR được xem là 1 phần của CPU, vì thế
chúng được CPU sử dụng trực tiếp và nhanh chóng, để gọi các thanh ghi này,
chúng ta không cần gọi địa chỉ mà chỉ cần gọi trực tiếp tên của chúng. RF
thường được sử dụng như các toán hạng (operand) của các phép toán trong
lúc lập trình.

Phần 2:

Là phần nằm ngay sau register file, phần này bao gồm 64 thanh ghi
được gọi là 64 thanh ghi nhập/xuất (64 I/O register) hay còn gọi là vùng nhớ
I/O (I/O Memory). Vùng nhớ I/O là cửa ngõ giao tiếp giữa CPU và thiết bị
ngoại vi. Tất cả các thanh ghi điều khiển, trạng thái…của thiết bị ngoại vi đều
nằm ở đây. Mỗi PORT liên quan đến 3 thanh ghi DDRx, PORTx và PINx, tất
cả 3 thanh ghi này đều nằm trong vùng nhớ I/O. Xa hơn, nếu muốn truy xuất
các thiết bị ngoại vi khác như Timer, chuyển đổi Analog/Digital, giao tiếp
USART…đều thực hiện thông qua việc điều khiển các thanh ghi trong vùng
nhớ này.

Vùng nhớ I/O có thể được truy cập như SRAM hay như các thanh ghi
I/O. Nếu sử dụng instruction truy xuất SRAM để truy xuất vùng nhớ này thì
28

địa chỉ của chúng được tính từ 0x0020 đến 0x005F. Nhưng nếu truy xuất như
các thanh ghi I/O thì địa chỉ của chúng được tính từ 0x0000 đến 0x003F.

Phần 3 :

RAM tĩnh, nội (internal SRAM), là vùng không gian cho chứa các biến
(tạm thời hoặc toàn cục) trong lúc thực thi chương trình, vùng này tương tự
các thanh RAM trong máy tính nhưng có dung lượng khá nhỏ (khoảng vài
KB, tùy thuộc vào loại chip).

Phần 4 :

RAM ngoại (external SRAM), các chip AVR cho phép người sử dụng
gắn thêm các bộ nhớ ngoài để chứa biến, vùng này thực chất chỉ tồn tại khi
nào người sử dụng gắn thêm bộ nhớ ngoài vào chip.

Phần 5 :

EEPROM (Electrically Ereasable Programmable ROM) là một phần quan


trọng của các chip AVR mới, vì là ROM nên bộ nhớ này không bị xóa ngay cả
khi không cung cấp nguồn nuôi cho chip, rất thích hợp cho các ứng dụng lưu
trữ dữ liệu. Như trong hình 1.4, phần bộ nhớ EEPROM được tách riêng và có
địa chỉ tính từ 0x0000.

 Hoạt động của AVR.


Hình 1.7 biểu diễn cấu trúc bên trong của 1 AVR. Bạn thấy rằng 32
thanh ghi trong Register File được kết nối trực tiếp với Arithmetic Logic Unit
- ALU (ALU cũng được xem là CPU của AVR) bằng 2 line, vì thế ALU có thể
truy xuất trực tiếp cùng lúc 2 thanh ghi RF chỉ trong 1 chu kỳ xung clock
(vùng được khoanh tròn màu đỏ trong hình 1.7).

Các instruction được chứa trong bộ nhớ chương trình Flash memory
dưới dạng các thanh ghi 16 bit. Bộ nhớ chương trình được truy cập trong mỗi
chu kỳ xung clock và 1 instruction chứa trong program memory sẽ được load
29

vào trong instruction register, instruction register tác động và lựa chọn
register file cũng như RAM cho ALU thực thi. Trong lúc thực thi chương
trình, địa chỉ của dòng lệnh đang thực thi được quyết định bởi một bộ đếm
chương trình – PC (Program counter). Đó chính là cách thức hoạt động của
AVR.

AVR có ưu điểm là hầu hết các instruction đều được thực thi trong 1
chu kỳ xung clock, vì vậy có thể nguồn clock lớn nhất cho AVR có thể nhỏ
hơn 1 số vi điều khiển khác như PIC nhưng thời gian thực thi vẫn nhanh hơn.

Hình VI ĐIỀU KHIỂN ATMEGA32.7: Cấu trúc bên trong AVR.


1.3. Các thanh ghi chức năng đặc biệt.
Bao gồm các thanh ghi dữ liệu và các thanh ghi điều khiển các cổng vào
ra. Chúng có thể truy nhập được bằng 2 cách:

 Bằng địa chỉ trực tiếp.


Ví dụ:

STR $3F, R11


30

hoặc: STR SREG.R11

 Hoặc có thể truy nhập gián tiếp chúng thông qua thanh ghi X, Y, Z.
Ví dụ :

LDI R28, 0x00

LDIR27, 0x5F
STD X, R11

Hai ví dụ này hoàn toàn tương đương, đều ghi dữ liệu vào thanh ghi SREG.

1.3.1. Status Register (SREG).


Nằm trong vùng nhớ I/O, thanh ghi SREG có địa chỉ I/O là 0x003F và địa
chỉ bộ nhớ là 0x005F (thường đây là vị trí cuối cùng của vùng nhớ I/O) là một
trong số các thanh ghi quan trọng nhất của AVR. Thanh ghi SREG chứa 8 bit
cờ (flag) chỉ trạng thái của bộ xử lí, tất cả các bit này đều bị xóa sau khi reset,
các bit này cũng có thể được đọc và ghi bởi chương trình. Chức năng của
từng bit được mô tả như trong hình 1.8.

Hình VI ĐIỀU KHIỂN ATMEGA32.8: Các bit trong thanh ghi SREG.
 C: Carry Flag - cờ nhớ (nếu phép toán có nhớ cờ sẽ được thiết lập).
 Z: Zero Flag - cờ zero (nếu kết quả phép toán bằng 0).
 N: Negative Flag (nếu kết quả của phép toán là âm).
 V: Two’s complement overflow indicator (cờ này được thiết lập khi
tràn số bù 2).
 V: For signed tests (S=N XOR V)S: N.
 H: Half Carry Flag (được sử dụng trong một số toán hạng sẽ được
chỉ rõ sau).
31

 T: Transfer bit used by BLD and BST instructions (được sử dụng


làm nơi trung gian trong các lệnh BLD, BST).
 I: Global Interrupt Enable/Disable Flag (đây là bit cho phép toàn cục
ngắt. Nếu bit này ở trang thái logic 0 thì không có một ngắt nào
được phục vụ).

1.3.2. SP (Stack Pointer).


Là một thanh ghi 16 bit nhưng cũng có thể được xem như hai thanh ghi
chức năng đặc biệt 8 bit. Có địa chỉ trong các thanh ghi chức năng đặc biệt là
$3E (Trong bộ nhớ RAM là $5E). Có nhiệm vụ trỏ tới vùng nhớ trong RAM
chứa ngăn xếp.

Hình VI ĐIỀU KHIỂN ATMEGA32.9: Các bit trong thanh ghi SP.
Khi chương trình phục vụ ngắt hoặc chương trình con thì con trỏ PC
được lưu vào ngăn xếp trong khi con trỏ ngăn xếp giảm hai vị trí. Và con trỏ
ngăn xếp sẽ giảm 1 khi thực hiện lệnh push. Ngược lại khi thực hiện lệnh POP
thì con trỏ ngăn xếp sẽ tăng 1 và khi thực hiện lệnh RET hoặc RETI thì con
trỏ ngăn xếp sẽ tăng 2. Như vậy con trỏ ngăn xếp cần được chương trình đặt
trước giá trị khởi tạo ngăn xếp trước khi một chương trình con được gọi hoặc
các ngắt được cho phép phục vụ. Và giá trị ngăn xếp ít nhất cũng phải lớn hơn
hoặc bằng 60H (0x60) vì 5FH trỏ lại là vùng các thanh ghi.
32

1.4. ADC (Analog to Digital Converter).

1.4.1. Nguyên lý chuyển đổi từ dữ liệu tương tự sang số (A - D).


Trong các ứng dụng đo lường và điều khiển bằng vi điều khiển bộ
chuyển đổi tương tự - số (ADC) là một thành phần rất quan trọng. Dữ liệu
trong thế giới của chúng ta là các dữ liệu tương tự (analog). Ví dụ nhiệt độ
không khí buổi sáng là 250C và buổi trưa là 32 0C, giữa hai mức giá trị này có
vô số các giá trị liên tục mà nhiệt độ phải “đi qua” để có thể đạt mức 32 0C từ
250C, đại lượng nhiệt độ như thế gọi là một đại lượng analog. Trong khi đó, rõ
ràng vi điều khiển là một thiết bị số (digital), các giá trị mà một vi điều khiển
có thể thao tác là các con số rời rạc vì thực chất chúng được tạo thành từ sự
kết hợp của hai mức 0 và 1. Ví dụ chúng ta muốn dùng một thanh ghi 8 bit
trong vi điều khiển để lưu lại các giá trị nhiệt độ từ 00C đến 2550C, như chúng
ta đã biết, một thanh ghi 8 bit có thể chứa tối đa 256 (2 8) giá trị nguyên từ 0
đến 255, như thế các mức nhiệt độ không nguyên như 28.123 0C sẽ không
được ghi lại. Nói cách khác, chúng ta đã “số hóa” (digitalize) một dữ liệu
analog thành một dữ liệu digital. Quá trình “số hóa” này thường được thực
hiện bởi một thiết bị gọi là “bộ chuyển đổi tương tự - số” hay đơn giản là
ADC (Analog to Digital Converter).

Có rất nhiều phương pháp chuyển đổi ADC. Phương pháp chuyển đổi
hay được sử dụng là phương pháp chuyển đổi trực tiếp (direct converting)
hoặc flash ADC. Các bộ chuyển đổi ADC theo phương pháp này được cấu
thành từ một dãy các bộ so sánh (như opamp), các bộ so sánh được mắc song
song và được kết nối trực tiếp với tín hiệu analog cần chuyển đổi. Một điện áp
tham chiếu (reference) và một mạch chia áp được sử dụng để tạo ra các mức
điện áp so sánh khác nhau cho mỗi bộ so sánh. Hình 1.10 mô tả một bộ
chuyển đổi flash ADC có 4 bộ so sánh, Vin là tín hiệu analog cần chuyển đổi
và giá trị sau chuyển đổi là các con số tạo thành từ sự kết hợp các mức nhị
phân trên các chân Vo. Trong hình 1.10, bạn thấy rằng do ảnh hưởng của
mạch chia áp (các điện trở mắc nối tiếp từ điện áp +15V đến ground), điện áp
33

trên chân âm (chân -) của các bộ so sánh sẽ khác nhau. Trong lúc chuyển đổi,
giả sử điện áp Vin lớn hơn điện áp “V-“ của bộ so sánh 1 (opamp ở phía thấp
nhất trong mạch) nhưng lại nhỏ hơn điện áp V- của các bộ so sánh khác, khi
đó ngõ Vo1 ở mức 1 và các ngõ Vo khác ở mức 0, chúng ta thu được một kết
quả số. Một cách tương tự, nếu tăng điện áp Vin ta thu được các tổ hợp số
khác nhau. Với mạch điện có 4 bộ so sánh như trong hình 1.10, sẽ có tất cả 5
trường hợp có thể xảy ra, hay nói theo cách khác điện áp analog Vin được
chia thành 5 mức số khác nhau. Tuy nhiên, chú ý là các ngõ Vo không phải là
các bit của tín hiệu số ngõ ra, chúng chỉ là đại diện để tổ hợp thành tín hiệu số
ngõ ra, và chúng ta không sử dụng được các bit Vo trực tiếp mà cần một bộ
giải mã (decoder).

Hình VI ĐIỀU KHIỂN ATMEGA32.10:Mạch flash ADC với 4 bộ so sánh.

Bảng 1. 5 Giá trị số ngõ ra sau khi giải mã.


34

Độ phân giải (resolution): như trong ví dụ trên, nếu mạch điện có 4 bộ


so sánh, ngõ ra digital sẽ có 5 mức giá trị. Tương tự nếu mạch điện có 7 bộ so
sánh thì sẽ có 8 mức giá trị có thể ở ngõ ra digital, khoảng cách giữa các mức
tín hiệu trong trường hợp 8 mức sẽ nhỏ hơn trường hợp 4 mức. Nói cách
khác, mạch chuyển đổi với 7 bộ so sánh có giá trị digital ngõ ra “mịn” hơn
khi chỉ có 4 bộ, độ “mịn” càng cao tức độ phân giải (resolution) càng lớn.
Khái niệm độ phân giải được dùng để chỉ số bit cần thiết để chứa hết các mức
giá trị digital ngõ ra. Trong trường hợp có 8 mức giá trị ngõ ra, chúng ta cần 3
bit nhị phân để mã hóa hết các giá trị này, vì thế mạch chuyển đổi ADC với 7
bộ so sánh sẽ có độ phân giải là 3 bit. Một cách tổng quát, nếu một mạch
chuyển đổi ADC có độ phân giải n bit thì sẽ có 2n mức giá trị có thể có ở ngõ
ra digital. Để tạo ra một mạch chuyển đổi flash ADC có độ phân giải n bit,
chúng ta cần đến 2n-1 bộ so sánh, giá trị này rất lớn khi thiết kế bộ chuyển đổi
ADC có độ phân giải cao, vì thế các bộ chuyển đổi flash ADC thường có độ
phân giải ít hơn 8 bit. Độ phân giải liên quan mật thiết đến chất lượng chuyển
đổi ADC, việc lựa chọn độ phân giải phải phù hợp với độ chính xác yêu cầu
và khả năng xử lý của bộ điều khiển. Trong hình 1.11 mô tả một ví dụ “số
hóa” một hàm sin analog thành dạng digital.

Hình VI ĐIỀU KHIỂN ATMEGA32.11: Tín hiệu analog và digital của hàm sin.
Điện áp tham chiếu (reference voltage): Cùng một bộ chuyển đổi
ADC nhưng có người muốn dùng cho các mức điện áp khác nhau, ví dụ
người A muốn chuyển đổi điện áp trong khoảng 0-1V trong khi người B muốn
dùng cho điện áp từ 0V đến 5V. Rõ ràng nếu hai người này dùng 2 bộ chuyển
35

đổi ADC đều có khả năng chuyển đổi đến điện áp 5V thì người A đang “phí
phạm” tính chính xác của thiết bị. Vấn đề sẽ được giải quyết bằng một đại
lượng gọi là điện áp tham chiếu - Vref (reference voltage). Điện áp tham
chiếu thường là giá trị điện áp lớn nhất mà bộ ADC có thể chuyển đổi. Trong
các bộ ADC, Vref thường là thông số được đặt bởi người dùng, nó là điện áp
lớn nhất mà thiết bị có thể chuyển đổi. Ví dụ, một bộ ADC 10 bit (độ phân
giải) có Vref=3V, nếu điện áp ở ngõ vào là 1V thì giá trị số thu được sau khi
chuyển đổi sẽ là: 1023x(1/3)=314. Trong đó 1023 là giá trị lớn nhất mà một
bộ ADC 10 bit có thể tạo ra (1023=210-1). Vì điện áp tham chiếu ảnh hưởng
đến độ chính xác của quá trình chuyển đổi, chúng ta cần tính toán để chọn 1
điện áp tham chiếu phù hợp, không được nhỏ hơn giá trị lớn nhất của input
nhưng cũng đừng quá lớn.

1.4.2. Chuyển đổi ADC trên AVR.


Chip AVR ATmega32 của Atmel có tích hợp sẵn các bộ chuyển đổi ADC
với độ phân giải 10 bit. Có tất cả 8 kênh đơn (các chân ADC0 đến ADC7), 16
tổ hợp chuyển đổi dạng so sánh, trong đó có 2 kênh so sánh có thể khuyếch
đại. Bộ chuyển đổi ADC trên AVR không hoạt động theo nguyên lý flash
ADC mà ADC trong AVR là loại chuyển đổi xấp xỉ lần lượt (successive
approximation ADC).
ADC trên AVR cần được “nuôi” bằng nguồn điện áp riêng ở chân AVCC,
giá trị điện áp cấp cho AVCC không được khác nguồn nuôi chip (VCC) quá
+/-0.3V. Nhiễu (noise) là vấn đề rất quan trọng khi sử dụng các bộ ADC, để
giảm thiểu sai số chuyển đổi do nhiễu, nguồn cấp cho ADC cần phải được
“lọc” (filter) kỹ càng. Một cách đơn giản để tạo nguồn AVCC là dùng một
mạch LC kết nối từ nguồn VCC của chip như minh họa trong hình 1.12, đây
là cách được gợi ý bởi nhà sản xuất AVR.
Điện áp tham chiếu cho ADC trên AVR có thể được tạo bởi 3 nguồn:
dùng điện áp tham chiếu nội 2.56V (cố định), dùng điện áp AVCC hoặc điện
áp ngoài đặt trên chân VREF. Một lần nữa, bạn cần chú ý đến nhiễu khi đặt
36

điện áp tham chiếu, nếu dùng điện áp ngoài đặt trên chân VREF thì điện áp
này phải được lọc thật tốt, nếu dùng điện áp tham chiếu nội 2.56V hoặc
AVCC thì chân VREF cần được nối với một tụ điện. Việc chọn điện áp tham
chiếu sẽ được đề cập chi tiết trong phần sử dụng ADC.

Các chân trên PORTA của chip ATmega32 được dùng cho bộ ADC, chân
PA0 tương ứng kênh ADC0 và chân PA7 tương ứng với kênh ADC7.

Hình VI ĐIỀU KHIỂN ATMEGA32.12: Tạo nguồn AVCC từ VCC.


1.5. Ngắt ngoài.

1.5.1. Ngắt trên AVR.


Interrupts, thường được gọi là ngắt, là một tín hiệu khẩn cấp gởi đến bộ
xử lí, yêu cầu bộ xử lí tạm ngừng tức khắc các hoạt động hiện tại để “nhảy”
đến một nơi khác thực hiện một nhiệm vụ khẩn cấp nào đó, nhiệm vụ này gọi
là trình phục vụ ngắt – ISR (Interrupt Service Routine). Sau khi kết thúc
nhiệm vụ trong ISR, bộ đếm chương trình sẽ được trả về giá trị trước đó để bộ
xử lí quay về thực hiện tiếp các nhiệm vụ còn dang dở. Như vậy, ngắt có mức
độ ưu tiên xử lí cao nhất, ngắt thường được dùng để xử lí các sự kiện bất ngờ
nhưng không tốn quá nhiều thời gian. Các tín hiệu dẫn đến ngắt có thể xuất
phát từ các thiết bị bên trong chip (ngắt báo bộ đếm timer/counter tràn, ngắt
báo quá trình gởi dữ liệu bằng RS232 kết thúc…) hay do các tác nhân bên
37

ngoài (ngắt báo có 1 button được nhấn, ngắt báo có 1 gói dữ liệu đã được
nhận…).

Hình VI ĐIỀU KHIỂN ATMEGA32.13: Ngắt.


Hình 1.13 minh họa cách tổ chức ngắt thông thường trong các chip
AVR. Số lượng ngắt trên mỗi dòng chip là khác nhau, ứng với mỗi ngắt sẽ có
vector ngắt, vector ngắt là các thanh ghi có địa chỉ cố định được định nghĩa
trước nằm trong phần đầu của bộ nhớ chương trình. Ví dụ vector ngắt ngoài 0
(external interrupt 0) của chip atmega8 có địa chỉ là 0x001 (theo datasheet từ
Atmel). Trong lúc chương trình chính đang thực thi, nếu có một sự thay đổi
dẫn đến ngắt xảy ra ở chân INT0 (chân 4), bộ đếm chương trình (Program
Counter) nhảy đến địa chỉ 0x009, giả sử ngay tại địa chỉ 0x001 chúng ta có
đặt 1 lệnh RJMP đến một trình phục vụ ngắt (IRS1 chẳng hạn), một lần nữa
bộ đếm chương trình nhảy đến IRS1 để thực thi trình phục vụ ngắt, kết thúc
ISR1, bộ đếm chương trình lại quay về vị trí trước đó trong chương trình
chính, quá trình ngắt kết thúc.
38

Bảng 1. 6 Các vector ngắt và Reset trên chip Atmega32.

1.5.2. Ngắt ngoài.


Là loại ngắt duy nhất độc lập với các thiết bị của chip, các ngắt khác
thường gắn với hoạt động của 1 thiết bị nào đó như Timer/Counter, giao tiếp
nối tiếp USART, chuyển đổi ADC…

Ngắt ngoài là cách rất hiệu quả để thực hiện giao tiếp giữa người dùng và
chip, có 3 thanh ghi liên quan đến ngắt ngoài đó là MCUCR, GICR và GIFR.
Cụ thể các thanh ghi được trình bày bên dưới.

Thanh ghi điều khiển MCU – MCUCR (MCU Control Register): là thanh
ghi xác lập chế độ ngắt cho ngắt ngoài. Thanh ghi MCUCR chứa các bits cho
phép chúng ta chọn 1 trong 4 MODE trên cho các ngắt ngoài. Hình 1.14 là
cấu trúc thanh ghi MCUCR được trích ra từ datasheet của chip atmega32.
39

Hình VI ĐIỀU KHIỂN ATMEGA32.14: Cấu trúc thanh ghi MCUCR.


MCUCR là một thanh ghi 8 bit nhưng đối với hoạt động ngắt ngoài,
chúng ta chỉ quan tâm đến 4 bit thấp của nó (4 bit cao dùng cho Power
manager và Sleep Mode). Bốn bit thấp là các bit Interrupt Sense Control
(ISC) trong đó 2 bit ISC11:ISC10 dùng cho INT1 và 2 bit ISC01:ISC00 dùng
cho INT0. Bảng 1.11 mô tả chức năng của các bit trên, đây là bảng “chân trị”
của 2 bit ISC11, ISC10. Bảng chân trị cho các bit ISC01, ISC00 hoàn toàn
tương tự.

Chức năng của các bit Sense Control: ví dụ bạn muốn set cho INT1 là
ngắt cạnh xuống (Falling Edge) trong khi INT0 là ngắt cạnh lên (Rising
Edge), hãy đặt dòng lệnh MCUCR=0x0B (0x0 = 00001011 nhị phân) trong
chương trình của bạn.

Bảng 1. 7 Chức năng của các bit ISC11 và ISC10 dùng cho INT1.

Thanh ghi điều khiển ngắt chung – GICR (General Interrupt Control
Register) (chú ý trên các chip AVR cũ, như các chip AT90Sxxxx, thanh ghi
này có tên là thanh ghi mặt nạ ngắt thông thường GIMSK) GICR cũng là 1
thanh ghi 8 bit nhưng chỉ có 2 bit cao (bit 6 và bit 7) là được sử dụng cho điều
khiển ngắt, cấu trúc thanh ghi như trong hình 1.15.
40

Hình VI ĐIỀU KHIỂN ATMEGA32.15: Thanh ghi điều khiển ngắt chung GICR.
Bit 7 – INT1 gọi là bit cho phép ngắt 1 (Interrupt Enable), set bit này bằng
1 nghĩa bạn cho phép ngắt INT1 hoạt động, tương tự, bit INT0 điều khiển
ngắt INT0.
Thanh ghi cờ ngắt chung – GIFR (General Interrupt Flag Register) có 2 bit
INTF1 và INTF0 là các bit trạng thái (hay bit cờ - Flag) của 2 ngắt INT1 và
INT0. Nếu có 1 sự kiện ngắt phù hợp xảy ra trên chân INT1, bit INTF1 được
tự động set bằng 1 (tương tự cho trường hợp của INTF0), chúng ta có thể sử
dụng các bit này để nhận ra các ngắt, tuy nhiên điều này là không cần thiết
nếu chúng ta cho phép ngắt tự động, vì vậy thanh ghi này thường không được
quan tâm khi lập trình ngắt ngoài. Cấu trúc thanh ghi GIFR được trình bày
trong hình 1.16.

Hình VI ĐIỀU KHIỂN ATMEGA32.16: Cấu trúc thanh ghi GIRF.


Sau khi đã xác lập các bit sẵn sàng cho các ngắt ngoài, việc sau cùng
chúng ta cần làm là set bit I, tức bit cho phép ngắt toàn cục, trong thanh ghi
trạng thái chung của chip (thanh ghi SREG). Một chú ý khác là vì các chân
PD2, PD3 là các chân ngắt nên bạn phải set các chân này là Input (set thanh
ghi DDRD). Quá trình thiết lập ngắt ngoài được trình bày trong hình 1.17:
41

Hình VI ĐIỀU KHIỂN ATMEGA32.17: Thiết lập ngắt ngoài.


1.6. Timer – Counter.

1.6.1. Tổng quan các bộ Timer/Counter trên chip ATmega32.


Timer/Counter là các module độc lập với CPU. Chức năng chính của các
bộ Timer/Counter là định thời (tạo ra một khoảng thời gian, đếm thời gian…)
và đếm sự kiện. Trên các chip AVR, các bộ Timer/Counter còn có thêm chức
năng tạo ra các xung điều rộng PWM (Pulse Width Modulation), ở một số
dòng AVR, một số Timer/Counter còn được dùng như các bộ canh chỉnh thời
gian (calibration) trong các ứng dụng thời gian thực. Các bộ Timer/Counter
được chia theo độ rộng thanh ghi chứa giá trị định thời hay giá trị đếm của
chúng, cụ thể trên chip Atmega32 có 2 bộ Timer 8 bit (Timer/Counter0 và
Timer/Counter2) và 1 bộ 16 bit (Timer/Counter1). Chế độ hoạt động và
phương pháp điều khiển của từng Timer/Counter cũng không hoàn toàn giống
nhau

Timer/Counter0: là một bộ định thời, đếm đơn giản với 8 bit. Gọi là đơn
giản vì bộ này chỉ có 1 chế độ hoạt động (mode) so với 5 chế độ của bộ
Timer/Counter1. Chế độ hoạt động của Timer/Counter0 thực chất có thể coi
như 2 chế độ nhỏ (và cũng là 2 chức năng cơ bản) đó là tạo ra một khoảng
thời gian và đếm sự kiện.
Timer/Counter1: là bộ định thời, đếm đa năng 16 bits. Bộ
Timer/Counter này có 5 chế độ hoạt động chính. Ngoài các chức năng thông
42

thường, Timer/Counter1 còn được dùng để tạo ra xung điều rộng PWM dùng
cho các mục đích điều khiển. Có thể tạo 2 tín hiệu PWM độc lập trên các
chân OC1A (chân 19) và OC1B (chân 18) bằng Timer/Counter1. Các bộ
Timer/Counter kiểu này được tích hợp thêm khá nhiều trong các chip AVR
sau này, ví dụ Atmega128 có 2 bộ, Atmega2561 có 4 bộ…
Timer/Counter2: tuy là một module 8 bit như Timer/Counter0 nhưng
Timer/Counter2 có đến 4 chế độ hoạt động như Timer/Counter1, ngoài ra nó
còn được sử dụng như một module canh chỉnh thời gian cho các ứng dụng
thời gian thực (chế độ asynchronous).

1.6.2. Sử dụng Timer/Counter.


Timer/Counter0:

Thanh ghi: có 4 thanh ghi được thiết kế riêng cho hoạt động và điều
khiển T/C0, đó là:

 TCNT0 (Timer/Counter Register): là 1 thanh ghi 8 bit chứa giá trị vận
hành của T/C0. Thanh ghi này cho phép bạn đọc và ghi giá trị một cách
trực tiếp.
 TCCR0 (Timer/Counter Control Register): là thanh ghi điều khiển hoạt
động của T/C0. Tuy là thanh ghi 8 bit nhưng thực chất chỉ có 3 bit có
tác dụng đó là CS00, CS01 và CS02.

Hình VI ĐIỀU KHIỂN ATMEGA32.18: Thanh ghi TCCR0 của T/C0.


• TIMSK (Timer/Counter Interrupt Mask Register): là thanh ghi mặt nạ
cho ngắt của tất cả các T/C, trong đó chỉ có bit TOIE0 tức bit số 0 (bit
đầu tiên) trong thanh ghi này là liên quan đến T/C0, bit này có tên là bit
cho phép ngắt khi có tràn ở T/C0. Tràn (Overflow) là hiện tượng xảy ra
43

khi bộ giá trị trong thanh ghi TCNT0 đã đạt đến MAX (255) và lại đếm
thêm 1 lần nữa.

Hình VI ĐIỀU KHIỂN ATMEGA32.19: Thanh ghi TIMSK của T/C0.

Khi bit TOIE0=1 và bit I trong thanh ghi trạng thái được set, nếu một
“tràn” xảy ra sẽ dẫn đến ngắt tràn.

 TIFR (Timer/Counter Interrupt Flag Register): là thanh ghi cờ nhớ cho


tất cả các bộ T/C. Trong thanh ghi này bit số 0, TOV0 là cờ chỉ thị ngắt
tràn của T/C0. Khi có ngắt tràn xảy ra, bit này tự động được set lên 1.
Thông thường trong điều khiển các T/C vai trò của thanh ghi TIFR
không quá quan trọng.

Timer/Counter1:

Timer/Counter1 là bộ T/C 16 bits, đa chức năng. Đây là bộ T/C rất lý


tưởng cho lập trình đo lường và điều khiển vì có độ phân giải cao (16 bits) và
có khả năng tạo xung điều rộng PWM (Pulse Width Modulation – thường
dùng để điều khiển động cơ).

Thanh ghi: có khá nhiều thanh ghi liên quan đến T/C1. Vì là T/C 16
bits trong khi độ rộng bộ nhớ dữ liệu của AVR là 8 bit nên đôi khi cần dùng
những cặp thanh ghi 8 bits tạo thành 1 thanh ghi 16 bit, 2 thanh ghi 8 bits sẽ
có tên kết thúc bằng các ký tự L và H trong đó L là thanh ghi chứa 8 bits thấp
(LOW) và H là thanh ghi chứa 8 bits cao (High) của giá trị 16 bits mà chúng
tạo thành.
44

1.7. USART.
Bộ USART của vi điều khiển ATMEGA32 có thể hoạt động như một bộ
truyền nhận song công, có nghĩa là hoạt động truyền và nhận có thể tiến hành
đồng thời (nó chứa các thanh ghi truyền, nhận riêng lẻ).

- Bộ phát tốc độ baud có thể tạo ra một số lớn tốc độ baud.


- Bộ nâng cao tốc độ baud tại tần số thạch anh thấp.
- Mỗi khung dữ liệu có thể có 5,6,7, 8 hoặc 9 bit dữ liệu và 1 hoặc 2
bit stop.
- Hỗ trợ bộ kiểm tra bit chẵn lẻ parity bằng phần cứng.
- Phát hiện trạng thái Overrun.
- Phát hiện khung truyền bị lỗi.
- Lọc nhiễu, phát hiện lỗi bit start.
- Cho phép ba ngắt riêng biệt là TX Complete, TX Data Register
Empty, RX Complete.

Trong truyền nhận bất đồng bộ hỗ trợ chức năng nhân đôi tốc độ.

1.7.1. Cờ và ngắt trong truyền nối tiếp.


Truyền USART có hai cờ là USART Data Register Empty (UDRE) và
Transmit Complete (TXC), cả cờ này có thể được dùng trong ngắt. Cờ UDRE
báo cho biết bộ đệm đã sẵn sàng nhận dữ liệu mới. Bit này lên mức 1 khi bộ
đệm truyền trong tình trạng trống (nhàn rỗi) và bị xóa về không khi bộ đệm
chứa dữ liệu. Khi ngắt UDRIE (Data Register empty Interrupt Enable) trong
thanh ghi UCSRA lên mức một thì xẩy ra ngắt (với điều kiện ngắt toàn cục
cho phép) UDRE bị xóa về không thông qua việc ghi lên thanh ghi UDR. Khi
ngắt điều khiển truyền dữ liệu được sử dụng, chương trình phục vụ ngắt được
thực hiện để ghi dữ liệu mới vào UDR. Có thể không dùng ngắt bằng cách
xóa bit UDRE để cấm ngắt.

Bit cờ TXC (Transmit Complete) được đặt mức một khi toàn bộ khung
dữ liệu trong thanh ghi dịch đã được dịch ra ngoài và không có dữ liệu mới
xuất hiện trong bộ đệm truyền. Bit cờ TXC tự động bị xóa khi chương trình
phục vụ ngắt được thực thi. Bit cờ TXC được sử dụng trong giao tiếp truyền
45

thông bán song công (như chuẩn RS485). Khi ngắt Transmit Complete cho
phép tức là bit TXCIE trong thanh ghi UCSRB được đặt lên mức một khi bit
TXC đặt lên mức một chương trình phục vụ ngắt được thực thi và cờ TXC tự
động bị xóa về 0.

1.7.2. Sơ đồ khối bộ USART.


* Tốc độ baud.

Tùy vào chế độ hoạt động mà tốc độ baud có thể được xác định như
trong bảng 1.8.

Bảng 1. 8 Cách xác định tốc độ baud.

- BAUD: tốc độ baud (bps).


- fosc : tần số thạch anh (Hz).
- UBRR giá trị của các bit UBRR11:0 trong hai thanh ghi UBRRH
và UBRRL .
46

Hình VI ĐIỀU KHIỂN ATMEGA32.20: Sơ đồ khối USART.


1.8. Giao tiếp TWI – I2C.

1.8.1. Nguyên lý truyền thông nối tiếp TWI và I2C.


TWI (Two-Wire Serial Interface) là một module truyền thông nối tiếp
đồng bộ trên các chip AVR dựa trên chuẩn truyền thông I 2C. I2C là viết tắt của
từ Inter-Integrated Circuit là một chuẩn truyền thông do hãng điện tử Philips
Semiconductor sáng lập và xây dựng thành chuẩn năm 1990. Phiên bản mới
nhất của I2C là V3.0 phát hành năm 2007. Về cơ bản TWI trong AVR hoàn
toàn tương thích I2C, do đó tìm hiểu TWI của AVR không chỉ giúp bạn giao
tiếp giữa các AVR với nhau mà có thể dùng TWI để điều khiển bất kỳ một
47

thiết bị nào theo chuẩn I2C (các chip nhớ, bộ chuyển đổi ADC, DCA, đồng hồ
thời gian thực…).

TWI (I2C) là một truyền thông nối tiếp đa chip chủ (tạm dịch của cụm từ
multi-master serial computer bus). Khái niệm “multi-master” được hiểu là
trong trên cùng một bus có thể có nhiều hơn một thiết bị làm Master, đồng
thời một Slave có thể trở thành một Master nếu nó có khả năng. Ví dụ trong
một mạng TWI của nhiều AVR kết nối với nhau, bất kỳ một AVR nào đều có
thể trở thành Master ở một thời điểm nào đó. Tuy nhiên nếu một mạng dùng
một AVR điều khiển các chip nhớ (như EEPROM AT24C1024 chẳng hạn) thì
khái niệm “multi-master” không tồn tại vì các chip nhớ được thiết kế sẵn là
Slave, không có khả năng trở thành master. TWI (I2C) được thực hiện trên 2
đường SDA (Serial DATA) và SCL (Serial Clock) trong đó SDA là đường
truyền/nhận dữ liệu và SCL là đường xung nhịp. Căn cứ theo chuẩn I2C, các
đường SDA và SCL trên các thiết bị có cấu hình “cực góp mở” (open-drain
hoặc open-collector), nghĩa là cần có các “điện trở kéo lên” (pull-up resistor)
cho các đường này. Ở trạng thái nghỉ (Idle), 2 chân SDA và SCL ở mức cao.
Hình 1.21 mô tả một mô hình mạng TWI (I2C) cơ bản.

Hình VI ĐIỀU KHIỂN ATMEGA32.21: Mạng TWI (I2C) với nhiều thiết bị và 2
điện trở kéo lên cho SDA, SCL.
48

Một số khái niệm và đặc điểm của TWI :

Master: là chip khởi động quá trình truyền nhận, phát đi địa chỉ của thiết bị
cần giao tiếp và tạo xung giữ nhịp trên đường SCL.

Slave: là chip có một địa chỉ cố định, được gọi bởi Master và phục vụ yêu cầu
từ Master.

SDA - Serial Data: là đường dữ liệu nối tiếp, tất cả các thông tin về địa chỉ
hay dữ liệu đều được truyền trên đường này theo thứ tự từng bit một. Chú ý là
trong chuẩn I2C, bit có trọng số lớn nhất (MSB) được truyền trước nhất, đặc
điểm này ngược lại với chuẩn UART.

SCL – Serial Clock: là đường giữ nhịp nối tiếp. TWI (I2C) là chuẩn truyền
thông nối tiếp đồng bộ, cần có 1 đường tạo xung giữ nhịp cho quá trình
truyền/nhận, cứ mỗi xung trên đường giữ nhịp SCL, một bit dữ liệu trên
đường SDA sẽ được lấy mẫu (sample). Dữ liệu nối tiếp trên đường SDA được
lấy mẫu khi đường SCL ở mức cao trong một chu kỳ giữ nhịp, vì thế đường
SDA không được đổi trạng thái khi SCL ở mức cao (trừ START và STOP
condition). Chân SDA có thể được đổi trạng thái khi SCL ở mức thấp.

Hình VI ĐIỀU KHIỂN ATMEGA32.22: Lấy mẫu dữ liệu nối tiếp.


49

START Condition - Điều kiện bắt đầu: từ trạng thái nghỉ, khi cả SDA và
SCL ở mức cao nếu Master muốn thực hiện một “cuộc gọi”, Master sẽ kéo
chân SDA xuống thấp trong khi SCL vẫn cao. Trạng thái này gọi là START
Condition (gọi tắt là S).

STOP Condition - Điều kiện kết thúc: sau khi thực hiện truyền/nhận dữ liệu,
nếu Master muốn kết thúc quá trình nó sẽ tạo ra một STOP condition. STOP
condition được Master thực hiện bằng cách kéo chân SDA lên cao khi đường
SCL đang ở mức cao. STOP condition chỉ được tạo ra sau khi địa chỉ hoặc dữ
liệu đã được truyền/nhận.

START – Bắt đầu lặp lại: khoảng giữa START và STOP condition là khoảng
bận của đường truyền, các Master khác không tác động được vào đường
truyền trong khoảng này. Trường hợp sau khi kết thúc truyền/nhận mà Master
không gởi STOP condition lại gởi thêm 1 START condition gọi là REPEAT
START. Khả năng này thường được dùng khi Master muốn lấy dữ liệu liên
tiếp từ các Slaves. Hình 1.23 mô tả các Master tạo ra START, STOP và
REPEAT START.

Hình VI ĐIỀU KHIỂN ATMEGA32.23: Master tạo ra START, STOP và REPEAT


START.

Address Packet Format – Định dạng gói địa chỉ: trên mạng TWI (I2C), tất
cả các thiết bị (chip) đều có thể là Master hay Slave. Mỗi thiết bị có một địa
chỉ cố định gọi là Device address. Khi một Master muốn giao tiếp với một
50

Slave nào đó, nó trước hết tạo ra một START condition và tiếp theo là gởi địa
chỉ Device address của Slave cần giao tiếp trên đường truyền, vì thế xuất hiện
khái niệm “gói địa chỉ” (Address Packet). Gói địa chỉ trong TWI (I2C) có
định dạng 9 bits trong đó 7 bit đầu (gọi là SLA, được gởi liền sau START
condition) chứa địa chỉ Slave, một bit READ/WRITE và một bit ACK-
Ackknowledge (xác nhận). Do bit địa chỉ có độ dài 7 bits nên về mặt lý
thuyết, trên 1 mạng TWI (I2C) có thể tồn tại tối đa 2^7=128 thiết bị có địa chỉ
riêng biệt. Tuy nhiên, có một số địa chỉ không được sử dụng như các địa chỉ
có định dạng 1111xxx (tức các địa chỉ lớn hơn hoặc bằng 120 không được
dùng). Riêng địa chỉ 0 được dùng cho “cuộc gọi chung” (General call). Bit
READ/WRITE (R/W) được truyền tiếp sau 7 bit địa chỉ là bit báo cho Slave
biết Master muốn “đọc” hay “ghi” vào Slave. Nếu bit này bằng 0 (gọi là W)
thì quá trình “Ghi” dữ liệu từ Master đến Slave được yêu cầu, nếu bit này
bằng 1 (gọi là R) thì Master muốn “đọc” dữ liệu từ Slave về. Tám bits trên
(SLA+R/W) được Master phát ra sau khi phát START condition, nếu một
Slave trên mạng nhận ra rằng địa chỉ mà Master yêu cầu trùng khớp với
Device address của chính mình, nó sẽ “đáp trả” lại Master bằng cách phát ra 1
tín hiệu “xác nhận” ACK bằng cách kéo chân SDA xuống thấp trong xung thứ
9. Ngược lại, nếu không có Slave đáp ứng lại, chân SDA vẫn ở mức cao trong
xung giữ nhịp thứ 9 thì gọi là tín hiệu “không xác nhận” – NOT ACK, lúc này
Master cần có những ứng xử phù hợp tùy theo mỗi trường hợp cụ thể, ví dụ
Master có thể gởi STOP condition và sau đó phát lại địa chỉ Slave khác…Như
vậy, trong 9 bit của gói địa chỉ thì chỉ có 8 bit được gởi bởi Master, bit còn lại
là do Slave. Ví dụ Master muốn yêu cầu “đọc” dữ liệu từ Slave có địa chỉ 43,
nó cần phát đi một byte như sau trên đường truyền: (43<<1)+1, trong đó
(43<<1) là dịch số 43 về bên trái 1 vị trí vì 7 bit địa chỉ nằm ở các vị trí cao
trong gói địa chỉ, sau đó cộng giá trị này với “1” tức là quá trình “đọc” được
yêu cầu.
51

Hình VI ĐIỀU KHIỂN ATMEGA32.24: Định dạng gói địa chỉ.

General call – Cuộc gọi chung: khi Master phát đi gói địa chỉ có dạng 0
(thực chất là 0+W) tức nó muốn thực hiện một cuộc gọi chung đến tất cả các
Slave. Tất nhiên, cho phép hay không cho phép cuộc gọi chung là do Slave
quyết định. Nếu các Slave được cài đặt cho phép cuộc gọi chung, chúng sẽ
đáp lại Master bằng ACK. Cuộc gọi chung thường xảy ra khi Master muốn
gởi dữ liệu chung đến các Slaves. Chú ý là cuộc gọi chung có dạng 0+R là vô
nghĩa vì không thể có chuyện Master nhận dữ liệu từ tất cả các Slave cùng
thời điểm.

Data Packet Format – Định dạng gói dữ liệu: sau khi địa chỉ đã được phát
đi, Slave đã đáp lại Master bằng ACK thì quá trình truyền/nhận dữ liệu sẽ
diễn ra giữa cặp Master/Slave này. Tùy vào bit R/W trong gói địa chỉ, dữ liệu
có thể được truyền theo hướng từ Master đến Slave hay từ Slave đến Master.
Dù di chuyển theo hướng nào, gói dữ liệu luôn bao gồm 9 bits trong đó 8 bits
đầu là dữ liệu và 1 bit cuối là bit ACK. Tám bits dữ liệu do thiết bị phát gởi và
bit ACK do thiết bị nhận tạo ra. Ví dụ khi Master thực hiện quá trình gởi dữ
liệu đến Slave, nó sẽ phát ra 8 bits dữ liệu, Slave nhận và phát lại ACK (kéo
SDA xuống 0 ở xung thứ 9), sau đó Master sẽ quyết định gợi tiếp byte dữ liệu
khác hay không. Nếu Slave phát tín hiệu NOT ACK (không tác động SDA ở
xung thứ 9) sau khi nhận dữ liệu thì Master sẽ kết thúc quá trình gởi bằng
52

cách phát đi STOP condition. Hình 1.25 mô tả định dạng gói dữ liệu trong
TWI (I2C).

Hình VI ĐIỀU KHIỂN ATMEGA32.25: Định dạng dữ liệu trong TWI (I2C).

Phối hợp gói địa chỉ và dữ liệu: một quá trình truyền/nhận TWI (I2C)
thường được bắt đầu từ Master, Master phát đi một START condition sau đó
gởi gói địa chỉ SLA+R/W trên đường truyền. Tiếp theo nếu có một Slave đáp
ứng lại, dữ liệu có thể truyền/nhận liên tiếp trên đường truyền (1 hoặc nhiều
byte liên tiếp). Khung truyền thông thường được mô tả như hình 1.26.

Hình VI ĐIỀU KHIỂN ATMEGA32.26: Phối hợp gói địa chỉ và dữ liệu.

Multi-Master Bus – Đường truyền đa chip chủ: như đã trình bày ở trên,
TWI (I2C) là chuẩn truyền thông đa chip chủ, nghĩa là tại một thời điểm có
thể có nhiều hơn 1 chip làm Master nếu các chip này phát ra START
condition cùng lúc. Nếu các Master có cùng yêu cầu và thao tác đối với Slave
thì chúng có thể “cùng tồn tại” và quá trình truyền/nhận có thể thành công.
53

Tuy nhiên, trong đa số trường hợp sẽ có một số Master bị “thất lạc” (lost).
Một Master bị lost khi nó truyền/nhận 1 mức cao trên SDA trong khi các
Master khác truyền/nhận 1 mức thấp.

1.8.2. TWI trên AVR.

Thanh ghi:

TWI trên AVR được vận hành bởi 5 thanh ghi bao gồm thanh ghi tốc độ
giữ nhịp TWBR, thanh ghi điều khiển TWCR, thanh ghi trạng thái TWSR,
thanh ghi địa chỉ TWAR và thanh ghi dữ liệu TWDR.

- TWBR (TWI Bit Rate Register): là 1 thanh ghi 8 bit quy định tốc độ
phát xung giữ nhịp trên đường SCL của chip Master.

Hình VI ĐIỀU KHIỂN ATMEGA32.27: Thanh ghi TWBR.

Tốc độ phát xung giữ nhịp được tính theo công thức:

Trong đó CPU Clock frequency là tần số hoạt động chính của AVR,
TWBR là giá trị thanh ghi TWBR và TWPS là giá trị của 2 bits TWPS1 và
TWPS0 nằm trong thanh thi trạng thái TWSR. Hai bits này được gọi là bit
prescaler, thông thường người ta hay set TWPS1:0 =00 để chọn Prescaler là 1
(40=1). Bảng 1.9 tóm tắt tốc độ xung giữ nhịp tạo ra trên SCL đối với các giá
trị của tham số.
54

Bảng 1. 9 Tốc độ xung giữ nhịp tham khảo.

- TWCR (TWI Control Register): là thanh ghi 8 bit điều khiển hoạt
động của TWI.

Hình VI ĐIỀU KHIỂN ATMEGA32.28: Thanh ghi TWCR.

Bit 7- TWINT (TWI Interrupt Flag): là một cờ báo rất quan trọng. TWINT
được tự động set lên 1 khi TWI kết thúc một quá trình bất kỳ nào đó (như
phát/nhận START, phát nhận địa chỉ…). Chú ý là bit này không tự động được
xóa bởi phần cứng như các cờ báo trong các module khác. Vì thế, khi lập
trình điều khiển TWI chúng ta luôn phải xóa TWINT trước khi muốn thực
hiện một quá trình nào đó. Một điểm quan trọng cần lưu ý là bit TWINT được
xóa khi chúng ta viết giá trị 1 vào nó. Trong khi lập trình cho TWI, chúng ta
thường xóa TWINT bằng cách viết 1 vào nó, sau đó liên tục kiểm tra TWINT,
nếu bit này được set lên 1 thì quá trình đã hoàn thành.
55

Bit 6 – TWEA (TWI Enable Acknowledge Bit): tạm hiểu là bit kích hoạt tín
hiệu xác nhận. Đối với chip Slave, nếu bit này được set thì tín hiệu xác nhận
ACK sẽ được gởi trong các trường hợp sau: địa chỉ do Master phát ra trùng
khớp với địa chỉ của Slave; một cuộc gọi chung đang xảy ra và Slave này cho
phép cuộc gọi chung; dữ liệu đã được Slave nhận từ Master. Như thế, khi set
một chip ở chế độ Slave, chúng ta cần set bit này để nó có thể đáp ứng lại
Master bất cứ khi nào được gọi. Đối với chip Master, tín hiệu ACK chỉ được
phát trong 1 trường hợp duy nhất đó là khi Master nhận dữ liệu từ Slave,
Master phát ACK để báo cho Slave là mình đã nhận được và muốn tiếp tục
nhận từ Slave.

Bit 5 – TWSTA (TWI START Condition Bit): là bit tạo START condition.
Khi một chip muốn trở thành Master để thực hiện 1 cuộc gọi, bit này cần
được set và một START condition được tạo ra trên đường truyền nếu đường
truyền đang rảnh. Nếu đường truyền không rảnh, TWI sẽ chờ cho đến khi nó
rảnh (nhận ra 1 STOP condition) và tiếp tục gởi START condition. Chú ý là
bit này cần được xóa bởi phần mềm sau khi START condition đã được gởi
(viết 0 vào bit này để xóa nó).

Bit 4 – TWSTO (TWI STOP Condition Bit): là bit tạo STOP condition cho
TWI. Khi Master muốn kết thúc một cuộc gọi, nó sẽ phát STOP condition
bằng cách viết giá trị 1 vào bit TWSTO. Slave cũng có thể tác động vào bit
này, nếu một cuộc gọi bị lỗi, viết 1 vào TWSTO trên Slave sẽ reset đường
truyền về trạng thái rảnh ban đầu.

Bit 3 – TWWC (TWI Write Collision Flag): khi cờ TWINT đang ở mức
thấp tức TWI đang bận, nếu chúng ta viết dữ liệu vào thanh ghi dữ liệu
(TWDR) thì một lỗi xảy ra, khi đó bit TWWC tự động được set lên 1. Vì thế,
trong quá trình truyền dữ liệu, bit TWINT cần được giữ mức cao khi ghi dữ
liệu vào thanh ghi TWDR và sau đó xóa khi dữ liệu đã sẵn sàng.
56

Bit 2 – TWEN (TWI Enable Bit): bit kích hoạt TWI trên AVR, khi TWEN
được set lên 1, TWI sẵn sàng hoạt động.

Bit 1 – Reserve: không sử dụng.

Bit 0 – TWIE (TWI Interrupt Enable Bit): bit cho phép ngắt TWI, khi bit
này được set bằng 1 đồng thời bit I trong thanh ghi trạng thái chung được set,
một ngắt TWI xảy ra khi bit TWINT được set bởi phần cứng. Ngắt TWI có
thể xảy ra sau bất kỳ hoạt động nào liên quan đến TWI. Do đó cần sử dụng
ngắt hợp lý. Thông thường, ngắt chỉ được sử dụng cho Slave, đối với Master
ngắt không cần thiết vì Master chủ động khởi động một cuộc gọi.

Một điều cần chú ý là các bit trong thanh ghi TWCR không cần được
set cùng lúc, tùy vào từng giai đoạn trong quá trình giao tiếp TWI các bit có
thể được set riêng lẻ.

- TWSR (TWI Status Register): là 1 thanh ghi 8 bit trong đó có 5 bit


chứa code trạng thái của TWI và 2 bit chọn prescaler.

Hình VI ĐIỀU KHIỂN ATMEGA32.29: Thanh ghi TWSR.

Có rất nhiều bước, nhiều tình huống xảy ra khi giao tiếp bằng TWI cho cả
Master và Slave. Ứng với mỗi trường hợp TWI sẽ tạo ra 1 code trong thanh
ghi TWSR. Lập trình cho TWI cần xét code trong 5 bit cao của thanh ghi
TWSR và đưa ra các ứng xử hợp lý ứng với từng code.

- TWDR (TWI Data Register): là thanh ghi dữ liệu chính của TWI.
Trong quá trình nhận, dữ liệu nhận về sẽ được lưu trong TWDR. Trong quá
trình gởi, dữ liệu chứa trong TWDR sẽ được chuyển ra đường SDA.
57

- TWAR (TWI Address Register): là thanh ghi chứa device address của
chip Slave. Cấu trúc thanh ghi được trình bày trong hình 1.30.

Hình VI ĐIỀU KHIỂN ATMEGA32.30: Thanh ghi TWAR.

Nhớ lại địa chỉ Slave được tạo thành từ 7 bits, trên thanh ghi TWAR 7
bits địa chỉ này nằm ở 7 vị trí cao. Trước khi sử dụng TWI như Slave, chúng
ta phải gán địa chỉ cho chip, việc viết địa chỉ thường được thực hiện bằng lệnh
TWAR = (Device_address<<1)+TWGCE. Trong đó TWGCE (TWI General
Call Enable) là bit cho phép cuộc gọi chung. Như đề cập bên trên, Slave có
quyền cho phép Master thực hiện cuộc gọi chung với nó hay không. Nếu
TWGCE=1, Slave sẽ đáp ứng lại cuộc gọi chung nếu có, nếu TWGCE=0 thì
Slave sẽ bỏ qua cuộc gọi chung.

Hoạt động của TWI:

TWI trên AVR được gọi là byte-oriented (tạm dịch là hướng byte) và
interrupt-based (dựa trên ngắt). Bất kỳ một sự kiện nào trong quá trình
truyền/nhận TWI cũng có thể gây ra 1 ngắt TWI. TWI trên AVR vì thế hoạt
động tương đối độc lập với chip. Tuy nhiên, cần khai thác ngắt trên AVR một
cách hợp lý. Ví dụ, đối với Master, chúng ta không cần sử dụng ngắt vì chip
này hoàn toàn chủ động trong việc truyền và nhận. Riêng với Slave, sử dụng
ngắt để tránh bỏ lỡ các cuộc gọi là cần thiết.

Tất cả các AVR trên mạng TWI đều có thể là Master hay Slave, cả
Master và Slave đều có thể truyền và nhận dữ liệu. Vì thế, có tất cả 4 mode
trong hoạt động của TWI trên AVR gồm: Master Transmitter (chip chủ
truyền), Master Receiver (chip chủ nhận), Slave Reicever (chip tớ nhận) và
58

Slave Transmitter (chip tớ truyền).


* Qui ước một số ký hiệu thường dùng:

- S: START condition – điều kiện bắt đầu.


- Rs: REPEAT START – bắt đầu lặp lại.
- R: READ Bit, bit này bằng 1 được gởi kèm với gói địa chỉ.
- W: WRITE Bit, bit này mang giá trị 0, gởi kèm gói địa chỉ.
- ACK: Ackowledge, bit xác nhận, chân SDA được kéo xuống 0 ở
xung thứ 9.
- NACK: Not Acknowledge, không xác nhận, SDA ở mức cao ở bit
thứ 9.
- Data: 8 bits dữ liệu.
- P: STOP condition – điều kiện kết thúc.
- SLA: Slave address, địa chỉ của Slave cần giao tiếp.

Master Transmitter mode – Master truyền dữ liệu.

Trong chế độ này, Master truyền 1 hoặc một số byte dữ liệu đến một hoặc
các Slave. Để bắt đầu, Master tạo ra một START condition trên đường SDA,
nếu đường truyền đang rảnh, Master sẽ tiếp tục phát đi địa chỉ của Slave cần
giao tiếp cùng với bit W (ghi) theo định dạng như sau: SLA+W. Nếu Slave
đáp lại bằng một ACK trong xung giữ nhịp thứ 9, Master sẽ tiếp tục gởi 1
hoặc liên tiếp các byte dữ liệu trên SDA. Cứ sau mỗi byte dữ liệu, Master sẽ
kiểm tra ACK từ Slave. Nếu Slave gởi một NACK hoặc Master không muốn
gởi thêm dữ liệu đến Slave nó sẽ phát đi một STOP condition hoặc một
REPEAT START (Rs). Nếu STOP được phát, cuộc gọi kết thúc, nếu Rs được
phát, một cuộc gọi mới bắt đầu, sau Rs là địa chỉ của Slave mới…Đó là về
mặt lý thuyết, trên thực tế làm sao để kiểm tra một START condition có được
gởi chưa? Làm sao biết có nhận được ACK sau khi phát địa chỉ hoặc dữ liệu?
Tất cả được TWI mã hóa thành các code chứa trong thanh ghi TWSR (chỉ 5
bit cao). Chúng ta chỉ thanh ghi này và đối chiếu với bảng code quy định sẵn
để biết trạng thái đường truyền và đưa ra quyết định tiếp theo. Hình 1.31 mô
59

tả một quá trình Master truyền dữ liệu, các khả năng có thể xảy ra và giá trị
tương ứng của thanh ghi TWSR.

Hình VI ĐIỀU KHIỂN ATMEGA32.31: Quá trình Master truyền dữ liệu.

Từ hình 1.31, chúng ta nhận thấy khi Master truyền dữ liệu, dãy code 0x08
-> 0x18 -> 0x28 ->… -> 0x28 (-> 0x30) là dãy code thành công nhất. Code
0x08 báo rằng START codition được truyền thành công, code 0x18 báo địa
chỉ truyền thành công và đã có Slave xác nhận bằng ACK, code 0x28 tức dữ
liệu được Master truyền thành công và Slave đã nhận được, báo ACK lại cho
Master, code 0x30 tức dữ liệu đã được truyền nhưng Slave không xác nhận
lại, lúc này Master có thể phát đi một STOP codition sau code 0x30. Ngoài ra
còn một số code khác tương ứng với các trường hợp khác như gởi địa chỉ thất
bại (code 0x20), Master bị lost (code 0x38)…Đối với mỗi loại ứng dụng, cách
“hành xử” sẽ khác nhau đối với các trường hợp thất bại này.

Master Receiver mode – Master nhận dữ liệu.


60

Trong chế độ này, Master nhận một hoặc một số byte dữ liệu từ một Slave.
Để bắt đầu, Master tạo ra một START condition trên đường SDA, nếu đường
truyền đang rảnh, Master sẽ tiếp tục phát đi địa chỉ của Slave cần giao tiếp
cùng với bit R (đọc) theo định dạng như sau: SLA+R. Nếu Slave đáp lại bằng
một ACK trong xung giữ nhịp thứ 9, Master sẽ bắt đầu sample dữ liệu trên
SDA. Cứ sau mỗi byte dữ liệu, nếu Master muốn nhận tiếp byte khác nó phải
phát ra 1 ACK ở xung thứ 9 báo cho Slave. Khi Master muốn kết thúc quá
trình nhận nó sẽ phát một NOT ACK sau khi nhận dữ liệu, liền sau đó Master
phát STOP để kết thúc cuộc gọi hoặc phát đi một REPEAT START nếu nó
muốn tiếp tục gọi các Slaves khác. Hình 1.32 mô tả một quá trình Master
nhận dữ liệu, các khả năng có thể xảy ra và giá trị code tương ứng của thanh
ghi TWSR.

Từ hình 1.32, trong quá trình Master nhận dữ liệu, dãy code 0x08 -> 0x40
-> 0x50 ->… -> 0x58 là dãy code thành công nhất. Code 0x08 báo rằng
START codition được truyền thành công, code 0x40 báo địa chỉ + R đã được
truyền thành công và đã có Slave xác nhận bằng ACK, code 0x50 báo dữ liệu
được Master nhận thành công và Master cũng đã phát một ACK bit sau khi
nhận, code 0x58 xảy ra khi Master nhận dữ liệu thành công nhưng nó không
phát ACK mà phát NOT ACK, báo cho Slave rằng Master không muốn nhận
thêm dữ liệu, tiếp theo Master sẽ phát một STOP condition hoặc một
REPEAT START. Các trường hợp khác chúng ta không khảo sát.
61

Hình VI ĐIỀU KHIỂN ATMEGA32.32: Quá trình Master nhận dữ liệu.

Slave Receiver mode – Slave nhận dữ liệu.

Hình 1.33 mô tả một quá trình Slave nhận dữ liệu, các khả năng có thể
xảy ra và giá trị code tương ứng của thanh ghi TWSR. Chế độ Slave nhận dữ
liệu xảy ra khi Master thực hiện một cuộc gọi phát dữ liệu (SLA+W). Như
quan sát trong hình 1.33, Slave chỉ nhận ra cuộc gọi này khi địa chỉ của nó
trùng với địa chỉ của Master (Own address mode) hoặc khi Master thực hiện
một cuộc gọi chung. Khi đó, bit TWINT của Slave sẽ được set lên 1. Nếu
Slave cho phép ngắt TWI (bit TWIE trong thanh ghi TWCR được set từ lúc
đầu) thì một ngắt xảy ra báo có một sự kiện TWI. Nếu code trong thanh ghi
TWSR là 0x60 thì một cuộc gọi địa chỉ riêng được yêu cầu và Slave cũng đã
đáp ứng lại Master bằng một ACK, Slave sau đó bắt đầu nhận dữ liệu từ
đường SDA. Cứ sau một byte dữ liệu Slave phải xác nhận một ACK nếu nó
còn muốn tiếp tục nhận. Nếu vì một lý do nào đó mà Slave không thể tiếp tục
62

nhận nó có thể phát một NOT ACK sau một byte dữ liệu. Cuộc gọi kết thúc
khi Slave nhận được STOP condition, tương ứng code 0xA0. Cuộc gọi chung
cũng diễn ra hoàn toàn tương tự cuộc gọi địa chỉ riêng nhưng code có giá trị
khác. Khi viết chương trình cho Slave trong chế độ nhận dữ liệu, chúng ta cần
xét cả 2 trường hợp cuộc gọi địa chỉ riêng và cuộc gọi chung.

Hình VI ĐIỀU KHIỂN ATMEGA32.33: Slave nhận dữ liệu.

Slave Transmitter mode – Slave truyền dữ liệu.

Đây là chế độ cuối cùng trong 4 chế độ của AVR TWI. Hình 1.34 mô tả
một quá trình Slave truyền dữ liệu, các khả năng có thể xảy ra và giá trị code
tương ứng của thanh ghi TWSR. Chế độ Slave phát dữ liệu xảy ra khi Master
muốn nhận dữ liệu từ Slave, Master thực hiện một cuộc gọi nhận dữ liệu
(SLA+R). Như quan sát trong hình 1.34, Slave chỉ nhận ra cuộc gọi này khi
63

địa chỉ của nó trùng với địa chỉ của Master (Own address mode). Khi đó, bit
TWINT của Slave sẽ được set lên 1. Nếu Slave đáp lại bằng một ACK ở xung
nhịp thứ 9, code trong thanh ghi TWSR sẽ là 0xA8, Slave sau đó bắt đầu phát
dữ liệu lên đường SDA. Cứ sau mỗi byte dữ liệu, Master sẽ xác nhận một
ACK nếu nó còn muốn tiếp tục nhận, code 0xB8 sẽ xuất hiện trong trường
hợp này. Nếu Master không muốn tiếp tục nhận dữ liệu từ Slave, một NOT
ACK sẽ được phát và code 0xC0 xuất hiện, Slave kết thúc quá trình phát dữ
liệu. Một trường hợp đặc biệt khi bit TWEA (bit ACK) trong thanh ghi
TWCR của Slave được reset về 0 trước khi Slave truyền dữ liệu, trường hợp
Slave muốn báo rằng nó đã hết dữ liệu để truyền, byte tiếp theo cũng là byte
cuối cùng. Sau khi Master nhận byte này, nó có thể xác nhận 1 ACK cho
Slave (vì thật ra Master không hề biết Slave đang truyền byte cuối), code trên
Slave trong trường hợp này là 0xC8 và Slave sẽ tự hết thúc quá trình truyền
mà không cần chờ Master. Khi lập trình cho Slave trong chế độ phát, cần phải
có sự “thỏa hiệp” với Master trước để tránh code 0xC8 vì code này không có
nhiều ý nghĩa.

Kỹ thuật chính dùng cho Master khi truyền hay nhận cuộc gọi là hỏi
vòng và chờ (polling and waiting). Ứng với mỗi code nhận về từ thanh ghi
TWSR (hay ứng với mỗi trạng thái của cuộc gọi) mà Master set các bit tương
ứng trong thanh ghi điều khiển TWCR và sau đó chờ bit TWINT được set
(quá trình kết thúc) để tiếp tục đọc và xét code TWSR. Quá trình chờ và xét
này lặp lại cho đến khi Master kết thúc cuộc gọi bằng STOP condition. Tuy
nhiên Slave thì khác, Slave không chủ động thực hiện cuộc gọi mà nó phải
chờ yêu cầu từ Master để phục vụ. Vì thế, nếu dùng “hỏi vòng” cho Slave thì
sẽ tốn thời gian chờ vô ích và đôi khi còn bỏ lỡ các cuộc gọi. Đối với Slave,
ngắt là phương pháp bắt cuộc gọi tối ưu nhất.
64

Hình VI ĐIỀU KHIỂN ATMEGA32.34: Slave nhận dữ liệu.


65

CHƯƠNG 2: CƠ SỞ LÝ THUYẾT XÂY DỰNG MÔ HÌNH

2.1. Tổng quan về xử lý ảnh.

2.1.1. Khái niệm xử lý ảnh.


Xử lý ảnh là một trong những mảng quan trọng nhất trong kỹ thuật thị
giác máy tính, là tiền đề cho nhiều nghiên cứu thuộc lĩnh vực này. Hai nhiệm
vụ cơ bản của quá trình xử lý ảnh là nâng cao chất lượng thông tin hình ảnh
và xử lý số liệu cung cấp cho các quá trình khác trong đó có việc ứng dụng thị
giác vào điều khiển.
Con người thu nhận thông tin qua các giác quan trong đó thị giác đóng vai
trò quan trọng nhất. Sự phát triển nhanh của phần cứng máy tính, xử lý ảnh và
đồ hoạ đã phát triển mạnh mẽ và ngày càng có nhiều ứng dụng trong cuộc
sống. Xử lý ảnh đóng một vai trò quan trọng trong tương tác người máy.
Quá trình xử lý nhận dạng ảnh là một quá trình thao tác nhằm
biến đổi một ảnh đầu vào để cho ra một kết quả mong muốn. Kết quả đầu ra
của một quá trình xử lý ảnh có thể là một ảnh "tốt hơn" hoặc một kết luận.

Hình CƠ SỞ LÝ THUYẾT XÂY DỰNG MÔ HÌNH.35: Sơ đồ quá trình xử lý ảnh.


2.1.2. Các bước cơ bản trong xử lý ảnh.
Quá trình xử lý một ảnh đầu vào nhằm thu được một ảnh đầu ra mong
muốn thường phải trải qua rất nhiều bước khác nhau. Các bước cơ bản của
một quá trình xử lý ảnh được thể hiện thông qua hình sau:
66

Hình CƠ SỞ LÝ THUYẾT XÂY DỰNG MÔ HÌNH.36: Các bước cơ bản trong xử lý


ảnh
Dựa vào sơ đồ trên, ta dễ dàng nhận thấy việc xử lý ảnh thông qua 5 bước
chính:
- Thu nhận ảnh đầu vào: Đây là bước đầu tiên trong quá trình xử lý ảnh.
Thực hiện điều này, ta cần có bộ thu ảnh, bộ thu ảnh ở đây có thể là máy chụp
ảnh đơn sắc hay màu, máy quét ảnh, máy quay... Để lấy ra các bức ảnh cần
thiết phục vụ cho quá trình xử lý ảnh.
- Tiền xử lý: Ảnh sau khi thu được từ các thiết bị cần được xử lý trước
khi đưa vào phục vụ cho quá trình trích chọn đặc điểm. Quá trình cải thiện về
độ tương phản, khử nhiễu, khôi phục ảnh, nắn chỉnh hình học… Nhằm tăng
chất lượng ảnh và giảm sai số cho việc phân tích bức ảnh sau này.
- Trích chọn đặc điểm: Bức ảnh thu được bao gồm nhiều vùng và thành
phần. Trong khi đó ta chỉ cần lấy ra những vùng nhất định để xử lý và lấy ra
kết quả mong muốn. Ví dụ: trích ra vùng chứa biển số xe trong một bức ảnh.
Điều này làm giúp cho việc xử lý ảnh được nhanh hơn, loại bỏ những phần dư
thừa không cần thiết., bức ảnh sẽ được thu gọn tối ưu.
- Hậu xử lý: Sau khi có được ảnh tối ưu cần thiết, ảnh sẽ được qua các
quá trình chuyển đổi.
- So sánh, đối chiếu và kết luận: Đây là quá trình quan trọng nhất. Ảnh sẽ
được so sánh, đối chiếu với ảnh mẫu trong trường hợp có mẫu so sánh hoặc
dùng phương pháp nội suy đối với trường hợp không có mẫu sẵn để đưa ra
kết luận hay một kết quả nào đó trong bức ảnh đó.
67

2.2. Bộ thư viện OpenCV.

2.2.1. Giới thiệu về bộ thư viện OpenCV.


Có rất nhiều các thư viện thị giác máy mã nguồn mở (intel OpenCV,
CMVIsion, ImLIb3D, Imalab…) mỗi thư viện có một nét riêng của nó mà
chúng ta có thể khai thác. Ở đây nhóm lựa chọn bộ thư viện OpenCV bởi tính
phổ biến và những khả năng chúng có thể đáp ứng.

Thư viện OpenCV là gì: OpenCV là viết tắt của Open Source
Computer Vision, là một thư viện mở gồm các hàm được xây dựng phục vụ
cho việc xử lý thị giác máy thời gian thực (Real time computer vision). Các
thuật toán xử lý ảnh thông thường lẫn cao cấp đều được tối ưu hóa bởi các
nhà phát triển thư viện thành các hàm đơn giản và rất dễ sử dụng. OpenCV hỗ
trợ hai ngôn ngữ chính: C/C++ và python. OpenCV là một thư viện thị giác
máy tính mã nguồn mở của Intel nó có thê làm đơn giản hóa công việc lập
trình thị giác máy tính. OpenCV bao gồm các hàm có khả năng rất tốt trong
công việc tìm, theo dõi, nhận dạng các bề mặt, lọc Kalman…Ngoài ra nó còn
cung cấp các cơ sở thuật toán thị giác máy tính thông qua các giao diện lập
trình ứng dụng ở các mức khác nhau. Nó được cung cấp hoàn toàn miễn phí
người dùng có thể download và sử dụng cho các mục đích của mình.

Intel đã đưa ra phiên bản OpenCV đầu tiên vào năm 1999. Ban đầu nó
chỉ là thư viện ảnh của Intel, về sau nó đã được sử dụng rộng rãi. OpenCV là
một thư viện đa nền tảng, nó chấp nhận cả Window, Linux và Mac OXS.

2.2.2. Cấu tạo của OpenCV.


Các hàm của OpenCV được chứa trong các module khác nhau.

CXCORE chứa các định nghĩa kiểu dữ liệu cơ sở. Ví dụ, các cấu trúc dữ

liệu cho ảnh, điểm và hình chữ nhật được định nghĩa trong cxtypes.h.

CXCORE cũng chứa đại số tuyến tính và phương pháp thống kê, chức năng
68

duy trì và điều khiển chuỗi. Một số ít, các chức năng đồ họa để vẽ trên ảnh
cũng được đặt ở đây.

CV chứa các thuật toán về xử lý ảnh và định kích cỡ camera. Các chức
năng hình họa máy tính cũng được đặt ở đây.

CVAUX được mô tả trong tài liệu của OpenCV như chứa các mã cũ và
thứ nghiệm. Tuy nhiên, các giao diện đơn cho sự nhận diện ảnh ở trong
module này. Code sau này chúng được chuyên dụng cho nhận diện mặt và
chúng được ứng dụng rộng rãi cho mục đích đó.

HIGHGUI và CVCAM được đặt trong cùng thư mục là “otherlibs”.


HIGHGUI chứa các giao diện vào ra cơ bản, nó cũng chứa các khả năng cửa
sổ mở rộng và vào ra video.

CVCAM chứa các giao diện cho video truy cập qua DirectX trên nền
Windows 32 bits.

2.3. Một số loại camera thường dùng trong xử lý ảnh.


Hiện nay có hai công nghệ chế tạo camera là công nghệ CCD - Charge
Couple Device (Thiết bị tích điện kép) và công nghệ CMOS -
Complementary Metal Oxide Semiconductor (Chất bán dẫn ôxít kim loại bổ
sung).

Dưới đây là sơ đồ cấu tạo mạch bên trong của hai loại trên:
69

Hình CƠ SỞ LÝ THUYẾT XÂY DỰNG MÔ HÌNH.37: Sơ đồ khối CMOS camera.

Hình CƠ SỞ LÝ THUYẾT XÂY DỰNG MÔ HÌNH.38: Sơ đồ khối CCD camera.


Cách làm việc của hai loại trên:

Nhiệm vụ của chip cảm biến là bắt ánh sáng khi cửa chập được mở và
chuyển chúng thành các điện tử; sau đó các điện tử này được chuyển thành
điện áp, cuối cùng điện áp chuyển sang dạng tín hiệu số.
70

CCD gồm một mạng lưới các điểm bắt sáng được phủ bằng lớp bọc
màu (đỏ - red, hoặc xanh lục – green, hoặc xanh dương – blue), mỗi điểm ảnh
chỉ bắt một màu. Do đó khi chụp ảnh (cửa chập mở), ánh sáng qua ống kính
và được lưu lại trên bề mặt chip cảm biến dưới dạng các điểm ảnh. Mỗi điểm
ảnh có một mức điện áp khác nhau sẽ được chuyển đến bộ phận đọc giá trị
theo từng hang. Giá trị mỗi điểm ảnh sẽ được khuếch đại và đưa vào bộ
chuyển đổi tín hiệu tương tự sang tín hiệu số, cuối cùng đổ vào bộ xử lý để tái
hiện hình ảnh đã chụp. Chính quá trình đọc thông tin thực hiện theo từng hàng
đã làm cho tốc độ xử lý ảnh chậm, rồi thiếu hoặc thừa sáng.

Các nhà nghiên cứu đã tính đến việc trang bị them bộ đọc ảnh bổ sung
xen kẽ vào các điểm bắt sáng để đọc tất cả các thông tin điểm ảnh trong một
lần nhưng điều này bắt buộc phải tăng không gian của chip cảm biến, do vậy
mà không khả thi về mọi mặt. Chính cái điều mà các nhà nghiên cứu muốn bổ
sung cho CCD thì CMOS lại có sẵn, bởi cạnh mỗi điểm bắt sáng đã có sẵn
các mạch điện bổ trợ dễ dàng tích hợp ngay quá trình xử lý điểm ảnh. Với cấu
trúc này, mỗi điểm ảnh sẽ được xử lý ngay tại chỗ và đồng loạt truyền tín hiệu
số về bộ xử lý để tái hiện hình ảnh đã chụp nên tốc độ xử lý sẽ nhanh hơn rất
nhiều.

Một ưu điểm nữa mà cấu trúc này đem lại là có thể cung cấp chức năng
tương tác một vùng điểm ảnh (như phóng to một phần ảnh) cho người sử
dụng, điều mà chip cảm biến CCD khó làm được. Với khả năng bổ trợ nhiều
như vậy nhưng chip cảm biến CMOS lại tiêu thụ ít năng lượng hơn chip cảm
biến CCD, cộng với nhiều yếu tố khác mà giá thành sản xuất chip CMOS
thấp.

Ở thế hệ đầu của chip cảm biến CMOS, độ nhiễu tạo ra do việc khuếch
đại điểm ảnh là đáng kể, làm cho ảnh chụp không được mịn. Điểm yếu này đã
được cải thiện ở thế hệ sau, bằng việc đọc hai lần điểm ảnh (lần một đọc giá
71

trị bắt sáng, lần hai đọc giá trị của mạch bổ trợ, sau đó thực hiện phép trừ) và
bằng vi thấu kính làm ánh sáng rơi vào đúng vị trí bắt sáng.

Ở thế hệ sau của chip CMOS đã khắc các khuyết điểm của thế hệ trước
và có một số ưu điểm mới so với chip CCD như sau:

- Độ nhạy sáng cao và độ phân giải cao.

- Điện năng tiêu thụ ít kéo dài thời gian dùng pin.

- Ít bị nhiễu.

- Tốc độ xử lý ảnh chụp nhanh.

- Tích hợp nhiều chức năng tương tác với ảnh chụp.

Sau đây là một số loại CMOS và CCD camera:

Hình CƠ SỞ LÝ THUYẾT XÂY DỰNG MÔ HÌNH.39: CMOS camera.


72

Hình CƠ SỞ LÝ THUYẾT XÂY DỰNG MÔ HÌNH.40: CCD camera.


2.4. Giao tiếp máy tính với phần mềm Visual C++ 2008.

2.4.1. Tìm hiểu cổng nối tiếp máy tính.


Cổng nối tiếp được sử dụng để truyền dữ liệu hai chiều giữa máy tính
và ngoại vi, có các ưu điểm sau:

- Khoảng cách truyền xa hơn truyền song song.

- Số dây kết nối ít.

- Có thể truyền không dây dùng hồng ngoại.

- Có thể ghép nối với vi điều khiển hay PLC.

- Cho phép nối mạng.

- Có thể tháo lắp thiết bị trong lúc máy tính đang làm việc.

- Có thể cung cấp nguồn cho các mạch điện đơn giản.

Các thiết bị ghép nối chia thành 2 loại: DTE (Data Terminal
73

Equipment) và DCE (Data Communication Equipment). DCE là các thiết


bị trung gian như MODEM còn DTE là các thiết bị tiếp nhận hay truyền
dữ liệu như máy tính, PLC, vi điều khiển,… Việc trao đổi tín hiệu thông
thường qua 2 chân RxD (nhận) và TxD (truyền). Các tín hiệu còn lại có
chức năng hỗ trợ để thiết lập và điều khiển quá trình truyền, được gọi là các
tín hiệu bắt tay (handshake).

Ưu điểm của quá trình truyền dùng tín hiệu bắt tay là có thể kiểm
soát đường truyền.

Tín hiệu truyền theo chuẩn RS-232 của EIA (Electronics


Industry Associations). Chuẩn RS-232 quy định mức logic 1 ứng với điện
áp từ -3V đến -25V, mức logic 0 ứng với điện áp từ 3V đến 25V và có khả
năng cung cấp dòng từ 10 mA đến 20 mA. Ngoài ra, tất cả các ngõ ra đều
có đặc tính chống chập mạch.

Chuẩn RS-232 cho phép truyền tín hiệu với tốc độ đến 20.000 bps
nhưng nếu cáp truyền đủ ngắn có thể lên đến 115.200 bps.

Các phương thức nối giữa DTE và DCE:

- Đơn công (simplex connection): dữ liệu chỉ được truyền theo 1


hướng.

- Bán song công ( half-duplex): dữ liệu truyền theo 2 hướng, nhưng


mỗi thời điểm chỉ được truyền theo 1 hướng.

- Song công (full-duplex): số liệu được truyền đồng thời theo 2 hướng.

Khi không truyền dữ liệu, đường truyền sẽ ở trạng thái mark (điện áp
-10V). Khi bắt đầu truyền, DTE sẽ đưa ra xung Start (space: 10V) và sau đó
lần lượt truyền từ D0 đến D7 và Parity, cuối cùng là xung Stop (mark: -10V)
để khôi phục trạng thái đường truyền.
74

Hình CƠ SỞ LÝ THUYẾT XÂY DỰNG MÔ HÌNH.41: Các mức điện


áp của chuẩn RS232

Từ sơ đồ trên ta thấy cải tiến của RS232B là làm tăng mức điện áp từ
±5V đến ±25V. Trong đó:

Mức logic 1 tính từ -5V đến -25V.

Mức logic 0 tính từ +5V đến +25V.

Các mức từ -3V đến +3V gọi là trạng thái chuyển tiếp. Các mức điện
áp từ ±3V đến ±5V gọi là không xác định. Dữ liệu có mức điện áp rơi vào
khoảng này sẽ dẫn đến kết quả không dự tính được và đây cũng là tình trạng
hoạt động của những hệ thống được thiết bị kế sơ sài.

Điều đáng chú ý ở đây là: Mức 1 ~ LOW, mức 0 ~ HIGH vì trước khi
đưa vào xử lý còn có bộ nhớ đảo còn gọi là bộ nhớ chuẩn dạng tín hiệu.

Việc nâng mức điện áp của chuẩn RS232B dẫn đến sự hạn chế về tốc
độ truyền, vì vậy người ta thấy giữa tốc độ truyền và khoảng cách truyền phải
có sự dung hoà. RS232C là chuẩn hiện nay đang được áp dụng.

Điện áp sử dụng là ±12V. Trong đó:

-12V là mức logic 1 (HIGH)


75

+12V là mức logic 0 (LOW)

Cụ thể:

+3V → +12V là mức 0

+5V → +12V là mức tin cậy (của mức 0)

-3V → -12V là mức 0

-5V → -12V là mức tin cậy (của mức 1)

Bằng việc thu hẹp giới hạn điện áp đường truyền, tốc độ truuyền dữ liệu được
tăng lên đáng kể.

Hình CƠ SỞ LÝ THUYẾT XÂY DỰNG MÔ HÌNH.42: Mức lôgic và khuôn


mẫu khung truyền RS232.

Bit bắt đầu (start) ~ mức 0, tiếp theo là 7 bit dữ liệu 1000001,1 bit chẵn
lẻ 1, cuối cùng là 2 bit dừng 11.

Như vậy, toàn bộ khung truyền được phát ra là 01000001111. Bit chẵn
lẻ dùng để kiểm tra phát hiện lỗi và sửa lỗi. Thực chất của quá trình này như
sau: Khi kí tự được truyền thì máy tính sẽ đếm số kí tự 1 trong kí tự được
truyền. Nếu số đó là chẵn => bit chẵn lẻ =1; Nếu số đó là lẻ => bit chẵn lẻ =0.
76

Ở nơi nhận sẽ kiểm tra kí tự nhận được và đếm số 1, sau đó sẽ so sánh với bit
chẵn lẻ.

Nếu kết quả trùng khớp thì khung truyền coi như không mắc lỗi, ngược lại nó
sẽ phát lệnh yêu cầu truyền lại khung truyền. Nếu tỷ lệ mắc lỗi càng nhiều thì
tốc độ truyền càng giảm. Kỹ thuật mã lỗi chẵn lẻ theo kiểu này có một đặc
điểm rất đơn giản, nhưng trong trường hợp bị mắc lỗi 2 lần liền hoặc 4 lỗi liền
thì lai không phát hiện ra.

Nhưng trên thực tế với 7 bit được truyền thì khả năng bị mắc 2 hoặc 4 lỗi là
rất nhỏ có thể xem như không bao giờ xảy ra. Chính vì vậy, cách mã lỗi theo
kiểu này vẫn được dùng phổ biến ở trong kỹ thuật truyền dữ liệu qua cổng nối
tiếp.

Tốc độ truyền:

Để đánh giá chất lượng của cuộc truyền dữ liệu qua cổng nối tiếp thì
một trong những thông số đặc trưng quan trọng là tốc độ truyền/nhận dữ liệu.

Trong kỹ thuật truyền dữ liệu qua cổng nối tiếp ta thấy có bit bắt đầu,
bit dừng. Trong một số trường hợp có bit chẵn lẻ đã được bổ xung vào, như
vậy có tới 10 bit được truyền trong khi chỉ có 7 bit dữ liệu, còn trong trường
hợp sử dụng 2 bit dừng thì có tới 11 bit truyền trong khi chỉ có 7 bit dữ liệu.
Như vậy nếu có 10 kí tự được gửi trong 1 giây và nếu như có 11 bit được sử
dụng cho 1 kí tự thì tốc độ truyền thông sẽ là 110 bit/s. Như vậy giữa tốc độ
truyền bit và tốc độ truyền kí tự là khác nhau.

Ngoài tốc độ truyền bit người ta còn sử dụng tốc độ baud. Đây là tên
của một nhà kỹ thuật người Pháp đã giành nhiều công sức để nghiên cứu về
truyền thông và người ta đã lấy tên ông để làm đơn vị truyền dữ liệu. Thông
thường tốc độ bit và tốc độ baud là đồng nhất, chỉ trong trường hợp có
môdem do có thêm quá trình biến đổi tín hiệu nên 2 tốc độ này nó khác nhau.
77

Hình CƠ SỞ LÝ THUYẾT XÂY DỰNG


MÔ HÌNH.43: Cổng com máy tính
thực tế.
2.4.2. Vi mạch MAX232.
Các bộ vi điều khiển có khả năng giao tiếp với thế giới bên ngoài thông
qua cổng nối tiếp. Vấn đề trở ngại duy nhất khi giao tiếp với máy tính là mức
logic ở bộ vi điều khiển và ở cổng COM của máy tính khác nhau, cụ thể như
sau:

Bảng 2.1: So sánh điện áp của các mức logic giữa TTL và RS232

Đối tượng Mức logic Mức điện áp tương ứng


Cổng COM 1 -12V đến -3V
(RS232) 0 +3V đến +12V
Vi điều khiển 1 +5V
(Mức TTL) 0 0V

Khắc phục vấn đề này, người ta sử dụng vi mạch MAX232 để chuyển


đổi mức điện áp giữa hai chuẩn. Vi mạch này có chứa hai bộ chuyển đổi mức
logic từ TTL sang RS232 và ngược lại.
78

Hình CƠ SỞ LÝ THUYẾT XÂY DỰNG MÔ HÌNH.44: Vi mạch MAX232


2.4.3. Giao tiếp máy tính với phần mềm Visual C++2008.
Bộ phần mềm hướng đối tượng hiện nay đều hỗ trợ cho lập trình viên công cụ
để giao tiếp cổng COM máy tính với các thiết bị ngoại vi và các bộ vi điều khiển
ngoài. Trong Visual C++2008 việc giao tiếp cổng nối tiếp ta làm như sau:

Trên Dialog chuột phải chọn Insert ActiveX Control:

Hình CƠ SỞ LÝ THUYẾT XÂY DỰNG MÔ HÌNH.45: Lấy ra công cụ điều khiển


cổng com trên Visual C++2008
Tiếp đó chọn Common Controls kết quả được biểu tượng như sau :
79

Hình CƠ SỞ LÝ THUYẾT XÂY DỰNG MÔ HÌNH.46: Biểu tượng cổng COM trên
Visual C++ 2008.

Chúng ta thiết lập cho cổng COM trong hàm Setting như sau :

Chúng ta thiết lập cho cổng COM trong hàm Setting như sau :

Void CPlateDlg::Setting(void)
{
if (m_mscomm.get_PortOpen())
m_mscomm.put_PortOpen(false);
m_mscomm.put_CommPort(5);
m_mscomm.put_RThreshold(1);
m_mscomm.put_InputLen(1);
m_mscomm.put_InputMode(0);
m_mscomm.put_OutBufferSize(1024);
m_mscomm.put_PortOpen(true);
}

Việc giao tiếp với với vi điều khiển thông qua các hàm ghi đọc dữ liệu
m_mscomm.put_Output() và m_mscomm.get_Input(); .
80

2.5. Cảm biến OMRON E3S.


Đây là cảm biến quang phản xạ dùng trong công nghiệp . Khi vật nằm trong
vùng phát hiện của cảm biến thì đầu ra của cảm biến sẽ tích cực ở mức thấp. Dựa
vào mức tích cực này các bộ vi điều khiển sẽ xử lý tín hiệu và đưa ra các cơ cấu
chấp hành. Các thông số của cảm biển như sau :

 Khoảng đo: 0 - 300 mm.


 Nguồn cấp: 12 - 24 VDC ± 10%.
 Ngõ ra: NPN voltage-current output.
 Chế độ hoạt động: Light-ON | Dark-ON.
 Điều chỉnh độ nhạy: Một chiết áp xoay.
 Kiểu kết nối: Cáp nối sẵn dài 2 m.
 Bảo vệ vọt áp, ngắn mạch, phân cực ngược, nhiễu giao thoa.

Hình CƠ SỞ LÝ THUYẾT XÂY DỰNG MÔ HÌNH.47: Hình ảnh cảm biến OMRON
E3S

Sơ đồ nối đây cảm biến dựa vào hình sau :


81

Hình CƠ SỞ LÝ THUYẾT XÂY DỰNG MÔ HÌNH.48 : Sơ đồ nối dây cảm biến


OMRON E3S
2.6. Drive điều khiển động cơ dùng MC33886.
Chip MC33886 là IC chuyên dụng để điều khiển động cơ, nó được tích hợp cầu
H bên trong. Được đóng gói ở dạng chip dán rất nhỏ gọn, nó thích hợp cho các
ứng dụng điều khiển động cơ trong các mạch robot.

Hình CƠ SỞ LÝ THUYẾT XÂY DỰNG MÔ HÌNH.49: Sơ đồ nguyên lý và hình


dạng thực tế chip MC33886.
82

Đặc điểm :

 Điện áp hoạt động từ : 5- 40VDC


 Dòng điện cực đại: 5A
 Tần số xung PWM tối đa lên tới 10Khz.

Hình CƠ SỞ LÝ THUYẾT XÂY DỰNG MÔ HÌNH.50: Sơ đồ khối chip MC33886.


MC33886 tích hợp bên trong một bộ cầu H do đó chỉ điều khiển được một
moto quay theo hai chiều.

Sơ đồ ghép nối với vi điều khiển như sau :

Hình CƠ SỞ LÝ THUYẾT XÂY DỰNG MÔ HÌNH.51: Sơ đồ ghép nối MC33886 với


vi điều khiển.
83

2.7. Modun led matrix.


Modun led matrix có chức năng hiển thị thông tin dưới dạng văn bản. Nó được
cấu tạo từ các led matrix 8x8 ghép thành một ma trận điểm ảnh. Để điều khiển
modun hiển thị được ký tự đồng nghĩa với chúng ta điều khiển từng điểm ảnh
riêng biệt, việc này thường do các ic chốt hoặc ghi dịch như 74HC595, 74HC573...

Hình CƠ SỞ LÝ THUYẾT XÂY DỰNG MÔ HÌNH.52: Modun led matrix


Có hai loại ma trận LED 8x8 là ma trận LED đơn sắc và ma trận LED đa sắc.

Hình CƠ SỞ LÝ THUYẾT XÂY DỰNG MÔ HÌNH.53: Led matrix 8x8 đa sắc


84

Một ma trận led 8x8 đơn sắc bao gồm 64 led được bố trí thành 8 hàng
x 8 cột, trong đó các anốt của 8 led trong cùng một hàng được nối với nhau để
tạo thành một đường dây hàng và các Katot của 8 led trong cùng một cột
được nối với nhau để tạo thành một đường dây cột. Như vậy một ma trận led
8x8 đơn sắc có tám đường dây hàng và tám đường dây cột, muốn 1 led trong
ma trận sáng ta cần cấp nguồn cho led và đường dây hàng và đường dây cột
tương ứng với led đó.

Một ma trận led 8x8 đa sắc bao gồm 64 điểm sáng được bố trí thành 8
hàng x 8 cột trong đó mỗi điểm sáng có thể gồm 1 led màu xanh lục + 1 led
màu đỏ hoặc 1 led màu xanh lục + 1 led màu xanh lơ + 1 led màu đỏ hoặc 1
led màu xanh lục + 1 led màu xanh lơ + 2 led màu đỏ.

Với loại led ma trận mà mỗi điểm sáng gồm 1 led màu xanh lục + 1 led
màu đỏ thì điểm sáng hiển thị màu xanh nếu led đỏ tắt, màu đỏ nếu led màu
xanh tắt, màu vàng nếu cả 2 led sáng và tắt nếu cả 2 led cùng tắt .trong cùng
1 hàng, các katot của các led màu xanh được nối với nhau để tạo thành 1
đường dây hàng thứ nhất và các katot của các led màu đỏ được nối với nhau
để tạo thành 1 đường dây hàng thứ 2. Các anot của 16 led trong cùng 1 cột
được nối với nhau để tạo thành 1 đường dây cột. Như vậy 1 led trong ma trận
sáng ta cần cấp nguồn cho led vào đường dây hàng và đường dây cột tương
ứng với led đó.
85

CHƯƠNG 3: XÂY DỰNG MÔ HÌNH HỆ THỐNG

3.1. Sơ đồ khối hệ thống.

Hình XÂY DỰNG MÔ HÌNH HỆ THỐNG.54: Sơ đồ khối hệ thống.


Mô hình bãi đỗ xe thông minh gồm các thành phần chính sau:

 Khối camera : Thu lại hình ảnh màu liên tục gửi về phần mềm nhận
dạng.
 Khối máy tính: Nơi chương trình xử lý ảnh thực thi nhiệm vụ, trao đổi
thông tin với vi điều khiển thông qua cổng nối tiếp.
 Khối cảm biến : Gồm 2 cảm biến OMRON loại phản xạ khuếch tán.
Nhiệm vụ phát hiện xe vào bến.
 Hai công tắc hành trình, xác định vị trị barie, giúp động cơ đóng ngắt
một cách chính xác.
 Khối Driver điều khiển động cơ: Gồm IC công suất tích hợp cầu H,
điều khiển động cơ quay thuận hoặc nghịch.
86

 Khối động cơ: Thực hiện việc nâng hạ barie tự động cho phép xe vào
bãi.
 Khối modun led matrix : hiển thị thông báo và thông tin biển số xe.
 Khối mạch điều khiển: Bộ não là chíp ATmega32, xử lý các thông tin
của cảm biển, điều khiển việc hiển thị lên led matrix và nâng hạ barie
tự động, trao đổi thông tin với phần mềm nhận dạng ảnh.

3.2. Nguyên lý hoạt động của mô hình.


Để nhận biết được xe vào bãi hệ mô hình biến có gắn 2 cảm biến phản xạ
khuếch tán OMRON đạt trước và sau barie. Khi có xe ô tô đến trong phạm vi
phát hiện cảm biến sẽ xuất một xung từ mức cao xuống mức thấp. Xung phát
ra được đưa vào 2 bộ ngắt ngoài của vi điều khiển. Khi có xe vào bến cảm
biến thứ nhất đưa ra yêu cầu nhận dạng bằng cách gửi một mã kí tự lên phần
mềm nhận dạng. Hình ảnh camera đưa về phần mềm nhận dạng là liên tục,
khi có yêu cầu nhận dạng phần mềm sẽ tự động chụp ảnh. Sau khi xử lý, nhận
ra được biển xe, phần mềm gửi thông tin của xe xuống bộ vi điều khiển hiển
thị biển xe đến trong modun led matrix, đồng thời điều khiển barie tự động
mở cho xe vào bến. Cảm biến thứ 2 sau khi xe qua barie nó sẽ gửi thông tin
tới vi điều khiển hiện thị lời chào lên modun led matrix, đồng thời đóng barie
xuống. Ngoài ra hệ thống có gắn thêm 2 công tắc hành trình, để đảm bảo việc
nâng hạ barie một cách chính xác.
87

3.3. Giao diện phần mềm.

Hình XÂY DỰNG MÔ HÌNH HỆ THỐNG.55: Giao diện phần mềm điều khiển.
Mô hình ở đây là một hệ thống tự động nên giao diện điều khiển khá
đơn giản. Để vận hành hệ thống chỉ cẩn bấm nút START, tất cả các quy trình
sẽ diễn ra tự động. Khung camera hiển thị hình ảnh thu được từ camera liên
tục. Khung Source Image hiển thị ảnh chụp ảnh xe vào. Khung Result Image
hiển thị biển xe được khoanh vùng. Khi ngưng sử dụng hệ thống ta bấm nút
exit để thoát khỏi chương trình.
88

3.4. Mạch điều khiển.

3.4.1. Khối điều khiển trung tâm ATmega32.

Hình XÂY DỰNG MÔ HÌNH HỆ THỐNG.56: Khối điều khiển trung tâm
ATmega32.
Mạch điều khiển chính gồm chip ATmega32, các mạch phụ trợ đi kèm
như mạch reset chip, phần nạp chương trình qua ISP, hệ thống phím nhấn, các
led báo trạng thái và các cổng IO cho phép ghép nối với thiết bị ngoại vi bên
ngoài.

Khối dao động thạch anh chạy với xung nhịp 8Mhz đi kèm với hai tụ
22p cho phép chip hoạt động ổn định.
89

3.4.2. Khối nguồn cung cấp.

Hình XÂY DỰNG MÔ HÌNH HỆ THỐNG.57: Khối nguồn cung cấp.


Khối nguồn cung cấp được chia ra làm hai mức điện áp cung cấp:

 Nguồn 5V: Nguồn này nuôi các khối vi điều khiển, cảm biến, modun
led matrix. Phần nguồn này được IC 7805 ổn áp kết hợp với tran công
suất B688 kích dòng tránh bị sụp áp trên mạch.
 Nguồn 24V: Phần này nuôi mạch Driver điều khiển động cơ nâng hạ
barie.

3.4.3. Khối Driver điều khiển động cơ.

Hình XÂY DỰNG MÔ HÌNH HỆ THỐNG.58: Khối Driver điều khiển động cơ.
90

Khối này sử dụng chip MC33668 để điều khiển động cơ, kết hợp các tụ lọc
cho động cơ hoạt động ổn định nhất.

3.4.4. Khối modun led matrix.

Hình XÂY DỰNG MÔ HÌNH HỆ THỐNG.59: Khối modun matrix.


Khối này gồm 7 matrix 3 màu 8x8, các IC giải mã 74HC595, IC đệm
74HC245, IC quét 74HC138 và FET công suất AMP4953. Với việc sử dụng
các IC trên cho phép hiển thị kí tự trên led matrix tốt nhất, các led sáng đều,
IC 74HC595 hạn chế tốt nhất việc led bị giật khi quét chữ.

3.4.5. Khối truyền thông RS232.

Hình XÂY DỰNG MÔ HÌNH HỆ THỐNG.60: Khối truyền thông RS232.


91

3.4.6. Hình ảnh mạch thực tế.

Hình XÂY DỰNG MÔ HÌNH HỆ THỐNG.61: Hình ảnh mạch điều khiển.

Hình XÂY DỰNG MÔ HÌNH HỆ THỐNG.62: Modun led matrix

Hình XÂY DỰNG MÔ HÌNH HỆ THỐNG.63: Driver điều khiển động cơ.
92

3.5. Lắp ghép mô hình.

Hình XÂY DỰNG MÔ HÌNH HỆ THỐNG.64: Mô hình bãi đỗ xe hoàn thiện.


Mô hình có chiều dài 150cm, rộng 50cm, cao 60cm được bố trí như sau:

- Cảm biến siêu âm bố trí phía trước và sau barie sao cho ảnh chụp từ
camera là tốt nhất.
- Modun led matrix đặt chính giữa , phía trên đặt camera chụp ảnh.
- Barie đặt phía sau với động cơ kéo xích, cho khả năng nâng hạ chính
xác nhất.
- Mạch điều khiển và máy tính đặt bên trái mô hình thuận tiện cho việc
điều khiển.
93

CHƯƠNG 4: CHẠY THỬ NGHIỆM MÔ HÌNH VÀ ĐÁNH


GIÁ, KẾT LUẬN

4.1. Ảnh chạy thực nghiệm mô hình hệ thống.

Hình CHẠY THỬ NGHIỆM MÔ HÌNH VÀ ĐÁNH GIÁ, KẾT LUẬN.65: Ảnh chạy
thực nghiệm mô hình.
4.2. Đánh giá kết quả đạt được.
Đề tài đã xây dựng được mô hình hệ thống bãi đỗ xe thông minh, cả về
phần cứng, phần mềm và giao diện chương trình nhận dạng biển xe. Mô hình
hệ thống nhận diện tốt các biển xe dưới điều kiện ánh sáng đủ, camera quan
sát tốt. Kết quả thử nghiệm trên 5 biển số xe tự tạo cho độ chính xác 80%,
một phần sai số do biển xe tự chế nên khoảng cách và font biển số chưa chuẩn
xác. Hệ thống cảm biến phát hiện xe đến chính xác, modun led matrix hiển thị
tốt dưới ánh sáng ban ngày kết hợp giữa 3 màu linh hoạt. Barie và động cơ
hoạt động nhịp nhàng, khả năng đóng ngắt ngay khi nâng hoặc hạ qua
ngưỡng. Phần mạch điều khiển ổn định, sử dụng các linh kiện dán cho thiết kế
gọn gàng. Tốc độ xử lý của mạch khá nhanh, thời gian từ lúc xe vào đến lúc
94

lấy được thông tin xe tầm 1,5s. Hệ thống nhận dạng tốt cả biển 7 ký tự lẫn
biển 8 ký tự. Phần mềm nhận dạng tốt biển có độ nghiêng dưới 15 độ.

Tuy nhiên mô hình vẫn còn nhiều hạn chế do đang trong giai đoạn phát
triển. Hệ thống mới chỉ nhận dạng biển xe và hiển thị thông tin lên led matrix,
chưa có chức năng in vé tự động hoặc xuất ra cơ sở dữ liệu cho việc quản lý
và lưu trữ thông tin. Mô hình mới chỉ nhận dạng được biển xe dưới điều kiện
ánh sáng tốt, ảnh chụp từ camera phải rõ nét. Biển xe phải rõ ràng không bám
bụi bẩn, bùn đất. Góc nghiêng của biển không vượt quá giới hạn cho phép.
Nếu không thỏa mãn các yếu tốt trên phần mềm nhận dạng sẽ không khoanh
vùng được biển xe hoặc nhận dạng sai kí tự. Phần mạch điều khiển vẫn còn ở
mức độ đơn giản, cần kết hợp nhiều modun như RFID, hồng ngoại để thuận
tiện cho việc in vé.

4.3. Hướng phát triển của đề tài.


Mô hình mới chỉ gói gọn trong đề tài tốt nghiệp đại học, tuy nhiên nó vượt
xa mong đợi. Hệ thống đã chạy thành công phần cơ bản của bãi gửi xe thông
minh. Trong tương lai muốn áp dụng mô hình vào thực tế cần phát triển, hoàn
thiện thêm rất nhiều. Quan trọng nhất là khả năng xử lý ảnh, trong tương lai
phần mềm nhận dạng sẽ áp dụng nhiều thuận toán mới trong việc xử lý như:
khử nhiễu, sử dụng bộ lọc Kalman, sử dụng mạng noron ( trí tuệ nhân tạo )
vào việc khoanh vùng, bẻ góc lệch biển, nhận dạng kí tự bằng tập huấn luyện.
Mô hình có ứng dụng rất nhiều trong cuộc sống, chỉ cần tùy biến chút ít là có
thể sử dụng trong các mục đích khác nhau. Ví dụ như chỉ cần kết hợp với máy
in vé hoặc hệ thống RFID ghi thông tin lên thẻ từ là ta đã có hệ thống bãi gửi
xe tự động. Kết hợp thêm phần cơ sở dữ liệu ta có một trạm thu phí tự động,
các xe khi mua vé tháng sẽ được ghi lại biển số vào cơ sở dữ liệu khi xe qua
trạm phần mềm sẽ đối chiếu biển xe nếu có trong cơ sở dữ liệu sẽ cho phép xe
qua. Đó chỉ là ý tưởng để đi đến hiện thực cần rất nhiều nỗ lực và cố gắng, hi
vọng các bạn sinh viên khóa tiếp theo sẽ tiếp tục xây dựng và nghiên cứu
95

hoàn thiện hơn đề tài này, trong tương lai không xa có thể áp dụng mô hình
này vào bãi gửi xe trong trường hoặc các trung tâm cửa hàng siêu thị.

4.4. Kết luận.


Sau một thời gian làm việc và nghiên cứu đề tài “mô hình bãi gửi xe thông
minh” đã hoàn thành và thử nghiệm chạy thành côngvà có thể ứng dụng vào
cuộc sống. Để hoàn thiện đề tài này em đã :

- Tìm hiểu và lập trình thành thạo chip ATmega32 cho các ứng dụng thực
tế.
- Tìm hiểu bộ thư viện OpenCV viết các ứng dụng nhận dạng khuôn mặt,
đồ vật, nhận dạng biển số, chữ viết.
- Học lập trình ứng dụng MFC trong Visual C++2008 viết các phần mềm
trên windows giao tiếp vi điều khiển, xử lý ảnh.
- Sử dụng thành thạo phần mềm thiết kế mạch Altium Design, có kinh
nghiệm làm việc với linh kiện dán, tư duy thiết kế mạch 2 lớp.

Em xin chân thành cảm ơn ban giám hiệu nhà trường cũng như sự nhiệt
tình giúp đỡ của các thầy cô trong khoa Điện tử và đặc biệt là sự chỉ bảo tận
tình của Cô Th.s Vũ Thị Thu Hương và Ts. Ngô Mạnh Tiến là người trực
tiếp hướng dẫn em hoàn thành đề tài này.

Em xin chân thành cảm ơn !

TÀI LIỆU THAM KHẢO


96

[1]. Gary Bradski và Adrian Kaehler, “Learning OpenCV” ,NXB O’Reilly


Media, 09/2008.

[2]. Vadim Pisarevsky , “Introduction to OpenCV”, ebook.

[3]. David Qing Chen , “A basic introduction to OpenCV for Image


Processing” , ĐH Ottawa, 01/2007.

[4]. Alexandre R.J Francois, “CAMSHIFT tracker design experiments with


Intel OpenCV and SAI” 06/2004.

[5]. Nguyễn Duy Nghĩa, “Nghiên cứu kỹ thuật xử lý Video số, ứng dụng vào
theo vết và phân loại đối tượng”, 2000-2004, ebook.

[6]. TS. Đỗ Năng Toàn, TS Phạm Việt Bình, “Giáo trình môn học Xử Lý Ảnh”
ĐH Thái Nguyên.

[7]. Trần Quốc Đăng , “Đồ án thị giác máy tính”, ĐHBKHN , ebook.

[8]. Ngô Hải Bắc, “Lập trình giao tiếp máy tính qua cổng RS232”, ebook.

[9]. http://opencv.willowgarage.com/documentation/index.htm

[10]. Datasheet ATmega32 “alldatasheet.com”

Một số trang web:

1. www.alldatasheet.com
2. www.atmel.com
3. www.dientuvietnam.net
4. www.dks.edu.vn
5. www.hocavr.com
6. www.phanit.com
7. http://machdientu.net/
97

PHỤ LỤC

CHƯƠNG 5: Code chương trình ATmega32:

//Project: Mo hinh bai gui xe thong minh


//Design: Le Duc He
//Date: 1/6/2012
//View Website: http://machdientu.net

// Them cac thu vien lap trinh


#include <mega16.h>
#include <delay.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <font.c>
// Dinh nghia cac chan dieu khien modun led matrix
#define LACH_RED PORTB.0
#define DATA_RED PORTB.1
#define LACH_BLUE PORTB.2
#define DATA_BLUE PORTB.3
#define SCK PORTB.4
// Dinh nghia cac chan quet hang modun led matrix
#define A PORTB.7
#define B PORTB.6
#define C PORTB.5
// Dinh nghia cong tac hanh trinh
#define HT1 PIND.6
98

#define HT2 PIND.4


// Dinh nghia phim nang ha barie
#define SW1 PINC.0
#define SW2 PINC.1
// Dinh nghia chan dieu khien dong co
#define DDR PORTA.4
#define PWM PORTA.5
// Dinh nghia loa chip
#define SPEAK PORTC.7
// Dinh nghia cac led bao trang thai
#define LED1 PORTA.0
#define LED2 PORTA.1
#define LED3 PORTA.2
#define LED4 PORTA.3
// Dinh nghia mau modun led matrix
#define RED 0
#define BLUE 1
#define ORANGE 2

unsigned char welcome[]="WELCOME";


unsigned char comin[]="COME IN";
unsigned char do_an[]="DO AN TOT NGHIEP !! ";
unsigned char bienso[9];
unsigned char maA[8]={0,1,0,1,0,1,0,1};
unsigned char maB[8]={0,0,1,1,0,0,1,1};
unsigned char maC[8]={0,0,0,0,1,1,1,1};
unsigned char leng,k,m,x=0,y=0,color;
unsigned int d=0,a=0,b,i=0,j,enable=1,kt=0;
int index=0;
99

unsigned char font[];


#ifndef RXB8
#define RXB8 1
#endif
#ifndef TXB8
#define TXB8 0
#endif
#ifndef UPE
#define UPE 2
#endif
#ifndef DOR
#define DOR 3
#endif
#ifndef FE
#define FE 4
#endif
#ifndef UDRE
#define UDRE 5
#endif
#ifndef RXC
#define RXC 7
#endif
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
// USART Receiver buffer
#define RX_BUFFER_SIZE 8
100

char rx_buffer[RX_BUFFER_SIZE];
#if RX_BUFFER_SIZE <= 256
unsigned char rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int rx_wr_index,rx_rd_index,rx_counter;
#endif
// This flag is set on USART Receiver buffer overflow
bit rx_buffer_overflow;
// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if(data=='@')
{
for(m=0;m<7;m++)
bienso[m]=' ';
leng=0;
}
else if(data=='#')
{ a=0;
enable=1;
kt=1;
}
else if(data=='$')
{
delay_ms(10);
a=1;
101

index=1;
kt=3;
}
else
{
bienso[leng] =data;
leng++;
}

if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)


{
rx_buffer[rx_wr_index++]=data;
#if RX_BUFFER_SIZE == 256
// special case for receiver buffer size=256
if (++rx_counter == 0)
{
#else
if (rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
if (++rx_counter == RX_BUFFER_SIZE)
{
rx_counter=0;
#endif
rx_buffer_overflow=1;
}
}
}
#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
#define _ALTERNATE_GETCHAR_
102

#pragma used+
char getchar(void)
{
char data;
while (rx_counter==0);
data=rx_buffer[rx_rd_index++];
#if RX_BUFFER_SIZE != 256
if (rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
#endif
#asm("cli")
--rx_counter;
#asm("sei")
return data;
}
#pragma used-
#endif
// USART Transmitter buffer
#define TX_BUFFER_SIZE 8
char tx_buffer[TX_BUFFER_SIZE];
#if TX_BUFFER_SIZE <= 256
unsigned char tx_wr_index,tx_rd_index,tx_counter;
#else
unsigned int tx_wr_index,tx_rd_index,tx_counter;
#endif
// USART Transmitter interrupt service routine
interrupt [USART_TXC] void usart_tx_isr(void)
{
if (tx_counter)
{
103

--tx_counter;
UDR=tx_buffer[tx_rd_index++];
#if TX_BUFFER_SIZE != 256
if (tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
#endif
}
}
#ifndef _DEBUG_TERMINAL_IO_
// Write a character to the USART Transmitter buffer
#define _ALTERNATE_PUTCHAR_
#pragma used+
void putchar(char c)
{
while (tx_counter == TX_BUFFER_SIZE);
#asm("cli")
if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))
{
tx_buffer[tx_wr_index++]=c;
#if TX_BUFFER_SIZE != 256
if (tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
#endif
++tx_counter;
}
else
UDR=c;
#asm("sei")
}
#pragma used-
#endif
104

// Chuong trinh con dieu khien dong co quay thuan


void DC_thuan()
{
DDR=1;
PWM=0;
}
// Chuong trinh con dieu khien dong co quay nghich
void DC_nghich()
{
DDR=0;
PWM=1;
}
// Chuong trinh con dung dong co
void DC_dung()
{
DDR=0;
PWM=0;
}
// Ham xuat du lieu ra modun led matrix
void hienthi(unsigned char x,unsigned char y)
{
unsigned int i,temp;
for(i=0;i<8;i++)
{
if(y==0)// mau do
{
DATA_BLUE=1;
temp=x;
105

temp=temp&0x80;
if(temp==0x80)
DATA_RED=1;
else
DATA_RED=0;
SCK=0;
x*=2;
SCK=1;
}
if(y==1)// mau xanh
{
DATA_RED=1;
temp=x;
temp=temp&0x80;
if(temp==0x80)
DATA_BLUE=1;
else
DATA_BLUE=0;
SCK=0;
x*=2;
SCK=1;
}
if(y==2)// mau CAM
{
temp=x;
temp=temp&0x80;
if(temp==0x80)
{
DATA_BLUE=1;
106

DATA_RED=1;
}
else
{
DATA_BLUE=0;
DATA_RED=0;
}
SCK=0;
x*=2;
SCK=1;
}
}
}
void output_matrix()
{
LACH_RED=0;
LACH_BLUE=0;
LACH_RED=1;
LACH_BLUE=1;
}
// Ham xu ly chuoi chay khoi dong
void xuly()
{
unsigned int i,j,l;
l=(strlen(do_an));
for(i=0;i<l;i++)
{
for(j=0;j<8;j++)
{
107

font[8*i+j]=codefont[8*(do_an[i]-32)+j];
d++;
}
}
}
// Ham xu ly chuoi bien so xe gui xuong tu may tinh
void xuly1()
{
unsigned int i,j,l;
l=(strlen(bienso));
for(i=0;i<l;i++)
{
for(j=0;j<8;j++)
{
font[8*i+j]=codefont[8*(bienso[i]-32)+j];
}
}
}
// Ham xu ly chuoi chay chao mung
void xuly2()
{
unsigned int i,j,l;
l=(strlen(welcome));
for(i=0;i<l;i++)
{
for(j=0;j<8;j++)
{
font[8*i+j]=codefont[8*(welcome[i]-32)+j];
}
108

}
}
// Ham xu ly chuoi chay chu com in
void xuly3()
{
unsigned int i,j,l;
l=(strlen(comin));
for(i=0;i<l;i++)
{
for(j=0;j<8;j++)
{
font[8*i+j]=codefont[8*(comin[i]-32)+j];
}
}
}
// Ham chay dich dong chu tren led matrix
void dich_hien_thi()
{
unsigned int in,tg;
tg=font[0];
for(in=0;in<d;in++)
{
font[in]=font[in+1];
}
font[d-1]=tg;
}

// Ham chay dong chu tren led matrix


void matrix_chu(unsigned char mau,unsigned char tocdo)
109

{
for(k=0;k<tocdo;k++)
{
for(j=0;j<8;j++)
{
hienthi(0xff,2);
hienthi(0xff,2);
hienthi(0xff,2);
hienthi(0xff,2);
hienthi(0xff,2);
hienthi(0xff,2);
hienthi(0xff,2);
LACH_RED=0;LACH_BLUE=0;
LACH_RED=1;LACH_BLUE=1;
A=maA[j];
B=maB[j];
C=maC[j];
hienthi(~font[j+48],mau);
hienthi(~font[j+40],mau);
hienthi(~font[j+32],mau);
hienthi(~font[j+24],mau);
hienthi(~font[j+16],mau);
hienthi(~font[j+8] ,mau);
hienthi(~font[j],mau);
LACH_RED=0;LACH_BLUE=0;
LACH_RED=1;LACH_BLUE=1;
}
}
if(kt==0)
110

dich_hien_thi();
}
// Ham hien thi bien xe len led matrix
void matrix_bienxe()
{
for(j=0;j<8;j++)
{
hienthi(0xff,2);
hienthi(0xff,2);
hienthi(0xff,2);
hienthi(0xff,2);
hienthi(0xff,2);
hienthi(0xff,2);
hienthi(0xff,2);
output_matrix();
A=maA[j];
B=maB[j];
C=maC[j];
hienthi(~font[j+48],0);
hienthi(~font[j+40],0);
hienthi(~font[j+32],0);
hienthi(~font[j+24],0);
hienthi(~font[j+16],1);
hienthi(~font[j+8],2);
hienthi(~font[j],2);
output_matrix();
}}

// Ngat ngoai doc tu cam bien thu nhat


111

interrupt [EXT_INT0] void ext_int0_isr(void)


{ a=0;
delay_ms(20);
putchar(66);
enable=1;
kt=1;
delay_ms(30);
//index=1;
}
// Ngat ngoai doc tu cam bien thu hai
interrupt [EXT_INT1] void ext_int1_isr(void)
{ a=0;
delay_ms(20);
kt=2;
xuly2();
delay_ms(30);
index=2;
}
// Ngat timer nhay led don hien thi
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Place your code here
x++;
y++;
if(x<3)
LED1=0;
if(y<20)
LED4=0;
if(x>=3)
112

LED1=1;
if(y>=20)
LED4=1;
if(x==10)
x=0;
if(y==40)
y=0;
}
void main(void)
{
PORTA=0xff;
DDRA=0xff;
PORTB=0xff;
DDRB=0xff;
PORTC=0xff;
DDRC=0xf0;
PORTD=0xff;
DDRD=0x00;
// Timer 1
TCCR1A=0x00;
TCCR1B=0x02;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x27;
ICR1L=0x10;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
113

// External Interrupt(s) initialization


GICR|=0xC0;
MCUCR=0x0A;
MCUCSR=0x00;
GIFR=0xC0;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x04;
// USART initialization
UCSRA=0x00;
UCSRB=0xD8;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;
// Global enable interrupts
#asm("sei")
b=strlen(welcome)*3;
xuly();
while (1)
{
i++;
if(i==b)
color=RED;
if(i==2*b)
color=BLUE;
if(i==3*b)
color=ORANGE;
// Chon che do hien thi bien xe
if(enable==1&&kt==1)
114

{
xuly1();
enable=0;
}
if(kt==1)
{
matrix_bienxe();
}
//Chon che do hien dong chu do an tot nghiep
if(kt==0)
{
matrix_chu(color,14);
}
//Chon che do chay dong chu WELCOME
if(kt==2)
{
matrix_chu(color,14);
}
if(a==1)
{
xuly3();
}
if(kt==3)
{
matrix_chu(color,14);
}
//Doc phim nhan nang ha barie bang tay
if(SW1==0)
{
115

index=1;
}
if(SW2==0)
{
index=2;
}
// Dieu khien nang barie
if(index==1&&HT2==1)
{
LED2=0;
LED3=1;
DC_thuan();
SPEAK=0;
}
if(index==1&&HT2==0)
{
LED2=1;
LED3=1;
DC_dung();
SPEAK=1;
}
// Dieu khien ha barie
if(index==2&&HT1==1)
{
LED2=1;
LED3=0;
DC_nghich();
SPEAK=1;
}
116

if(index==2&&HT1==0)
{
LED2=1;
LED3=1;
DC_dung();
}
if(i==3*b)
i=0;
}
}
117

1. Hướng dẫn sử dụng phần mềm Codevision.

Chạy CodeVision bằng cách click chuột vào ICON của CodeVision trên Desktop được
cửa sổ như sau:

Để tạo Project mới chọn trên menu: File New được như sau:

Chọn Project sau đó click chuột vào OK được cửa sổ hỏi xem có sử dụng Code Winzard
không:
118

Chọn Yes được cửa sổ CodeWinzardAVR như sau :

Sử dụng chip AVR nào và thạch anh tần số bao nhiêu


ta nhập vào tab Chip. Để khởi tạo cho các cổng IO ta
chuyển qua tab Ports.
Các chân IO của AVR mặc định trạng thái IN, muốn
chuyển thành trạng thái OUT để có thể đưa các mức
logic ra ta click chuột vào các nút IN (mầu trắng) để
nó chuyển thành OUT trong các Tab Port. Sau đó
chọn File Generate, Save and Exit

Được cửa sổ yêu cầu nhớ các file của Project. Đây là
ví dụ IO nên ta save tên là IO.

Sau khi nhớ song 3 file : IO.c – IO.prj – IO.cwp được cửa sổ như sau:
119

Chúng ta đã được code vision khởi tạo code. Trong đó có đầy đủ code cần thiết mà
khi nãy chúng ta cấu hình cho cổng IO. Chúng ta bắt đầu soạn code. Để led nhấp nháy
chúng ta dùng hàm delay_ms(). Do đó ta thêm thư viện delay.h bằng cách tìm dòng lệnh:
#include <mega16.h> ngay đầu chương trình viết ngay dưới dòng lệnh sau: #include
<delay.h>. Để led nhấp nháy ở cổng IO ta đưa ra cổng IO một biến temp có giá trị tăng dần
từ 0 đến 255. Do đó ta khai báo thêm một biến unsigned char temp ngay dưới dòng //
Declare your global variables here như sau:
120

Khởi tạo cho các cổng IO


121

Trong hàm main có vòng while(1). Chúng ta soạn code vào đó như sau:
temp=0;
while (1)
{
// Place your code here
PORTA=temp;
PORTB=temp;
PORTC=temp;
PORTD=temp;
delay_ms(1000);
temp++;
};
}

Để dịch chương trình ấn F9 hoặc vào menu: Project Compile.


Được cửa sổ Information như sau:
122

Chương trình không có lỗi. Nhấp OK.


Để nạp chương trình các bạn cần cấu hình cho mạch nạp. Vào menu: Settings
Programmer được cửa sổ như bên cạnh.
Mạch nạp ta dùng STK 200 do đó các bạn chọn Kanda Systems STK200+/300. Nhấp OK.
Sau đó các bạn chọn trên menu: Projects Configure được cửa sổ như sau:

Trong tab After Make các bạn đánh dấu vào Program the Chip và nhấp OK.
Nhấn tổ hợp phím Shift + F9 được như hình bên.
Cắm Jump mạch nạp vào .Click vào Program. Đợi nạp xong nhổ jump nạp ra ấn Reset để
thấy led chạy.

You might also like