Hình P3_2.23: Cửa sổ biên dịch code chương trình -Nạp vào chip: trước khi nạp vào chip chúng ta cần thiết lập một số thông số như +Chọn loại mạch nạp: Atmel STK500/AVRISP +Chọn Port gi
Trang 1Bài 1: KIT AVR VÀ TRÌNH BIÊN DỊCH CODEVISIONAVR
I Mục đích
Đưa ra cái nhìn tổng quát các thành phần và cấu trúc của KIT thực tập là KIT chính mà sinh viên sẽ thực tập trong suốt quá trình học môn này
Sử dụng phần mềm CodeVisionAVR để soạn thảo, tổ chức một project cho bất
kỳ chip họ AVR nào
II Yêu cầu
1.Nắm rõ cấu trúc của vi điều khiển Atmega32
2.Hiểu được các module trên schematic của KIT VAR
3.Các bước để soạn thảo một project (source code) cho chip AVR
III Cơ sở lý thuyết
III.1 Vi điều khiển Atmega32
Một số đặc điểm của Atmega32
• Kiến trúc RISC mở rộng
- Tập lệnh với 131 lệnh, hầu hết mỗi lệnh đều được thực thi trong một chu
kỳ xung clock
- Một tập thanh ghi với 32 thanh ghi 8 bit, tất cả các chip thuộc họ AVR
đều có tập thanh ghi này
- Tần số tối đa có thể lên tới 16Mhz
• Bộ nhớ chương trình và bộ nhớ dữ liệu
- 32 Kbyte bộ nhớ lập trình được(flash), có thể nạp lại 10.000 lần
- 1024 Byte EEPROM, có thể nạp lai 100.000 lần
- 2 Kbyte SRAM nội
• Giao tiếp chuẩn JTAG(IEEE)
- Hỗ trợ chế độ Debug mở rộng trên chip
- Lập trình cho Flash, EEPROM, set Fuse bit và lock bit thông qua chuẩn
giao tiếp JTAG
• Đặc điểm thiết bị ngoại vi
- 2 bộ Timer/Counter 8 bit hoat động riêng biệt
- 1 bộ Timer/Counter 16 bit với Compare mode và Capture mode
- Bộ đếm thời gian thực với bộ tạo dao động riêng biệt
- 4 kênh PWM (Pulse Width Modulator)
Trang 2- 8 kênh 10 bit ADC
- Giao tiếp chuẩn nối tiếp 2 dây
- Lập trình truyền thông nối tiếp USART
- Bộ WatchDog Timer khả trình với bộ tạo dao động riêng biệt trên chip
• Những điểm đặc biệt của vi điều khiển
- Bao gồm cả ngắt nội lẫn ngắt ngoại
- 6 chế độ Sleep: Idle, ADC noise reduction, Power-save, Power-down,
Standby, Extended Standby
• I/O và hình thức đóng gói
- 32 đường I/O lập trình được
- 40 pin –PDIP, 44 lead-TQFP, 44 pad MLF
Trang 3Hình P3_2.2: Sơ khối bên trong của ATMega32 Lưu ý: Chi tiết về cấu trúc của vi điều khiển Atmega32 xem datasheet
Trang 4III.2 Giới thiệu KIT AVR
KIT AVR được thiết kế với mục tiêu phục vụ cho việc giảng dạy và nghiên cứu
về vi điều khiển và phát triển các ứng dụng nhúng trên vi điều khiển KIT AVR bao gồm các môđun sau:
III.2.1.Môđun xử lý trung tâm được thiết kế gồm:
- Vi điều khiển Atmega32
- Bộ tạo dao động ngoài (thạch anh 16MHz)
- Các công tắc nhấn được nối với chân của vi điều khiển như sau:
Bảng P3_2.1: Bảng sơ đồ chân của Atmega32 kết nối Switch
Số
TT
Chân của Atmega32
Ký hiệu thiết bị
PC5(TDI) PD6
14 19
10 30 32
21 9
20 13
17
25
12 11 31
1 2 3 4 5 6 7 8
33
40 39 38 37 36 35 34
15 18
26 27 28 29
22 23 24
(INT0)PD2 (RXD)PD0 (OC1A)PD5
VCC AVCC AREF
(OC2)PD7 RESET
(ICP)PD6 XT1
(INT1)PD3
(TMS)PC3
XT2 GND GND
(XCK/T0)PB0 (T1)PB1 (INT2/AIN0)PB2 (OC0/AIN1)PB3 (SS)PB4 (MOSI)PB5 (MISO)PB6 (SCK)PB7
(ADC7)PA7
(ADC0)PA0 (ADC1)PA1 (ADC2)PA2 (ADC3)PA3 (ADC4)PA4 (ADC5)PA5 (ADC6)PA6
(TXD)PD1 (OC1B)PD4
(TDO)PC4 (TDI)PC5 (TOSC1)PC6 (TOSC2)PC7
(SCL)PC0 (SDA)PC1 (TCK)PC2
VCC
PA4 PA5
PD7 PD4 PC0
PB3 PB0
PA6
PC7
R24 10k
Trang 5III.2.2 Các môđun giao tiếp vào/ra (I/O)
III.2.2.1 Các port của vi điều khiển Atmega32
Bảng P3_2.2:Bảng ký hiệu các PORT của Atmega32
Số
TT
Port của Atmega32
Ký hiệu thiết bị
J11
PORTC
1 2 3 4 5 6 7 8
PC2(TCK)
PD5
PD2 PD3 RxD
PD7
PD4 PD6
J12
PORTD
1 2 3 4 5 6 7 8
TxD
J10
PORTB
1 2 3 4 5 6 7 8
PB2 PB0
PB7
PB3 PB1 PB5 PB4
PA7
PA0 PA1 PA3 PA2 PA5
J13
PORTA
1 2 3 4 5 6 7 8 PA4
Hình P3_2.4: Các port của vi điều khiển Atmega32
Ký hiệu thiết bị
LCD2 LCD4
LCD1
J20
LCD
1 2 3 4 5 6 7 8
LCD0
LCD6
LCD2 LCD0 LCD7
VCC
LCD1 LCD5 R99330
LCD6 LCD5
7 8 9 10
11 12 13 14
15 16
LCD4 LCD7
Hình P3_2.5:Môđun màn hình hiển thị-LCD 16x2
Trang 6III.2.2.3 Led đơn: có 8 led đơn
Bảng P3_2.4: Bảng ký hiệu LED đơn
D5
LED
PA4 PA0
2 5 6 9 12 15 16 19
D0 D1 D2 D3 D4 D5 D6 D7
OELE
Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7
D7
LED
R9 R10 R7
Hình P3_2.6:Môđun LED đơn
III.2.2.4 Led 7 đoạn (7-SEGMENT LED)
Bảng P3_2.4: Bảng ký hiệu LED 7 đoạn
Trang 7Q9 PNP
Q7 PNP
PB6
DP G
R62 300
C
PA6
R43 1K
9 10
PA5
R42 1K R41
Hình P3_2.7:Môđun Led 7 đoạn
III.2.2.5 Switch DIP-8: được kết nối như hình sau, có ký hiệu là SW10
1 11
2 6 12 16
D0 D2 D4 D6
OE LE
Q0 Q2 Q4 Q6
R40
4.7K R50
4.7K
PC3(TMS)
R53
4.7K R58
Hình P3_2.8:Môđun Switch DIP-8
III.2.2.6 Ma trận LED 5x7: được kết nối như hình sau, có ký hiệu là U6
PA4 PC4(TDO)
R19 R18
R14 PA2
PC2(TCK)
PA0 PC1
R16 U6
MATRIX 5x7 (2 COLORs)
1 2
3 4
5 6
7
8
9 10
11
12 13
14 15 16 17 18
1 2
3 4
5 6
7 8
9 10
11
12 13
14 15 16 17 18
PA3
Hình P3_2.9:Môđun Ma trận LED 5x7
Trang 8III.2.3 Môđun giao tiếp theo chuẩn UART
Môđun này được thiết kế để truyền thông giữa máy tính với vi điều khiển thông qua chuẩn UART Môđun này được kết nối như hình sau, có ký hiệu là DB9
C1 104
TxD
C4 104
13 14
15 7 6 2 8 16
12 11 1 10 3 4 9 5
R1I T1O
DB9
5
2 3 6
4
1
8
C2 104
RxD
VCC
Hình P3_2.10:Môđun UART/ISP
III.2.4 Môđun điều khiển động cơ DC và động cơ bước (STEP MOTOR)
Dưới đây là sơ đồ mạch được thiết kế để ghép nối động cơ DC và động cơ bước với Vi điều khiển
VCC DK1A
C11 104
C9 104
15
VCC 1
DK2A DK2B
GND DK1B
LM7805 1
3 VI
OUT1A J1
L298
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
VCC OUT2B VCC OUT1B
OUT2A
C10 100u
Hình P3_2.11:Môđun động cơ DC
Trang 91 2 3 4
+12V
J9 1 2 3 4
J11
1 2 3
J7 1 2 3 4
U1
ULN2803
1 2 3 4 5 6 7 8
12 13 14 15 16 17
18
1 2 3 4 5 6 7 8 GND 101112 13 14 15 16 17 18
J10
1 2 3 4
Hình P3_2.12:Môđun động cơ bước
III.2.5 Môđun giao tiếp theo chuẩn I 2 C
Môđun này được thiết kế để giao tiếp giữa vi điều khiển với các chip ngoại vi như: EEPROM, Real Time Clock(RTC), thông qua chuẩn giao tiếp I2C
U9
DS1307
8 1
2
3 4
7
5 6
VCC X1
X2 VBAT GND SQW
SDA SCL
VCC
U7
PIN 3V
1 2
R12 4K7
D12 LED Y2
U10
24C64
8
1 2 3
4 7
5 6
VCC
A0 A1 A2 GNDWPSDASCL
R1 300R
R2 4K7
PC1 PC0
J4
CONG TAC
8 7 6 5
1 2 3 4
Hình P3_2.13:Môđun I2C
Trang 10D3 LED
R8 1k
C5 100uF/16V
C6 104
VCC
U8
USB_B
1 2 3
4
D+
GND VCC D-
2 4 6 8 10
PC2(TCK) PC5(TDI) PC3(TMS)
Hình P3_2.16:Môđun debugger
Trang 11-Môđun ISP Programer: dùng để nạp chương trình vào vi điều khiển
PB6 RST PB5
6 8 10
Hình P3_2.17:Môđun ISP Programer
IV Chương trình CodeVisionAVR
Đây là chương trình hỗ trợ lập trình cho vi điều khiển AVR bằng ngôn ngữ C, nó hỗ trợ nhiều thư viện lập trình, thuận lợi cho việc phát triển các ứng dụng lớn trên AVR Khởi động chương trình CodeVisionAVR bằng cách click chuột vào ICON
của CodeVision trên Desktop hoặc vào đường dẫn sau:
Hình P3_2.18: Khởi động chương trình CodeVisionAVR
Trang 12Xuất hiện cửa sổ chính của chương trình CodeVisionAVR như sau:
Hình P3_2.19: Cửa sổ chính của chương trình CodeVisionAVR
Tạo Project mới chọn File -> New sẽ xuất hiện cửa sổ Create New File
Trang 13Hình P3_2.20: Khởi tạo cấu hình cho chip và thiết bị ngoại vi
Sau khi đã khởi tạo xong cho chip và thiết bị ngoại vi chúng ta lưu lại cấu hình bằng cách chọn File -> Generate, Save and Exit
Sau đó xuất hiện cửa sổ yêu cầu lưu file source của project, gồm 3 file có tên mở rộng như sau: *.c, *.prj, *.cwp
Trang 14Hình P3_2.21: Lưu file source của project
Sau khi đã lưu các file source của project sẽ xuất hiện cửa sổ quản lý project
Hình P3_2.22: Cửa sổ quản lý project
Chương trình CodeVisionAVR sẽ tạo code mẫu, trong đó có đầy đủ code cần thiết mà chúng ta đã khởi tạo trước đó Đoạn code mẫu như sau:
Trang 15/*****************************************************
This program was produced by the
CodeWizardAVR V2.03.4 Standard
Automatic Program Generator
© Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l
Chip type : ATmega32
Program type : Application
Clock frequency : 16.000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 512
// Declare your local variables here
// Input/Output Ports initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
Trang 16// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon
// OC1B output: Discon
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80;
Trang 17Từ cửa sổ này chúng ta tiến hành viết code (bằng ngôn ngữ C), biên dịch và nạp vào vi điều khiển
-Để biên dịch code chương trình, chúng ta chọn Project -> Compile (F9)
Build (Shift+F9) và Build All (Ctrl+F9)
Hình P3_2.23: Cửa sổ biên dịch code chương trình
-Nạp vào chip: trước khi nạp vào chip chúng ta cần thiết lập một số thông số như
+Chọn loại mạch nạp: Atmel STK500/AVRISP
+Chọn Port giao tiếp: tuỳ theo máy tính nhận diện bộ STK500 ở port nào thì chúng ta chọn đúng port giao tiếp
Hình P3_2.24: Cấu hình thông số nạp vào chip vi điều khiển
Để nạp vào chip chúng ta chọn Tools -> Chip Programmer sẽ xuất hiện cửa sổ như hình bên dưới Sau đó chọn Program -> FLASH
Trang 18Hình P3_2.25: Cửa sổ nạp vào chip vi điều khiển
Trang 19Bài 2: ĐIỀU KHIỂN VÀO RA (I/O) VỚI LED ĐƠN
I Mục đích
-Hiểu rỏ và cấu hình được các thanh ghi của một port dữ liệu Cụ thể đối với PortA thì phải hiểu được các thanh ghi sau: DDRA, PINA, PORTA Tương tự đối với các port khác Khởi tạo được CPU hoạt động với cấu hình tối thiểu nhất -Hiểu được schematic của các môđun I/O như: LED đơn, Switch DIP-8
-Điều khiển được các port của chip AVR hoạt động như các port vào/ra dữ liệu -Điều khiển các LED đơn trên KIT theo ý muốn thông qua các port vào/ra của AVR
1 Cấu hình khởi tạo cho vi điều khiển ATMega32 hoạt động với thạch anh 16Mhz
2 Cấu hình PORT A và PORT B là xuất dữ liệu ra, PORT C là nhập dữ liệu
3 Sáng tất cả các LED đơn
4 Sáng 4 LED đơn D4-D7
5 Cho các LED đơn sáng từ phải sang trái
6 Đọc dữ liệu 8 bit trên SW10 và xuất ra 8 LED đơn (D4-D11)
III Cơ sở lý thuyết
Tất cả các port của AVR đều có chức năng Read-Modify-Write (Đọc-Ghi và Chỉnh sửa), được sử dụng như các port vào/ra Trong AVR có sẵn mức điện áp
ra ở các chân đủ để điều khiển LED trực tiếp Thêm vào đó ở mỗi chân của chip AVR đều có diot phân cực nghịch và tụ điện lọc thành phần AC
Chức năng cơ bản của các PORT là các cổng và/ra số, input hay output là dựa vào thiết lập ở thanh ghi DDRx, có thể thiết lập từng chân là input hay output (0
là input, 1 là output) Các chân của các port vào/ra ngoài chức năng thông thường là các cổng và/ra số, nó còn có thể có các chức năng khác (xem datasheet của từng loại vi điều khiển)
Trang 20III.1 Các thanh ghi dùng cho điều khiển các Port vào ra
Khi xem xét đến các cổng I/O của AVR thì ta phải xét tới 3 thanh ghi sau:
Hình P3_2.26: Các thanh ghi điều khiển các port vào/ra
Trong đó x cho biết tên port trong vi điều khiển là A, B, C, D,
Các thanh ghi bất kỳ của AVR bây giờ được xem như một biến kiểu 1 byte và ta
có thể truy xuất như một biến bình thường
a.Thanh ghi hướng dữ liệu DDRn
Định trạng thái (hướng dữ liệu) vào/ra của một PORTx bất kỳ, bit có giá trị bằng
0 là đọc dữ liệu, bit có giá trị bằng 1 là xuất dữ liệu
-Để cấu hình một port x bất kỳ là đọc dữ liệu: DDRx = 0x00;
-Để cấu hình một port x bất kỳ là xuất dữ liệu: DDRx = 0xFF;
Trên một port 8 bit bất kỳ cho phép chúng ta có thể cấu hình cho 3 bit là đọc dữ liệu từ ngoài vào và 5 bit còn lại là xuất dữ liệu ra
b Thanh ghi nhập/xuất dữ liệu PORTx và PINx
-Để xuất dữ liệu 8 bit ra 1 port (đã được cấu hình là xuất dữ liệu):
PORTx = data; //data phải là dữ liệu kiểu 1 byte
-Để đọc dữ liệu từ 1 port (đã được cấu hình là đọc dữ liệu vào):
data = PINx; //data phải là biến kiểu 1byte
Trên một port bất kỳ, đã được cấu hình là xuất 8 bit dữ liệu ra ngoài, như vậy có thể trong một lệnh xuất dữ liệu ra ngoài ta có thể xuất 1 bit dữ liệu mà thôi còn 7 bit dữ liệu còn lại không bị ảnh hưởng
Ngoài ra, chúng ta có thể sử dụng CodeWizardAVR để thiết lập cấu hình cho các PORT
Vi điều khiển AVR
Port x DDRx PORTx PINx
0 1 1 0 1 0 0 1
Trang 21Hình P3_2.27: Thiết lập cấu hình cho các PORT bằng CodeWizardAVR
Ví dụ như trên hình:các bit 0,1,2,4,7 của PORTA làm chân ra có trở kéo, còn các bit còn lại làm chân vào Khi đã thiết lập xong thì các bit 0,1,2,4,7 sẽ có thể xuất
dữ liệu ra còn các bit còn lại có thể nhận dữ liệu vào
c.Một số ví dụ khởi tạo PORT
-Ta muốn ghi dữ liệu giá trị logic ’0’ ra PORTA.0 để bật tắt một Led thì:
-Nếu ta thiết lập PORTA làm cổng vào và giá trị hiện thời của PORTA là 55
thì sau câu lệnh đọc giá trị từ PORTA: x=PORTA thì x=0x55
-Khi thiết lập PORTA làm cổng ra thì khi reset giá trị của PORTA là
PORTA=0xFF
Trang 22- Khi thiết lập PORTA làm cổng vào thì khi reset giá trị của PORTA là
PORTA=0x00
Việc thiết lập cổng vào ra là một việc quan trọng vì tùy theo mục đích sử dụng các cổng nào làm cổng vào ra, thì ta phải thiết lập đúng lúc đó mới có thể sử dụng được
III.2 Cấu hình phần cứng của các PORT, LED đơn và Switch trên KIT AVR
a Các port của vi điều khiển Atmega32
Bảng P3_2.5:Bảng ký hiệu các PORT của Atmega32
Số
TT
Port của Atmega32
Ký hiệu thiết bị
J11
PORTC
1 2 3 4 5 6 7 8
PC2(TCK)
PD5
PD2 PD3 RxD
PD7
PD4 PD6
J12
PORTD
1 2 3 4 5 6 7 8
TxD
J10
PORTB
1 2 3 4 5 6 7 8
PB2 PB0
PB7
PB3 PB1 PB5 PB4
PA7
PA0 PA1 PA3 PA2 PA5
J13
PORTA
1 2 3 4 5 6 7 8 PA4
Hình P3_2.28: Các port của vi điều khiển Atmega32
b Led đơn: có 8 led đơn được tích hợp trên KIT
Bảng P3_2.6: Bảng ký hiệu LED đơn
Trang 23PA6 PB0
D5
LED
PA4 PA0
2 5 6 9 12 15 16 19
D0 D1 D2 D3 D4 D5 D6 D7
OELE
Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7
D7
LED
R9 R10 R7
Hình P3_2.29: Sơ đồ kết nối 8 LED đơn trên KIT
c Switch DIP-8: được kết nối như hình sau, có ký hiệu là SW10
2 5 9 12 15 19
D0 D1 D3 D4 D6
OE LE
Q0 Q1 Q3 Q4 Q6
R40
4.7K R50
4.7K
PC3(TMS)
R53
4.7K R58
IV.1 Khởi tạo CPU
Thực hiện các bước để tạo project mới (xem hướng dẫn ở mục IV của Bài 1).Lưu ý ở bước khởi tạo CPU, từ cửa sổ CodeWizardAVR chúng ta chọn thẻ Chip và chọn cấu hình chip như sau:
Trang 24-Chip: Atmega32
-Clock: 16MHz
Hình P3_2.31: Khởi tạo CPU
IV.2 Khởi tạo PORT
Từ cửa sổ CodeWizardAVR chúng ta chọn thẻ Ports và cấu hình cho Port A, Port B là xuất dữ liệu ra, PORT C là nhập dữ liệu Để cấu hình Port A chúng ta chọn thẻ PortA, trong mỗi Port có 2 thông số cần cấu hình:
-Data Direction: cấu hình hướng dữ liệu (chứa trong thanh ghi DDRx)
-Pullup/Output Value: giá trị xuất mặc định (chứa trong thanh ghi PORTx)
Hình bên dưới cho biết thiết lập cấu hình của Port A với hướng dữ liệu là xuất (0xFF)
và giá trị xuất là 0x00 Port B được thiết lập cấu hình tương tự Port A
Trang 25
(a) (b)
Hình P3_2.32: (a) Khởi tạo Port A, (b) Khởi tạo Port C
Sau khi thiết lập xong thì 2 thanh ghi chứa các giá trị đã thiết lập cấu hình như sau:
IV.3 Viết code chương trình
Sau khi đã hoàn tất quá trình tạo project và khởi tạo CPU và Port theo yêu cầu, chúng ta tiến hành viết code để nạp vào vi điều khiển để điều khiển những thiết bị ngoại vi theo yêu cầu
Trang 26Gợi ý viết code như sau:
delay_ms(500);
};
}
IV.4 Biên dịch code và nạp vào vi điều khiển
Sau khi đã viết code xong, chúng ta tiến hành biên dịch và nạp vào vi điều khiển
-Để biên dịch chương trình chúng ta chọn: Project -> Compile hoặc nhấn F9
Trong quá trình biên dịch nếu code bị lỗi sẽ được thông báo lỗi thông qua cửa sổ ở hình sau nó cho biết số lỗi Ngoài ra chương trình còn cho chúng ta biết một số thông số khác như:
Bit variables size: 0 byte(s)
Data Stack area: 60h to 25Fh
Data Stack size: 512 byte(s)
Estimated Data Stack usage: 0 byte(s)
RAM Global variables size: 0 byte(s)
Hardware Stack area: 260h to 85Fh
Hardware Stack size: 1536 byte(s)
Heap size: 0 byte(s)
EEPROM usage: 0 byte(s), 0.0% of EEPROM
Trang 27
Hình P3_2.33: Cửa sổ thông báo lỗi khi biên dịch
-Để nạp vào chip chúng ta chọn Tools -> Chip Programmer sẽ xuất hiện cửa sổ như hình bên dưới Sau đó chọn Program -> FLASH
Hình P3_2.34: Cửa sổ nạp vào chip
Trang 28Bài 3: ĐIỀU KHIỂN LED 7 ĐOẠN
I Mục đích
-Hiểu rỏ và cấu hình được các thanh ghi của một port dữ liệu Cụ thể đối với PortA thì phải hiểu được các thanh ghi sau: DDRA, PINA, PORTA Tương tự đối với các port khác Khởi tạo được CPU hoạt động với cấu hình tối thiểu nhất -Hiểu được schematic của các môđun I/O như: LED 7 đoạn, Switch DIP-8 -Biết phương pháp quét LED 7 đoạn
-Điều khiển các LED 7 đoạn trên KIT theo ý muốn thông qua các port vào/ra của AVR
1.Đưa số bất kỳ ra LED 7 đoạn
2.Phản ánh trạng thái của SW10 lên LED 7 đoạn (J21)
3.Hiển thị một số có kiểu là integer được đếm tăng dần ra 4 LED 7 đoạn
4.Hiển thị trên led 7 đoạn (J21) các số thập phân từ 0 – 9 được điều chỉnh từ các Switch SW10
5 Hiển thị trên led 7 đoạn (J22) các số thập lục phân từ 0 – F được điều chỉnh từ
các Switch SW10
III Cơ sở lý thuyết
III.1 Led 7 đoạn (7-SEGMENT LED)
Bảng P3_2.7: Bảng ký hiệu LED 7 đoạn
4 led 7 đoạn anot chung, 4 chân anot chung (chân dương) được nối với 4 transitor
để ta có thể quét led sử dụng 4 chân của PORTB, các chân điều khiển sáng các thanh còn lại được nối song song nhau và đưa vào PORTA của AVR thông qua chốt U13 và có thứ tự như sau: Từ bít 0 -> 6 ứng với từ A -> G Bít thứ 7 là dấu chấm
Trang 29Vì có 4 led nên ta có thể hiển thị đến hàng nghìn Do đó đầu vào của ta là một số bất kì lớn tới hàng nghìn Ta phải tách lấy từng số hàng nghìn, trăm, chục, đơn vị rồi đưa vào 4 biến rồi tùy vào 4 biến số đó mà ta đưa ra từng led Quét led ta làm như sau: đưa PORTB.7 xuống 0 để bật nguồn cho led hàng đơn vị, đẩy trị số hàng đơn vị ra PORTA, trễ một khoảng thời gian -> đưa PORTB.7 lên một để tắt nguồn led đơn vị, đưa PORTB.6 xuống 0 để bật nguồn cho led hàng chục, đẩy giá trị hàng chục ra PORTA, trễ một khoảng thời gian, … Cứ làm như vậy đến hàng nghìn Như vậy tại một thời điểm chỉ có một led sáng chỉ bằng 1/3 thời gian led tắt, nhưng do tần số bật led nhanh, mắt người lưu ảnh nên vẫn thấy led sáng như lúc nào cũng bật nguồn cho led.
G U13
Q8 PNP
C J22
LED 1
4 5 7
9
10 D
F
J23
LED 1
4 5 7
9
10 E
D A
Q9 PNP
Q7 PNP PB6
DP G
C
PA6
R43 1K
J21
LED 1
4 5 7
9 10
PA5
R42 1K R41
4 5 7
9
10 D
Hình P3_2.35:Môđun Led 7 đoạn
III.2 Switch DIP-8: được kết nối như hình sau, có ký hiệu là SW10
PC6
R51
4.7K
PC4(TDO) U16
74LS373
3 7 13 17
1 11
2 6 12 16
D0 D2 D4 D6
OE LE
Q0 Q2 Q4 Q6
R40
4.7K R50
4.7K
PC3(TMS)
R53
4.7K R58
SW DIP-8
PC1
Hình P3_2.36:Môđun Switch DIP-8
Trang 30IV Thực hành
-Giải mã các giá trị thập phân tùy vào kết nối của led 7 đoạn, để biết bít nào ứng với thanh nào của led 7 ta tiến hành kích hoạt từng bít để biết Sau khi biết rõ cấu trúc kết nối của led 7 ta tiến hành giải mã 10 số và bỏ các giá trị này vào một mảng, sau đó muốn hiển thị số nào ta chỉ việc truy xuất đến giá trị tương ứng trong mảng và xuất ra led 7, led 7 sẽ hiển thị đúng giá trị ta muốn
-Khai báo port kết nối với SW là input, sau khi đã khởi tạo là input thì bất cứ lúc nào ta tác động lên SW thì giá trị cũng được input vào chip, ta tìm giá trị tương ứng của giá trị này trong mảng giá trị giải mã ở trên, và xuất ra led 7 đoạn
-Sử dụng kỹ thuật quét led
-Các bước khởi tạo tương tự bài 2 Lưu ý: trong bài này vì nếu đưa PORTB và PORTA lúc khởi tạo bằng 0x00 thì tất cả các led sẽ sáng do đó tại các câu lệnh khởi tạo cho hai PORT này các bạn hãy gán cho nó giá trị 0xFF như sau:
switch(x) // Tuy thuoc vao bien dau vao ma dua du lieu ra tu 0 9
{ //logic 1 tat led, logic 0 bat led
case 0: { PORTA=0xC0; break; } // So 0
case 1: { PORTA=0xF9; break; } // So 1
case 2: { PORTA=0xA4; break; } // So 2
case 3: { PORTA=0xB0; break; } // So 3
case 4: { PORTA=0x99; break; } // So 4
case 5: { PORTA=0x92; break; } // So 5
case 6: { PORTA=0x82; break; } // So 6
case 7: { PORTA=0xF8; break; } // So 7
case 8: { PORTA=0x80; break; } // So 8
case 9: { PORTA=0x90; break; } // So 9
}
}
Trang 31void hienthi(int n)
{
int a,b,c,d;
// Lay cac so cac hang
a= n/1000; // lay hang nghin
b=(n-a*1000)/100; // lay hang tram
c=(n-a*1000-b*100)/10; // lay hang chuc d=(n-a*1000-b*100-c*10);// lay hang don vi // Quet led
PORTB=0xEF;// led dau tien
daydulieu(d);// day ra hang don vi
delay_ms(10);// tre
PORTB=0xFF;// tat toan bo led
PORTB=0xDF;//led thu hai
daydulieu(c);// dua ra hang chuc
Trang 32Bài 4: ĐIỀU KHIỂN LED MA TRẬN 5x7
I Mục đích
-Hiểu được schematic của các môđun I/O như: LED ma trận 5x7
-Biết cách giải mã và phương pháp hiển thị trên LED ma trận
-Điều khiển các LED ma trận trên KIT theo ý muốn thông qua các port vào/ra của AVR
II Yêu cầu
1 Tạo bảng giãi mã các số thập phân từ 0-9, các chữ cái A-Z
2 Hiển thị lần lượt các số từ 0-9, mỗi lần hiển thị cách nhau đúng 3 giây
3 Hiển thị lần lượt các số từ A-Z, mỗi lần hiển thị cách nhau đúng 3 giây
4 Hiển thị lần lượt các ký tự V-I-D-I-E-U-K-H-I-E-N
5 Di chuyển chuỗi “AB” trên ma trận Led từ phải sang trái
III Cơ sở lý thuyết
Ma trận LED 5x7 được kết nối như hình sau, có ký hiệu là U6
PA4 PC4(TDO)
R19 R18
R14 PA2
PC2(TCK)
PA0 PC1
R16 U6
MATRIX 5x7 (2 COLORs)
1 2
3 4
5 6
7
8
9 10
11
12 13
14 15 16 17 18
1 2
3 4
5 6
7 8
9 10
11
12 13
14 15 16 17 18
PA3
Hình P3_2.37: Môđun Ma trận LED 5x7
Ma trận LED gồm các LED phát quang bố trí thành hàng và cột trong một võ Các tín hiệu điều khiển hàng PA0 - PA6 ( Port A ) nối vào Anode của tất cả các LED trên cùng một hàng Các tín hiệu điều khiển cột PC0 -PC4 (Port B) nối vào Cathode của tất cả các LED trên cùng một cột Khi có 1 cặp tín hiệu điều khiển hàng và cột ví dụ như khi PA0 = 1 và PC0 = 1, các Anode của hàng LED thứ nhất RW1 (hàng trên cùng) được cấp điện thế cao Đồng thời các Cathode của cột LED thứ nhất CL1 (bìa trái) được cấp thế thấp.Tuy nhiên chỉ có LED 1 là sáng vì nó có đồng thời thế cao trên Anode và thế thấp trên Cathode Như vậy khi có 1 cặp tín hiệu điều khiển hàng và cột thì chỉ có duy nhất 1 LED tại điểm hàng và cột gặp nhau là sáng Trên cơ sở cấu trúc
Trang 33như vậy ta có thể xây dựng được bảng ma trận LED với số lượng LED lớn hơn ví dụ như trong các bảng quang báo
Hình P3_2.38: Sơ đồ kết nối Ma trận LED 5x7
Trong trường hợp ta cần hiển thị đồng thời 1 số LED trong ma trận để có thể hiển thị một ký hiệu nào đó ví dụ chữ ‘L‘ trên ma trận LED Khi đó ta thấy các LED ở cột bìa trái (CL1) sáng và các LED ở hàng dưới cùng (RW7) sáng Nếu trong hiển thị tĩnh ta phải đặt tất cả các PA0 đến PA6 và PC0-4 ở mức cao, lúc này sẽ làm sáng các ở hàng RW7 và cột CL1 nhưng khi đó điều gì sẽ xảy ra? Ta thấy rõ ràng là khi đó thì các LED khác trong ma trận cũng được cấp áp cao vào Anode và áp thấp vào Cathode do
đó nó sẽ sáng tất cả các LED trong ma trận Vì vậy trong điều khiển ma trận LED ta
Trang 34không thể sử dụng phương pháp hiển thị tĩnh mà phải dùng phương pháp quét (hiển thị động) Nghĩa là tiến hành cấp tín hiệu điều khiển theo dạng xung theo kiểu quét cho các hàng và cột cần hiển thị Tần số quét nhỏ nhất cho một chu kỳ cần khoảng 20Hz (50ms) nhằm bảo đảm cho mắt thấy các LED sáng đều không nháy Như vậy để hiển thị được chữ L có thể điều khiển tuần tự như trong bảng sau:
Nhịp 1 : PA0 - PA6 = 1, PC0 = 1 ; Sáng cột LED thứ nhất CL1
Nhịp 2 : PA0 - PA5 = 0, PA6 = 1, PC1 = 1 ; Sáng LED hàng RW7 và cột CL2
Nhịp 3 : PA0 - PA5 = 0, PA6 = 1, PC2 = 1 ; Sáng LED hàng RW7 và cột CL3
Nhịp 4 : PA0 - PA5 = 0, PA6 = 1, PC3 = 1 ; Sáng LED hàng RW7 và cột CL4
Nhịp 5 : PA0 - PA5 = 0, PA6 = 1, PC4 = 1 ; Sáng LED hàng RW7 và cột CL5
Nhịp 6 : Quay lại giống nhịp 1
(từ nhịp 1 đến nhịp 6 là 1 chu kỳ quét tối thiểu phải là 20Hz)
-Xem kỹ thuật quét led như hướng dẫn bên trên
- Tính toán dữ liệu hiển thị
Chữ ‘A’: 7Eh, 09h, 09h, 09h,7Eh
Chữ ‘B’: 7Fh, 49h,49h,49h, 36h
Giữa chữ A và B có một cột trống để phân biệt
->Chuỗi “AB”: 7Eh, 09h, 09h, 09h, 7Eh, 00h, 7Fh, 49h,49h,49h, 36h
Có thể thêm khoảng trắng trước và sau chuỗi để chuỗi hiện ra từ từ
->Chuỗi “ AB ”: 00h, 00h, 00h, 00h, 00h, 7Eh, 09h, 09h, 09h, 7Eh, 00h,
7Fh, 49h,49h,49h, 36h,00h, 00h, 00h, 00h
Như vậy, một ký tự cần hiển thị trên ma trận Led cần 6 byte và 5 byte 00h đầu chuỗi, 3
50*6 + 5 + 3 = 308 byte
Trang 35Quá trình hiển thị và cho chữ chạy mô tả như hình vẽ:
Hình P3_2.39: Quá trình hiển thị chữ chạy “AB”
Tóm tắt:
Lần 1: hiển thị từ pa[0] ÷ pa[4]
Lần 2: hiển thị từ pa[1] ÷ pa[5]
Î lần j: hiển thị từ pa[j] ÷ pa[j+5]
Lần 16: hiển thị từ pa[15] ÷ pa[19]
Trang 36-Hãy tạo một Project với tên gọi MATRIX57, với yêu cầu hiển thị các số từ 0 -> 9 trên Led ma trận
Code gợi ý để viết chương trình cho vi điều khiển:
#define DATA_DDR DDRA
#define CTRL_PORT PORTC //PORTC is connected to control lines of
số 8 bits, như thế chúng ta cần tổng cộng 1115 byte cho bảng font trong khi kích thước SRAM của chip ATmega32 chỉ là 2KB (2048 byte) Nếu dùng SRAM chứa bảng font
Trang 37sẽ rất phí phạm vì đây là 1 bảng tĩnh, giá trị trong bảng hoàn toàn không thay đổi mà chỉ được truy xuất đọc Vì thế chúng ta có thể tận dụng bộ nhớ chương trình (Flash) để lưu bảng font này Dòng đầu tiên trong List 1 chúng ta include header “pgmspace.h” để
sử dụng các thao tác trên bộ nhớ chương trình Tiếp theo chúng ta khai báo 1 mảng tĩnh
có tên font7x5 với kiểu dữ liệu là prog_char tức là kiểu char nhưng chứa trong bộ nhớ chương trình (Program memory) Giá trị chứa trong mảng font7x5 chính là dữ liệu của bảng font, thực chất mảng font7x5 là mảng 1 chiều liên tục, việc tách ra trên nhiều dòng
có mục đích giúp người đọc dễ hình dung khi truy cập các giá trị của mảng để xuất ra sau này Bạn hãy hiểu rằng cứ một tổ hợp 5 số sẽ tạo thành một symbol hiển thị cho ma trận LED Dữ liệu trong bảng font được sắp xếp theo trình tự ASCII và để tạo điều kiện thuận lợi khi truy xuất bảng font theo mã ASCII của ký tự cần hiển thị Tuy nhiên cần chú ý là bảng font được bắt đầu cho symbol có mã ASCII là 32 chứ không bắt đầu từ
mã ASCII 0, vì thế khi truy cận bảng font từ mã ASCII chúng ta cần lấy mã ASCII trừ
đi 32 để được vị trí chính xác trong bảng
Tiếp theo chúng ta sẽ tìm hiểu chương trình chính, dòng 3 trong list 2 include file font.h để sử dụng bảng font trong chương trình chính Các dòng từ 5 đến 9 định nghĩa các PORT kết nối với ma trận LED, PORTD là Data bus trong khi PORTC là control lines Chương trình con void DOTputChar75(uint8_t chr) trong dòng 11 là thủ tục đọc
dữ liệu từ bảng font và hiển thị trên ma trận LED Tham số chr của chương trình này chính là mã ASCII của ký tự cần hiển thị trên ma trận LED Dòng 12 khai báo 2 biến phụ, trong đó biến line chứa tín hiệu điều khiển cho các đường Control Dòng 13 khai báo một biến tạm tchr dùng chứa địa chỉ dữ liệu cần lấy ra từ bảng font để xuất ra các đường Data, vì mã ASCII là một số 8 bit trong khi số lượng dữ liệu trong bảng font lớn gấp 5 lần số lương ký tự, vì thế cần khai báo biến tchr có kiểu dữ liệu 16 bit Nội dung chính của đoạn chương trình này nằm trong vòng lặp for, biến i đại diện cho số thứ tự
của các chân Control được cho chạy từ 0 đến 4, trong dòng 15 “CTRL_PORT=line;”
xuất tín hiệu điều khiển ra CTRL_PORT tức ra các chân C Do biến line được khởi tạo
bằng 1 nên ở lần lặp đầu tiên giá trị CTRL_PORT=0b00000001, tức chân C0 ở mức
cao trong khi các chân còn lại ở mức thấp, cột đầu tiên được chọn Sau khi 1 cột đã
được chọn, dòng 16 “DATA_PORT=~ font7x5[((tchr - 32) * 5) + i]);” đọc và xuất dữ
liệu từ bảng font ra các chân Data Trước hết là cách tính địa chỉ của dữ liệu trong bảng font Như trình bày trong phần giải thích cho bảng font, bảng này được chúng ta bắt đầu
Trang 38từ ký tự có mã 32 nên chúng ta cần trừ đi 32 để tham chiếu đến vị trí chính xác trong bảng font: tchr-32 Ví dụ muốn hiển thị ký tự có mã chr = 48 (mã của ký tự ‘0’), vị trí của tổ hợp dữ liệu tạo nên số ‘0’ được chứa trong bảng font ở vị trí 16, giá trị này được tính 48-32=16 Tiếp theo, do mỗi ký tự được tạo thành từ 5 số nên địa chỉ thực chất của
số đầu tiên trong tổ hợp sẽ là (tchr-32)*5 Để di chuyển trong phạm vi 5 dữ liệu ứng với 6 cột của ma trận LED, biến i được cộng dồn vào địa chỉ này và chúng ta có: tchr -
32) * 5) + i Để đọc dữ dữ liệu dạng byte từ bộ nhớ chương trình, chúng ta cần dùng
hàm pgm_read_byte, hàm này được định nghĩa trong header pgmspace.h được khai báo
trong file font.h Như vậy sau khi thực hiện “font7x5[((tchr - 32) * 5) + i])” chúng ta
thu được dữ liệu 1 byte tương ứng với cột thứ i của ký tự chr từ bảng font, việc cuối cùng có thể là xuất giá trị này ra DATA_PORT Tuy nhiên, trước khi xuất byte đọc được ra DATA_PORT, chúng ta cần đảo các bit của byte này bằng toán tử “~”, lý do được giải thích là do các LED trong ma trận trong ví vụ này có các hàng nối với cực âm Cathode, để một LED sáng thì giá trị cần cấp cho bit D tương ứng là 0 nghĩa là ngược lại so với cách chúng ta tạo bảng font (sáng là 1) Chỉ bằng một thao tác đơn giản là toán tử “~” chúng có thể dễ dàng vượt qua trở ngại này Trong trường hợp ma trận LED
có các hàng nối với cực dương Anode thì chúng ta không cần đảo giá trị đọc về Dòng
17 thực hiện dịch chuyển giá trị của biến line sang trái 1 vị trí, việc làm có tác dụng chuẩn bị cho lần kế tiếp chân C kế tiếp sẽ được kích Hàm delay trong dòng 18 giúp các LED trong cột hiện tại sáng trong 1 khoảng thời gian trước khi chuyển qua cột khác Chương trình chính trong ví dụ này thật sự rất đơn giản, chúng ta trước hết cần khởi động hướng xuất nhập cho các PORT và sau đó gọi hàm DOTputChar75() trong vòng lặp vô tận while(1) Ở ví dụ trên, ký tự ‘4’ được xuất ra và kết quả hiển thị như trong hình 3 Chú ý là hàm DOTputChar75() chỉ “quét” qua các cột 1 lượt, vì thế muốn hiển thị một ký tự trong một khoảng thời gian chúng ta cần gọi hàm DOTputChar75() lặp lại trong khoảng thời gian đó
Trang 39Bài 5: HIỂN THỊ LCD 16x2
I Mục đích
điều khiển LCD bằng AVR cả 2 chế độ 8 bit và 4 bit
Từ module LCD 16x2 có thể mở rộng sang những module tương tự, ví dụ như module LCD 16x4, 40x2, …
II Yêu cầu
1 Khởi tạo giá trị ban đầu cho LCD
2 Viết một chương trình cho LCD để hiển thị một ký tự bất kỳ lên LCD
3 Viết một đoạn chương trình con để hiển thị một ký tự bất kỳ ra một vị trí bất kỳ
4 Dịch các ký tự từ trái sang phải trên LCD
III Cơ sở lý thuyết
III.1 Giới thiệu
Ngày nay, thiết bị hiển thị LCD (Liquid Crystal Display) được sử dụng trong rất nhiều các ứng dụng của VĐK LCD có rất nhiều ưu điểm so với các dạng hiển thị khác Nó có khả năng hiển thị kí tự đa dạng, trực quan (chữ, số và kí tự đồ họa), dễ dàng đưa vào mạch ứng dụng theo nhiều giao thức giao tiếp khác nhau, tốn rất ít tài nguyên hệ thống và giá thành rẽ …
LCD được chia sẵn thành từng ô và ứng với mỗi ô chỉ có thể hiển thị một ký tự ASCII Cũng vì lý do chỉ hiện thị được ký tự ASCII nên loại LCD này được gọi là Text LCD (để phân biệt với Graphic LCD có thể hiển thị hình ảnh) Mỗi ô của Text LCD bao gồm các “chấm” tinh thể lỏng, việc kết hợp “ẩn” và “hiện” các chấm này
sẽ tạo thành một ký tự cần hiển thị Trong các Text LCD, các mẫu ký tự được định nghĩa sẵn Kích thước của Text LCD được định nghĩa bằng số ký tự có thể hiển thị trên 1 dòng và tổng số dòng mà LCD có Ví dụ LCD 16x2 là loại có 2 dòng và mỗi dòng có thể hiển thị tối đa 16 ký tự Một số kích thước Text LCD thông thường gồm 16x1, 16x2, 16x4, 20x2, 20x4…Hình 1 là một ví dụ Text LCD 16x2
Trang 40Ký hiệu thiết bị
LCD2 LCD4
LCD1
J20
LCD
1 2 3 4 5 6 7 8
LCD0
LCD6
LCD2 LCD0 LCD7
VCC
LCD1 LCD5 R99330
LCD6 LCD5
7 8 9 10
11 12 13 14
15 16
LCD4 LCD7