92
Trang 1 MỤC LỤC CHƢƠNG 1: CÁC KHÁI NIỆM CƠ BẢN TRONG HỆ THỐNG NHÚNG ................ 3 1.1. Hệ nhúng ........................................................................................................... 3 1.2. Hệ thời gian thực ............................................................................................... 3 1.3. Biễu diễn số và dữ liệu ...................................................................................... 3 1.4. Cấu trúc phần cứng của hệ thống nhúng ............................................................ 4 1.5. Hệ điều hành nhúng và phần mềm nhúng .......................................................... 5 1.5.1. Hệ điều hành nhúng .................................................................................... 5 1.5.2. Hệ điều hành thời gian thực –RTOS: (Realtime Operationg System ) ......... 6 1.5.3. Phần mềm nhúng ........................................................................................ 7 1.6. Quy trình thiết kế hệ thống nhúng ..................................................................... 8 1.7. Mô hình hệ thống nhúng .................................................................................. 10 CHƢƠNG 2: HỌ VI ĐIỀU KHIỂN ARM ................................................................. 11 2.1. Tổng quan ....................................................................................................... 11 2.2. Cơ chế Pipeline ............................................................................................... 12 2.3. Các thanh ghi .................................................................................................. 13 2.4. Thanh ghi trạng thái chƣơng trình hiện hành ................................................... 14 2.5. Các mode ngoại lệ ........................................................................................... 15 2.6. Tập lệnh ARM 7.............................................................................................. 16 2.6.1. Các lệnh rẽ nhánh ..................................................................................... 18 2.6.2. Các lệnh xử lý dữ liệu ............................................................................... 18 2.6.3. Các lệnh truyền dữ liệu ............................................................................. 19 2.6.4. Lệnh SWAP ............................................................................................. 20 2.7. Ngắt mềm (SWI – Software Interrupt Instruction) ........................................... 20 2.8. Đơn vị MAC (Multiply Accumulate Unit (MAC) ............................................ 21 2.9. Tập lệnh THUMB ........................................................................................... 21 2.10. Phần mềm phát triển và công cụ phần cứng ................................................... 23 2.10.1. Cấu trúc file start up ............................................................................... 23 2.10.2. Công cụ phần cứng ................................................................................. 25 2.10.3. Cách viết chƣơng trình C với tập lệnh ARM và tập lệnh THUMB .......... 25 2.11. Cấu trúc bên trong ......................................................................................... 26 2.11.1. Bản đồ bộ nhớ ........................................................................................ 26 2.11.2. Lập trình thanh ghi ................................................................................. 27

Lap Trinh ARM - Ngo Vinh

Embed Size (px)

Citation preview

Page 1: Lap Trinh ARM - Ngo Vinh

Trang 1

MỤC LỤC

CHƢƠNG 1: CÁC KHÁI NIỆM CƠ BẢN TRONG HỆ THỐNG NHÚNG ................ 3

1.1. Hệ nhúng ........................................................................................................... 3

1.2. Hệ thời gian thực ............................................................................................... 3

1.3. Biễu diễn số và dữ liệu ...................................................................................... 3

1.4. Cấu trúc phần cứng của hệ thống nhúng ............................................................ 4

1.5. Hệ điều hành nhúng và phần mềm nhúng .......................................................... 5

1.5.1. Hệ điều hành nhúng .................................................................................... 5

1.5.2. Hệ điều hành thời gian thực –RTOS: (Realtime Operationg System ) ......... 6

1.5.3. Phần mềm nhúng ........................................................................................ 7

1.6. Quy trình thiết kế hệ thống nhúng ..................................................................... 8

1.7. Mô hình hệ thống nhúng .................................................................................. 10

CHƢƠNG 2: HỌ VI ĐIỀU KHIỂN ARM ................................................................. 11

2.1. Tổng quan ....................................................................................................... 11

2.2. Cơ chế Pipeline ............................................................................................... 12

2.3. Các thanh ghi .................................................................................................. 13

2.4. Thanh ghi trạng thái chƣơng trình hiện hành ................................................... 14

2.5. Các mode ngoại lệ ........................................................................................... 15

2.6. Tập lệnh ARM 7 .............................................................................................. 16

2.6.1. Các lệnh rẽ nhánh ..................................................................................... 18

2.6.2. Các lệnh xử lý dữ liệu ............................................................................... 18

2.6.3. Các lệnh truyền dữ liệu ............................................................................. 19

2.6.4. Lệnh SWAP ............................................................................................. 20

2.7. Ngắt mềm (SWI – Software Interrupt Instruction) ........................................... 20

2.8. Đơn vị MAC (Multiply Accumulate Unit (MAC) ............................................ 21

2.9. Tập lệnh THUMB ........................................................................................... 21

2.10. Phần mềm phát triển và công cụ phần cứng ................................................... 23

2.10.1. Cấu trúc file start up ............................................................................... 23

2.10.2. Công cụ phần cứng ................................................................................. 25

2.10.3. Cách viết chƣơng trình C với tập lệnh ARM và tập lệnh THUMB .......... 25

2.11. Cấu trúc bên trong ......................................................................................... 26

2.11.1. Bản đồ bộ nhớ ........................................................................................ 26

2.11.2. Lập trình thanh ghi ................................................................................. 27

Page 2: Lap Trinh ARM - Ngo Vinh

Trang 2

2.11.3. Memory Acelerator Module (MAM) ...................................................... 27

2.11.4. PLL- Phase Locked Loop ....................................................................... 29

2.11.5. Bộ chia bus (VLSI Peripheral Bus Divider) ............................................ 32

2.12. Các cổng vào ra ............................................................................................. 33

CHƢƠNG 3: LẬP TRÌNH VI ĐIỀU KHIỂN ARM ................................................... 34

3.1. Hƣớng dẫn sử dụng phần mềm Keil C ............................................................. 34

3.2. Truy nhập các chân vào ra chung..................................................................... 42

Thí dụ 1: Viết chƣơng trình điều khiển led đơn sáng nhấp nháy ......................... 43

Thí dụ 2: Chƣơng trình hiển thị chữ trên LCD .................................................... 44

3.3. Lập trình ngắt .................................................................................................. 50

3.3.1. Chân Connect Block ................................................................................. 50

3.3.2. Các chân ngắt ngoài .................................................................................. 51

3.3.3. Cấu trúc ngắt ............................................................................................ 52

3.3.4. Ngắt FIQ .................................................................................................. 54

3.3.5. Kết thúc ngắt ............................................................................................ 56

3.3.6. Vecto IRQ ................................................................................................ 56

3.3.7. Kết thúc một ngắt IRQ .............................................................................. 57

3.3.8. Ngắt không có địa chỉ ............................................................................... 58

3.3.9. Kết thúc ngắt không địa chỉ ...................................................................... 59

3.4. Lập trình Timer ............................................................................................... 59

3.4.1. Các Timer ................................................................................................. 59

3.4.2. Đồng hồ thời gian thực (Real Time Clock - RTC) .................................... 67

3.5. Lập trình qua UART........................................................................................ 70

3.6. Giao diện I2C .................................................................................................. 78

3.7. Giao diện SPI .................................................................................................. 81

3.8. Chuyển đổi ADC và DAC ............................................................................... 83

3.8.1. Chuyển đổi ADC ...................................................................................... 83

3.8.2. Chuyển đổi D/A ........................................................................................ 85

3.9. Truyền dữ liệu qua CAN(Controller Area Network) ........................................ 85

TÀI LIỆU THAM KHẢO .......................................................................................... 92

Page 3: Lap Trinh ARM - Ngo Vinh

Trang 3

CHƢƠNG 1: CÁC KHÁI NIỆM CƠ BẢN TRONG HỆ THỐNG NHÚNG

(tổng số tiết: 3T, số tiết lý thuyết: 3T, số tiết thực hành: 0)

1.1. Hệ nhúng

Hệ nhúng là một phần hệ thống xử lý thông tin nhúng trong các hệ thống

lớn, phức hợp và độc lập. Thí dụ: ôtô, tủ lạnh, các thiết bị đo lƣờng, điều khiển,

truyền thông.

Là những tổ hợp của phần cứng và phần mềm để thực hiện một hoặc một

nhóm chức năng chuyên biệt, cụ thể (Trái ngƣợc với máy tính PC là đa năng).

Một hệ thống nhúng là một máy tính với chất lượng cao, yêu cầu về độ tin cậy

cao hơn các loại máy tính khác.

Các thiết bị PDAs, Web pad không phải là hệ thống nhúng.

1.2. Hệ thời gian thực

Chia làm 2 loại:

Thời gian thực cứng là khi hệ thống hoạt động với yêu cầu thoả mãn sự ràng

buộc trong khung thời gian cứng tức là nếu vi phạm thì sẽ dẫn đến hoạt

động của toàn hệ thống bị sai hoặc bị phá huỷ. Thí dụ: Lò phản ứng hạt

nhân,…

Thời gian thực mềm là khi hệ thống hoạt động với yêu cầu thoả mãn ràng

buộc trong khung thời gian mềm, nếu vi phạm và sai lệch nằm trong khoảng

cho phép thì hệ thống vẫn có thể hoạt động được và chấp nhận được. Thí dụ

nhƣ hệ thống phát thanh truyền hình.

Hầu hết hệ nhúng là các hệ thời gian thực và hầu hết các hệ thời gian thực là hệ

nhúng-> Thuộc tính thời gian là thuộc tính tiêu biểu cho hệ thống nhúng.

1.3. Biễu diễn số và dữ liệu

Đơn vị cơ bản nhất trong biểu diễn thông tin của hệ thống số đƣợc gọi là bit,

chính là ký hiệu viết tắt của thuật ngữ binary digit.

1964, IBM đã thiết kế và chế tạo máy tính số sử dụng một nhóm 8 bit để

đánh địa chỉ bộ nhớ và định nghĩa ra thuật ngữ 8 bit = 1 byte.

Ngày nay sử dụng rộng rãi thuật ngữ word là một từ dữ liệu dùng để biểu

diễn kích thƣớc dữ liệu mà đƣợc xử lý một cách hiệu quả nhất đối với mỗi

Page 4: Lap Trinh ARM - Ngo Vinh

Trang 4

loại kiến trúc xử lý số cụ thể. Chính vì vậy một từ có thể là 16 bits, 32 bits,

hoặc 64 bits…

Mỗi một byte có thể đƣợc chia ra thành hai nửa 4 bit và đƣợc gọi là các

nibble.

Nibble chứa các bít trọng số lớn đƣợc gọi là nibble bậc cao, và nibble chứa

các bit trọng số nhỏ đƣợc gọi là nibble bậc thấp.

Các hệ thống cơ số:

Một cách tổng quát một hệ biểu diễn số cơ số b và a là một số nguyên nằm

trong khoảng giá trị cơ số b đƣợc biểu diễn nhƣ sau:

n

i

i

i xbaA0

1

cơ số binary (nhị phân), cơ số decimal (thập phân), cơ số hexadecimal, cơ số

8 Octal (bát phân).

1.4. Cấu trúc phần cứng của hệ thống nhúng

Hình 1.1. Kiến trúc cơ bản của của các chip vi điều khiển nhúng

CPU: Đóng vài trò là bộ não, giả mã và thực thi lệnh, gồm khối ALU, bộ giả

mã, bộ tuần tự và các thanh ghi.

Page 5: Lap Trinh ARM - Ngo Vinh

Trang 5

Xung nhịp và trạng thái tín hiệu: Hoạt động của hệ thống đƣợc thực hiện đồng bộ hoặc

dị bộ theo các xung nhịp chuẩn. Các nhịp đó đƣợc lấy trực tiếp hoặc gián tiếp từ một

nguồn xung chuẩn thƣờng là các mạch tạo xung hoặc dao động thạch anh.

Bus: có 3 loại, bus dữ liệu, địa chỉ và điều khiển (Bus điều khiển phục vụ

truyền tải các thông tin dữ liệu để điều khiển hoạt động của hệ thống).

Bộ nhớ: có 2 loại kiến trúc

- Kiến trúc von neumann: không phân biệt vùng chứa dữ liệu và mã

chƣơng trình. Cả chƣơng trình và dữ liệu đều đƣợc truy nhập theo

cùng một đƣờng.

- Kiến trúc Havard: tách/phân biệt vùng lƣu mã chƣơng trình và dữ liệu.

Mã chƣơng trình chỉ có thể đƣợc lƣu và thực hiện trong vùng chứa

ROM và dữ liệu cũng chỉ có thể lƣu và trao đổi trong vùng RAM.

Hầu hết các vi xử lý nhúng ngày nay sử dụng kiến trúc bộ nhớ Havard hoặc kiến

trúc Havard mở rộng (tức là bộ nhớ chƣơng trình và dữ liệu tách biệt nhƣng vẫn cho

phép khả năng hạn chế để lấy dữ liệu ra từ vùng mã chƣơng trình).

Bộ nhớ chƣơng trình: Eprom và Flash

Là các chíp khả trình, cấu tạo từ các transitor, eprom có thể xóa bằng tia cực tím,

trong khi Flash có thể xóa bằng các xung điện, có thể lập trình trực tiếp và không cần

tháo ra khỏi mạch.

Bộ nhớ RAM: gồm SRAM và DRAM

Bộ điều khiển ngắt: Xử lý yêu cầu ngắt

Bộ định thời chó canh (Watchdog Timer): Là một bộ định thời đặc biệt để

định nghĩa 1 khung thời gian hoạt động bình thƣờng của hệ thống. Tự động

reset lại hệ thống khi phát hiện các sự cố mềm nhƣ hệ thống bị treo hoặc chạy

quẩn.

Khung thời gian do ngƣời lập trình đặt ra.

1.5. Hệ điều hành nhúng và phần mềm nhúng

1.5.1. Hệ điều hành nhúng

- Đóng vai trò trung gian để tƣơng tác trực tiếp với phần cứng và các chƣơng trình ở

lớp trên cũng nhƣ ngƣời sử dụng: Quản lý các tiến trình, quản lý tài ngyên và bảo về

các tài nguyên khỏi sự xâm phạm.

Page 6: Lap Trinh ARM - Ngo Vinh

Trang 6

- Đƣợc nạp và thực thi đầu tiên khi hệ thống khởi động

- Để nạp hệ điều hành cần sử dụng bộ nạp boot-loader, có kích thƣớc nhỏ gọn, đảm

nhiệm chức năng tiền hệ điều hành.

- Bộ nạp khởi tạo cũng có nhiệm vụ khởi tạo vùng nhớ dữ liệu và các thanh ghi hệ

thống trƣớc khi nhảy tới chƣơng trình ứng dụng chính.

- Có rất nhiều dạng khác nhau của bộ nạp khởi tạo, từ dạng đơn giản đến phức tạp.

1.5.2. Hệ điều hành thời gian thực –RTOS: (Realtime Operationg System )

- Các chức năng chính nhƣ định thời, giải quyết xung đột dữ liệu, giao tiếp giữa các

tác vụ process/task.->Ngắn gọn: RTOS là hệ điều hành đa nhiệm - multitasking dùng

cho các ứng dụng thời gian thực.

- RTOS: Cung cấp các giao tiếp giữa phần cứng và chƣơng trình ứng dụng, với các

tính năng chủ yếu sau: Đa nhiệm - Multitasking, Đồng bộ - Sync , xử lý sự kiện và

ngắt, I/O, truyền thông giữa các tách vụ process/task, quản lý Timer, Clock và bộ nhớ

(tựa chung là quản lý tài nguyên).

Hình 1.2. Cấu trúc của OSEK

Phân loại:

a. Các hệ điều hành mang tính thƣơng mại: thƣờng nhỏ và nhanh, nhƣ QNX,

PDOS, pSOS, VxWorks, Nulceus, ERCOS, EMERALDS, Windows CE, chúng có các

đặc điểm sau:

Page 7: Lap Trinh ARM - Ngo Vinh

Trang 7

+ Có thời gian chuyển ngữ cảnh và thời gian đáp ứng nhanh.

+ Kích thƣớc rất nhỏ.

+ Không có bộ nhớ ảo và có thể cố định mã, dữ liệu trong bộ nhớ.

+ Hệ thống đa tác vụ và chuẩn giao tiếp liên quá trình. Các mailbox, các

sự kiện, các tín hiệu và các đèn báo đƣợc định nghĩa tốt.

Những hệ điều hành này thƣờng có các đặc tả tốt và có các công cụ tốt để phát triển

các ứng dụng nhúng thời gian thực. Nó hỗ trợ các ràng buộc thời gian thực với các

dịch vụ nhƣ:

+ Các giới hạn thời gian thực hiện.

+ Đồng hồ thời gian thực.

+ Lập lịch thứ tự ƣu tiên.

+ Cảnh báo đặc biệt và thời gian quá hạn (timeout).

+ Hỗ trợ các hàng đợi thời gian thực.

+ Cung cấp việc xử lý độ trễ, treo hay kích hoạt việc thực hiện.

b. Hệ điều hành thời gian thực mở rộng tới Unix và các hệ điều hành khác

Các hệ điều hành này nhƣ: RT-UNIX, RT-LINUX, RT-MACH, RT-POSIX. Chúng

chậm hơn và có khả năng dự đoán ít hơn so với các hệ điều hành thời gian thực thƣơng

mại ở trên nhƣng chúng lại có nhiều chức năng và môi trƣờng phát triển tốt hơn dựa

trên tập các giao tiếp chuẩn và thân thiện.

c. Các nhân cho mục đích nghiên cứu

Thí dụ nhƣ: Spring, MARS, HARTOS, MARUTI, ARTS, CHAOS, DARK.

Các hệ điều hành này có các đặc điểm sau:

+ Hỗ trợ các thuật toán lập lịch thời gian thực và việc phân tích thời gian.

+ Hỗ trợ các dịch vụ cơ bản để đồng bộ thời gian thực.

+ Nhấn mạnh khả năng dự đoán hơn là hiệu năng trung bình.

+ Hỗ trợ cho khả năng chịu lỗi.

- Đối với LPC2000 thì OS đƣợc xem là hệ điều hành tốt nhất.

1.5.3. Phần mềm nhúng

- Ngôn ngữ đƣợc sử dụng để phát triển các ứng dụng nhúng thƣờng là C hoặc

Assembler.

- Keil C là công cụ hỗ trợ viết soạn thảo, debug và biên dịch code (cả C và ASM).

Page 8: Lap Trinh ARM - Ngo Vinh

Trang 8

- Simulator là một chƣơng trình phần mềm cho phép ngƣời phát triển mã chƣơng

trình chạy mô phỏng một chƣơng trình viết cho một nền VXL/VĐK (nền phần

cứng đích) trên một môi trƣờng phần cứng khác (hay còn gọi là môi trƣờng phát

triển); cho phép chạy từng bƣớc, kiểm thử, điều chỉnh với các giá trị khác nhau, sử

dụng các thuật toán khác nhau.

Hỗ trợ các chức năng giống nhƣ trên phần cứng đích, có thể kèm theo emulator.

- Emulator là một thiết bị phần cứng có khả năng thực hiện nhƣ một nền phần cứng

đích ( Còn gọi là cộng cụ phát triển thời gian thực bởi vì nó cho ta phản ứng với các

sự kiện nhƣ VĐK đích thực thi)

Các bộ Emulator thƣờng có kèm theo cả phần chƣơng trình giám sát

(monitor program) để cho phép ngƣời phát triển chƣơng trình cho VĐK đích kiểm

tra nội dung, trạng thái các thanh ghi và các khu vực bộ nhớ và thiết lập các điểm

dừng khi thực hiện chạy chƣơng trình.

1.6. Quy trình thiết kế hệ thống nhúng

Khi tiếp cập kiển trúc hệ thống nhúng dƣới góc nhìn kỹ thuật có thể sử dụng một số

mô hình để miêu tả chu kỳ thiết kế. Một số mô hình điển hình nhƣ sau:

Mô hình big-bang: Mô hình này về cơ bản là không cần có kế hoạch và quy

trình trƣớc và trong quá trình thiết kế.

Mô hình code anh fix: Đƣa ra ra các yêu cầu nhƣng không có quy trình trƣớc

khi bắt đầu phát triển dự án.

Mô hình waterfall(thác nƣớc): Phát triển hệ thống theo từng bƣớc, có đƣợc kết

quả của bƣớc trƣớc mới thực hiện bƣớc sau và lặp lại từ đầu.

Page 9: Lap Trinh ARM - Ngo Vinh

Trang 9

Hình 1.3. Mô hình thác nƣớc

Mô hình spiral (xoáy ốc): Là một quy trình phát triển hệ thống theo từng bƣớc,

tại mỗi bƣớc có sự thay đổi và quay lại thiết kế bƣớc trƣớc sao cho phù hợp.

Hình 1.4. Mô hình xoán ốc

Thực tế ngƣời ta thƣờng kết hợp các mô hình, nhƣ mô hình chu kỳ thời gian sống là sự

kết hợp của mô hình waterfall và mô hình spiral

Page 10: Lap Trinh ARM - Ngo Vinh

Trang 10

Hình 1.5. Mô hình phát triển hệ thống theo chu kỳ thời gian sống

1.7. Mô hình hệ thống nhúng

Mô hình hệ thống nhúng gồm 3 lớp

Hình 1.5. Mô hình tổng thể của hệ thống nhúng

Page 11: Lap Trinh ARM - Ngo Vinh

Trang 11

CHƢƠNG 2: HỌ VI ĐIỀU KHIỂN ARM

2.1. Tổng quan

- Họ vi điều khiển LPC2000 là ARM7, ngƣời lập trình không cần thiết phải thành thạo

ARM 7 để sử dụng LPC2000 mà vấn đề phức tạp là ở trình biên dịch C.

- Ngƣời lập trình cần có kiến thức cơ bản về cách CPU làm việc và các đặc tính của nó

để tạo ra các thiết kế tin cậy.

- ARM 7 là một máy tính nhỏ với tập lệnh nhỏ, khả năng tính toán cao, tiêu thụ năng

lƣợng thấp.

- Vi điều khiển ARM đƣợc phát triển theo kiến trúc RISC (Reduced Instruction Set

Computer):

- Chỉ có các lệnh nạp hoặc lƣu trữ là có thể tham chiếu tới bộ nhớ,

- Tồn tại ít lệnh và kiểu định địa chỉ, khuôn dạng lệnh cố định,

- Có nhiều tập thanh ghi,

- Các lệnh thực hiện trong một chu ky máy,

- Lệnh đƣợc thực hiện trực tiếp trên phần cứng(CISC có 1 chƣơng trình thông

dịch nhỏ),

- Chƣơng trình biên dịch mã nguồn phức tạp(CISC-chƣơng trình thông dịch

phức tạp),

- Hỗ trợ cơ chế pipeline,

- Kích thƣớc chƣơng trình lớn.

Cấu trúc các chân:

Thí dụ các chân của LPC2101:

Page 12: Lap Trinh ARM - Ngo Vinh

Trang 12

Hình 2.1. Cấu trúc các chân của LPC2101

2.2. Cơ chế Pipeline

- Trái tim của ARM7 là cơ chế pipeline, thực thi lệnh theo ba bƣớc: đọc lệnh, giải mã

lệnh và thực thi lệnh.

Hình 2.2. Ba bƣớc thực hiện của pipepline

- Pipeline có phần cứng độc lập để thực hiện các bƣớc, trong khi lệnh thứ nhất đang

thực thi, lệnh thứ 2 đƣợc giải mã và lệnh thứ 3 đƣợc đọc lên pipeline.

- Hầu hết các lệnh của ARM 7 đƣợc thực thi trong 1 chu kỳ máy.

Page 13: Lap Trinh ARM - Ngo Vinh

Trang 13

- Pipeline làm việc rất tốt trong trƣờng hợp chƣơng trình không rẽ nhánh. ARM chỉ

cho phép thực hiện các bƣớc nhảy ngắn trong đoạn chƣơng trình.

- Pipeline là một thành phần của CPU, thanh ghi PC chạy ở 8 bytes đầu của lệnh hiện

hành sẽ đƣợc thực thi. Thí dụ: 0x4000 LDR PC,[PC,#4]-> PC=0x400C

2.3. Các thanh ghi

- ARM7 có kiến trúc kiểu load and store, bởi vậy, để thực hiện các lệnh xử lý dữ liệu

thì tất cả các dữ liệu phải đƣợc tải từ bộ nhớ vào một tập các thanh ghi trung tâm, lệnh

xử lý dữ liệu đƣợc thực hiện và lƣu trữ dữ liệu trở lại bộ nhớ.

Hình 2.3. Kiến trúc load and store của ARM 7

- ARM7 có 17 thanh ghi 32 bít:

- Các thanh ghi R0 đến R12 là các thanh ghi chung,

- Thanh ghi R13 là thanh ghi con trỏ ngăn xếp,

- R14 là thanh ghi liên kết,

- R15 là thanh ghi bộ đếm chƣơng trình (PC) và

- Thanh ghi trạng thái chƣơng trình CPSR.

- Thanh ghi R14 dùng trong chƣơng trƣờng hợp gọi đến chƣơng trình con “gần” thì nó

sẽ cất giữ địa chỉ của trả về của chƣơng trình chính, nếu trong chƣơng trình con này

gọi đến một chƣơng trình con khác thì địa chỉ của chƣơng trình chính phải đƣợc cất

giữa vào ngăn xếp.

Page 14: Lap Trinh ARM - Ngo Vinh

Trang 14

Hình 2.4. Các thanh ghi của ARM7

2.4. Thanh ghi trạng thái chƣơng trình hiện hành

Hình 2.5. Thanh ghi trạng thái chƣơng trình CPSR

- CPU ARM7 thực thi 2 loại lệnh: Tập lệnh ARM 32 bít và tập lệnh đƣợc nén 16 bít.

Bít T sẽ quyết định loại lệnh nào sẽ đƣợc thực thi, ngƣời lập trình không nên set hay

xóa giá trị của bít này.

- ARM7 có 7 chế độ hoạt động khác nhau, ngƣời lập trình thƣờng chạy trong chế độ

ngƣời dùng để truy cập đến các bank thanh ghi từ R0-R15 và thanh ghi trạng thái

chƣơng trình(CPSR). Tuy nhiên khi gặp các ngoại lệ nhƣ ngắt, lỗi bộ nhớ, ngắt mềm

CPU sẽ chuyển sang chế độ khác. Mỗi chế độ các thanh ghi R13 và R14 có giá trị

Page 15: Lap Trinh ARM - Ngo Vinh

Trang 15

riêng. Ở chế độ ngắt nhanh FIQ các thanh ghi R7-R12 có giá trị giống nhau (không cần

dùng stack để lƣu chữ).

Hình 2.6. 6 chế độ hoạt động của APU ARM7

2.5. Các mode ngoại lệ

- Khi có một ngoại lệ xảy ra, CPU sẽ chuyển chế độ và thanh ghi PC sẽ đƣợc đảy về

địa chỉ của vecto ngoại lệ. Bảng vecto bắt đầu từ địa chỉ 0 trùng địa chỉ vecto ngắt.

- Mỗi vecto ngoại lệ là 4 bytes.

Hình 2.6. Bảng các vecto ngắt

Page 16: Lap Trinh ARM - Ngo Vinh

Trang 16

Hình 2.7. Thứ tự ƣu tiên của các ngắt

Hình 2.8. Thí dụ về trật tự xử lý khi có một ngoại lệ ngắt xảy ra

Hình 2.9. CPU trở lại trạng thái ban đầu khi kết thúc phụ vụ ngoại lệ

2.6. Tập lệnh ARM 7

- ARM7 có 2 tập lệnh: Tập lệnh mở rộng 32 bít và tập lệnh nén (THUMB) 16 bít.

- CPU ARM7 đƣợc thiết kế để hỗ trợ xử lý theo kiểu big endian hay little endian:

Page 17: Lap Trinh ARM - Ngo Vinh

Trang 17

Hình 2.10. Hai kiểu xử lý của CPU ARM7

- Một đặc điểm thú vị của ARM7 là tất cả các lệnh đều có thể là các lệnh có điều

kiện, bằng cách so sánh 4 bít từ bit 28 đến bít 31 của kết quả thực hiện lệnh với các bít

điều kiện trong thanh ghi CPSR, nếu điều khiện không thỏa mãn thì lệnh sẽ không

đƣợc thực thi.

- Các lệnh xử lý dữ liệu sẽ bị ảnh hƣởng bởi các bít điều kiện trong thanh ghi

CPSR. Hai lệnh cơ bản MOV và ADD có thể đặt các tiến tố đằng trƣớc với 16 điều

kiện nhƣ sau:

Hình 2.11. 16 điều kiện đƣợc kiểm tra trƣớc khi thực thi lệnh

Page 18: Lap Trinh ARM - Ngo Vinh

Trang 18

Thí dụ: EQMOV R1,#0x00800000;

Giá trị 0x00800000 chỉ đƣa vào R1 khi kết quả cuối cùng của lệnh có các bít

tƣơng ứng với 4 bít trong thanh ghi CPSR và bít cờ Z đƣợc set =1.

- Các lệnh của ARM7 có thể chia thành 6 nhóm: Các lệnh rẽ nhánh, các lệnh xử lý

dữ liệu, truyền dữ liệu, truyền khối dữ liệu, lệnh số học và ngắt mềm.

2.6.1. Các lệnh rẽ nhánh

- Cho phép nhảy tiến hoặc lùi trong phạm vi 32MB, địa chỉ của lệnh tiếp theo sẽ

đƣợc lƣu vào thanh ghi liên kết R14.

- Lệnh rẽ nhánh có 2 biến thể: Rẽ nhánh trao đổi (branch exchange) và rẽ nhánh

liên kết trao đổi (branch link exchange). Hai lệnh này cơ giống nhau nhƣng lệnh rẽ

nhánh liên kết địa chỉ của lệnh tiếp theo đƣợc cộng thêm 4 bytes rồi đƣa vào R14.

2.6.2. Các lệnh xử lý dữ liệu

Cú pháp tổng quát:

Hình 2.12. Cú pháp tổng quát của một lệnh xử lý dữ liệu có điều kiện

Mỗi lệnh đều có 2 toán hạng, trong đó toán hạng thứ nhất phải là thanh ghi, toán hạng

còn lại có thể thanh ghi hoặc giá trị cụ thể.

Bít „S‟ đƣợc sử dụng để điều khiển điều kiện của lệnh:

S=1 thì điều kiện của lệnh phụ thuộc vào kết quả của lệnh,

S=0 thì không có điều gì xảy ra

Nếu S=1 và PC là thanh ghi chứa kết quả thì SPSR của chế độ hiện hành đƣợc

copy vào CPSR.

Page 19: Lap Trinh ARM - Ngo Vinh

Trang 19

Hình 2.13. Bảng các lệnh xử lý dữ liệu

2.6.3. Các lệnh truyền dữ liệu

Hình 2.14. Các lệnh truyền dữ liệu

Page 20: Lap Trinh ARM - Ngo Vinh

Trang 20

Hình 2.15. Các lệnh truyền một khối dữ liệu

2.6.4. Lệnh SWAP

- ARM7 hỗ trợ các tín hiệu thời gian thực với một lệnh swap cho phép trao đổi chỗ

nội dung của hai thanh ghi.

- Lệnh này đƣợc hỗ trợ trong thƣ viện ARM chứ không trực tiếp từ ngôn ngữ C.

Hình 2.16. Mô tả lệnh swap trong ARM7

2.7. Ngắt mềm (SWI – Software Interrupt Instruction)

Page 21: Lap Trinh ARM - Ngo Vinh

Trang 21

Các ngắt mềm sinh ra một ngoại lệ khi thực thi, đƣa vi xử lý vào chế độ hoạt động

giám sát và PC nhảy tới địa chỉ 0x00000008. Cũng nhƣ các lệnh ARM khác, lệnh ngắt

mềm chứa một mã điều kiện thực thi trong 4 bít thấp của toán hạng, các bít còn lại là

trống rỗng.

Hình 2.17. Điều kiện của ngắt mềm để CPU vào chế độ giám sát

Có thể giả lặp chƣơng trình con phục vụ ngắt của ngắt mềm nhƣ sau:

switch( *(R14-4) & 0x00FFFFFF) // Kiểm tra giá trị

//đƣợc lƣu trữ trong thanh ghi liên kết

{

case ( SWI-1):

…}

2.8. Đơn vị MAC (Multiply Accumulate Unit (MAC)

- MAC hỗ trợ phép nhận số nguyên kiểu integer và long integer, khi nhân kiểu

integer 2 thanh ghi 32 bít với nhau thì kết quả là 32 bít đƣợc đặt vào thanh ghi thứ 3.

Khi nhân 32 bít kiểu long integer thì kết quả là 64 bít và đƣợc đặt vào 2 thanh ghi.

- Các lệnh nhận dạng ASM:

Tên lệnh Viết tắt Kết quả

MUL Multiply 32 bit

MULA Multiply accumulate 32 bit

UMULL Unsigned multiply 64 bit

UMLAL Unsigned multiply accumulate 64 bit

SMULL Signed multiply 64 bit

SMLAL Signed multiply accumulate 64 bit

Bảng 2.1. Các lệnh nhân trong vi điều khiển ARM

2.9. Tập lệnh THUMB

- Tập lệnh ARM là tập lệnh 32 bít, ARM có tập lệnh 16 bít gọi là tập lệnh

THUMB. Tập lệnh THUMB thực chất là tập lệnh nén lại từ tập lệnh ARM.

Page 22: Lap Trinh ARM - Ngo Vinh

Trang 22

Hình 2.18. Tập lệnh THUMB đƣợc nén lại từ tập lệnh ARM

- Tập lệnh THUMB cho giá trị kết quả thấp hơn tập lệnh ARM nhƣng mà các kết

quả này chiếm một tỷ lệ lớn hơn. Tập lệnh THUMB tiết kiệm đƣợc không gian nhớ

30% và chạy nhanh hơn 40% so với tập lệnh ARM.

- Tập lệnh THUMB không có điều kiện thực thi trừ các lệnh rẽ nhánh. Các lệnh xử

lý dữ liệu thì cần có một thanh ghi nguồn và một thanh ghi đích.

Thí dụ: Với lệnh cộng thanh ghi R0 và R1:

Dùng lệnh ARM: ADD R0, R0,R1 //R0 = R0+R1

Dùng lệnh THUMB: ADD R0,R1 // R0 = R0+R1

- Tập lệnh THUMB chỉ có thể truy cập đến các thanh ghi thấp từ R0-R7, các thanh

ghi cao từ R8-R12 bị giới hạn truy cập:

Hình 2.19. Mô hình lập trình tập lệnh THUMB

Page 23: Lap Trinh ARM - Ngo Vinh

Trang 23

Ngƣời lập trình không thể truy cập trực tiếp vào thanh ghi CPSR và SPSR. Ngƣời lập

trình có thể sử dụng 2 lệnh BLX và BX để chuyển chế độ hoạt động với các lệnh. Khi

reset vi điều khiển làm việc với tập lệnh THUMB, khi có 1 ngoại lệ xảy ra thì sẽ

chuyển sang làm việc với tập lệnh ARM, khi kết thúc ngoại lệ thì quay trở về làm việc

với lệnh ARM.

Hình 2.20. Trao đổi giữa lệnh ARM và lệnh THUMB

2.10. Phần mềm phát triển và công cụ phần cứng

- Keil C ARM là công cụ cho phép lập trình mô phỏng vi điều khiển ARM với hệ

thống thƣ viện đƣợc hỗ trợ tƣơng đối đầy đủ về vi điều khiển core ARM 7 nhƣ: họ vi

điều khiển LPCxxxx và ARM966E-S, cortex-M0 đến cortex-M3.

- Phần mềm isp của atmel và H-jtag để biên dịch và nạp code lên board.

2.10.1. Cấu trúc file start up

- Phần đầu cung cấp bảng vecto ngắt:

Page 24: Lap Trinh ARM - Ngo Vinh

Trang 24

Hình 2.21. Các định nghĩa các vecto ngắt trong file startup.s

Bảng vecto ngắt đƣợc định nghĩa tại địa chỉ 0x00000000 và cho phép bộ đếm

chƣơng trình nhảy đến chƣơng trình con phụ vụ ngắt ( ISR-interupt service routine).

Rải địa chỉ của vio điều khiển là liên tiếp, không bị ngắt quãng trong bảng vecto ngắt.

Lệnh LDR (Load Register) đƣợc sử dụng để tải hằng tƣơng ứng với vecto ngắt trong

bảng vecto ngắt.

- Bảng vecto ngắt và bảng các hằng nằm ở 64 bytes đầu tiên của bộ nhớ.

- Lệnh NOP đƣợc sử dụng để nhảy đến vị trí vecto ngắt tại địa chỉ 0x00000014, vị

trí lỗi.

- Phần tiếp trong file startup.s cấu hình con trỏ ở đỉnh ngăn xếp cho từng chế độ

hoạt động:

- Kích thƣớc Stack tính theo byte, thí dụ trong file startup của LPCxxxx nhƣ sau:

Page 25: Lap Trinh ARM - Ngo Vinh

Trang 25

Hình 2.22. Cấu hình stack cho từng chế độ hoạt động

- Vùng nhớ dành cho stack đƣợc định nghĩa ở phần địa chỉ cao nhất của bộ nhớ và

lớn dần về phần địa chỉ thấp.

2.10.2. Công cụ phần cứng

- Họ LPC2000 của hãng Philips có nhiều cổng cho phép kết nối vi điều khiển với

máy tính, thƣờng đƣợc sử dụng nhất là cổng JTAG. Khi kết nối trực tiếp với máy tính

cho phép ngƣời lập trình debug trực tiếp trên mạch phần cứng:

Hình 2.23. Kết nối LPC2000 với máy tính qua cổng JTAG

- Đồng thời kèm theo module ETM cho phép debug chƣơng trình: nhƣ theo dõi

thời gian thực, theo dõi sự kiện và phân tích quá trình thực thi.

2.10.3. Cách viết chƣơng trình C với tập lệnh ARM và tập lệnh THUMB

- Để sử dụng các định nghĩa địa chỉ các ARM7, trong chƣơng trình cần khai báo

thƣ viện hợp lệ, thí dụ với họ LPC có các khai báo: #include LPC2xxx.h hoặc

LPC21xx.h hoặc LPC210x.h

- Ngƣời lập trình có thể đƣa ra các hàm đƣợc biên dịch theo lệnh tập ARM hoặc tập

THUMB. Để chỉ định một hàm sẽ đƣợc biên dịch theo tập lệnh nào dùng directive

#pragma, thí dụ:

Page 26: Lap Trinh ARM - Ngo Vinh

Trang 26

#pragma ARM // khai báo các lệnh ARM

int main(void)

{

while(1){

THUMB_function(); //gọi đến hàm THUMB

}}

#pragma THUMB //Switch to THUMB instructions

void THUMB_function(void)

{

unsigned long i,delay;

for (i = 0x00010000;i < 0x01000000 ;i = i<<1){

for (delay = 0;delay<0x000100000;delay++){} //tạo vòng lặp

IOSET1 = i; //chuyển đến led tiếp theo

}}

- Có thể chỉ ra trực tiếp trên lệnh:

int ARM_FUNCTION ( int my_var) __ARM

{…}

int THUMB_FUNCTION ( int my_var) __THUMB {…}

2.11. Cấu trúc bên trong

2.11.1. Bản đồ bộ nhớ

Hình 2.24.

Page 27: Lap Trinh ARM - Ngo Vinh

Trang 27

2.11.2. Lập trình thanh ghi

- Một thanh ghi chức năng đƣợc điều khiển bởi 3 thanh ghi ngƣời dùng, một thanh

ghi để đọc trạng thái, một thanh ghi để xóa và một thanh ghi để ghi dữ liệu lên.

Hình 2.25.Cấu trúc tổng quát khi truy cập thanh ghi chức năng trong ARM7

2.11.3. Memory Acelerator Module (MAM)

- Là bộ nhớ nằm giữa bộ nhớ Flash và CPU ARM, có tốc độ thực thi cao.

Hình 2.26: Mô hình bộ nhớ MAM

- CPU ARM có thể chạy ở tốc độ 80MHz, mỗi lần chíp Flash truy cập hết 50ns.

- Flash chạy ở tốc độ 20MHz

Page 28: Lap Trinh ARM - Ngo Vinh

Trang 28

- MAM đƣợc tạo ra nhƣ là một cache đầy đủ cho phép CPU dễ dàng truy cập trực

tiếp vào FLASH.

Hình 2.27. Truy cập bộ nhớ FLASH qua MAM

- Khi đọc các lệnh từ bank thứ nhất thì bank thứ hai đƣợc chốt.

- MAM là trong suốt với ngƣời dùng và đƣợc cấu hình bởi 2 thanh ghi: điều khiển

(MAMCR) và định thời (MAMTIM). Thanh ghi định thời đƣợc sử dụng để điều khiển

mối quan hệ giữa CPU và FLASH bằng cách thiết lập 3 bít đầu tiên của nó để chỉ định

chu kỳ xung nhịp của CPU đƣợc yêu cầu bởi MAM để truy cập vào FLASH.

- Khi FLASH có tốc độ 20MHz và CPU có có thể có tốc độ cực đại là 60MHz, số

chu kỳ yêu cầu truy cập FLASH là 3.

Thí dụ: Cấu hình MAM

#include "LPC21xx.h"

void ChangeGPIOPinState(unsigned int state);

int main(void){

unsigned int delay,val;

unsigned int FLASHer = 0x00010000; // Khai báo cục bộ

IODIR0 = 0x00FF0000; // Thiết lập các chân ra

VPBDIV = 0x02;

ADCR = 0x00270601; // Thiết lập A/D: 10-bit AIN0 @ 3MHz

ADCR |= 0x01000000; // Khởi tạo bộ chuyển đổi A/D

while(1)

{ do {

val = ADDR; // Đọc thanh ghi dữ liệu bộ chuyển đổi A/D

Page 29: Lap Trinh ARM - Ngo Vinh

Trang 29

}while ((val & 0x80000000) == 0);

val = ((val >> 6) & 0x03FF);

if (val <0x80)

{

MAMCR = 0;

MAMTIM = 0x03;

MAMCR = 0x02;

}else

{ MAMCR = 0x0; }

for(delay = 0;delay<0x100000;delay++) //tạo vòng lặp

{;}

ChangeGPIOPinState(FLASHer); //Đổi trạng thái các chân ra ở cổng

FLASHer = FLASHer <<1; //Dịch đến đèn led tiếp

if(FLASHer&0x01000000)

{

FLASHer = 0x00010000; //Lặp lại đèn đầu tiên

// overflow

}}}

void ChangeGPIOPinState(unsigned int state)

{

IOSET0 = state; //set output pins

IOCLR0 = ~state; //clear output pins

}

2.11.4. PLL- Phase Locked Loop

- Tạo ra một tần số dao động ngoài từ 10-25MHz từ mạch dao động cơ bản và có

thể tăng lên 60 MHz để cung cấp cho CPU ARM và thiết bị ngoại vi.

- Tần số đầu ra của PLL có thể thay đổi tự động, cho phép thiết bị điều chỉnh theo

tốc độ thực thi để duy trì nguồn năng lƣợng khi ở trạng thái rảnh rỗi.

Page 30: Lap Trinh ARM - Ngo Vinh

Trang 30

Hình 2.28

- Hai hằng M và P phải đƣợc lập trình để quyết định xung clock (Cclk) cho CPU và

AHB.

- Hăng thứ nhất đƣợc nhân một cách tuyến tính với tần số dao động bên ngoài đƣa

vào. Tần số ra của PLL là: Cclk=M x Osc

- Ngƣợc lại PLL lại đƣợc điều khiển bởi một dao động hoạt động hiện hành (CCO)

ở dải tần 156MHz-320MHz. Hằng số thứ 2 phải đƣợc lập trình để đảm bảo sao cho

CCO đƣợc giữ một giá trị cụ thể: Fcco = Cclk x 2 x P

- Trên board phát triển thì dao động thạch anh là 12MHz, bởi vậy để CPU đạt đƣợc

tốc độ tối đa 60MHz thì: M = Cclk/Osc = 60/12 =5

và 156< Fcco <320 = 60 x 2 x P

Thực nghiệm thì P=2.

- Giao diện lập trình PLL:

Hình 2.29.

- Giá trị trong các thanh ghi PLLCON, PLLCFG và PLLSTAT sẽ đƣợc ghi sau khi

giá trị trong PLL FEED đƣợc ghi.

Page 31: Lap Trinh ARM - Ngo Vinh

Trang 31

- Khi cập nhật giá trị thanh ghi PLLCON và PLLCFG thì phải ghi liên tiếp hai giá

trị 0x000000AA và 0x00000055 cho thanh ghi PLLFEED, các giá trị này phải ghi

trong các chu kỳ liên tiếp.

- Nếu lập trình cho phép các ngắt thì ngắt sẽ sinh ran gay sau khi từ đầu tiên đƣợc

ghi và các thiết lập mới cho PLL sẽ không có ảnh hƣờng.

- Để cài đặt PLL phải ghi các giá trị cho P và M tới thanh ghi PLLCFG, sau đó set

D0 của thanh ghi PLLCON để cho phép PLL khởi động.

- Giá trị của M chiếm 5 bít thấp (D4-D0), P chiếm 2 bít D6D5:

Hình 2.30. Giá trị của P và M trong thanh ghi PLLCFG

- PLL mất một khoảng thời gian xác định đủ để sử dụng nguồn xung clock. Sự khởi

động PLL có thể đƣợc kiểm tra bằng cách đọc bít LOCK (D10) trong thanh ghi trạng

thái PLLSTAT.

- Khi LOCK bít =1, PLL có thể đƣợc sử dụng nhƣ nguồn xung clock chính. Một

ngắt có thể đƣợc sinh ra khi PLL khóa, bởi vậy ngƣời lập trình có thể thực hiện các

nhiệm vụ khác khi PLL khởi động. Khi PLL bị khóa thì có thể thay thế nguồn xung

cho Cclk bằng cách điều khiển bít PLLC trong thanh ghi PLLCON.

Page 32: Lap Trinh ARM - Ngo Vinh

Trang 32

Hình 2.31. Trình tự khởi động PLL

2.11.5. Bộ chia bus (VLSI Peripheral Bus Divider)

Mạch dao động ngoài hoặc đầu ra của PLL đƣợc sử dụng để tạo ra nguồn xung Cclk

cho CPU ARM hoặc hệ thống bus có tần số cao. Các thiết bị ngoại vi có thể sử dụng

bus VPB riêng biệt.

Hình 2.32. Tạo xung Pclk từ Cclk

- Bộ chia có thể chia tốc độ Cclk xuống 2 đến 24 lần. Thanh ghi trong bộ chia

VPBDIV có thể lập trình được và chứa số lần giảm tốc độ. Tại thời điểm khởi động,

giá trị cực đại đƣợc nạp và bằng ¼ giá trị Cclk lúc khởi động.

- Hiện nay tất cả các thiết bị ngoại vi của họ vi điều khiển LPC có thể chạy ở tần số

60MHz. Vì vậy, bộ chia tần VPB thƣờng đƣợc sử dụng để tiết kiệm nguồn bằng cách

tạo xung clock chấp nhận đƣợc cho các ứng dụng.

Thí du cấu hình PLL và VPB:

Page 33: Lap Trinh ARM - Ngo Vinh

Trang 33

Cấu hình PLL để tạo ra tần số Cclk là 60MHz và Pclk là 30MHz với xung đầu vào là

12MHz:

void init_PLL(void)

{

PLLCFG = 0x00000024; // Thiết lập hệ số nhân và bộ chia cho PLL

// give 60.00 MHz

PLLCON = 0x00000001; // Kích hoạt PLL

PLLFEED = 0x000000AA; // Cập nhật thanh ghi PLLFEED

PLLFEED = 0x00000055;

while (!(PLLSTAT & 0x00000400)); // kiểm tra bít Lock

PLLCON = 0x00000003; // Kết nối tới PLL

PLLFEED = 0x000000AA; //Cập nhật các thanh ghi PLL

PLLFEED = 0x00000055;

VPBDIV = 0x00000002; //Thiết lập bus VLSI với tần số 30.000MHz

}

2.12. Các cổng vào ra

- Các cổng vào ra của ARM là 32 bít, vi điều khiển có thể chỉ có 1 cổng hoặc có

nhiều hơn, nhƣng các chân dùng cho cổng vào/ra cũng là các chân dùng chung cho các

mục đích khác nhƣ biến đổi AD, ngắt, giao diện SPI, I2C,…

- Các chân đƣợc sử dụng vào mục đích nào tùy vào việc cấu hình chúng cho mục

đích đó. Trong chƣơng 3 sẽ trình bày cụ thể về cách lập trình cho các chân cổng vào

ra.

Page 34: Lap Trinh ARM - Ngo Vinh

Trang 34

CHƢƠNG 3: LẬP TRÌNH VI ĐIỀU KHIỂN ARM

3.1. Hƣớng dẫn sử dụng phần mềm Keil C

B1: Tạo một project mới:

B2: Tạo thƣ mục mới để chứa project mới tạo:

B3: Đặt tên cho thƣ mục là TD1 và click đúp lên thƣ mục này để mở ra và đặt tên

cho project là TD1:

Page 35: Lap Trinh ARM - Ngo Vinh

Trang 35

B4: Chọn vi điều khiển với core ARM7, thí dụ LPC2101:

B5: Chọn Yes để tự động thêm code start up vào project:

Page 36: Lap Trinh ARM - Ngo Vinh

Trang 36

B6: Chọn New để thêm file mới để soạn thảo mã nguồn của vi điều khiển:

B7: Soạn thảo mã nguồn và ghi với tên MAM.C

Page 37: Lap Trinh ARM - Ngo Vinh

Trang 37

B8: Ghi lại với tên MAM.C

B9: Add file MAM.c vào project:

Page 38: Lap Trinh ARM - Ngo Vinh

Trang 38

B10: Chọn file MAM.c:

B11: Cấu hình cho project:

Page 39: Lap Trinh ARM - Ngo Vinh

Trang 39

B12: Trong tab Target chọn tần số là 12:

B13: Trong tab Output chọn create hex File:

Page 40: Lap Trinh ARM - Ngo Vinh

Trang 40

B14: Biên dịch project:

B15: Trên proteus vẽ mạch mô phỏng:

Page 41: Lap Trinh ARM - Ngo Vinh

Trang 41

B16: Nạp file .hex cho vi điều khiển:

B17: Chọn file TD1.hex trong thƣ mục của project tạo từ keil C:

Page 42: Lap Trinh ARM - Ngo Vinh

Trang 42

3.2. Truy nhập các chân vào ra chung

Các chân vào (General purpose I/O input pins) ra đƣợc điều khiển bởi 4 thanh ghi:

Hình 3.1. Các chân vào ra đƣợc dùng cho mục đích chung

- Mỗi chân GPIO đƣợc điều khiển bởi 4 bít để điều khiển hƣớng dữ liệu, set, xóa và

trạng thái của chân.

- Mỗi bít trong thanh ghi IODIR: 0 cho phép cấu hình các chân là đầu vào

1 cho phép cấu hình các chân là đầu ra

Page 43: Lap Trinh ARM - Ngo Vinh

Trang 43

- Khi các chân là đầu ra thì các bít tƣơng ứng trên các thanh ghi IOSET và IOCLR

cho phép ngƣời lập trình điều khiển trạng thái của các bít.

- Để xóa chân nào thì đƣa set bít đó =1 tƣơng ứng trong thanh ghi IOCLR

- Để đọc nội dung của chân sử dụng thanh ghi IOPIN

Thí dụ 1: Viết chƣơng trình điều khiển led đơn sáng nhấp nháy

Ghép nối một led đơn với chân P0.0 của LPC2101, Sơ đồ nối chân Proteus:

Chƣơng trình điều khiển:

//Thi du chuong trinh dieu khien led nhap nhay tai chan p0.1

//LPC 2101

#include"LPC21xx.h"

void delay(unsigned int a);

int main(void){

IODIR0=0x00000001 ;

while(1){

IOSET0=0x00000001 ;

delay(0x100000);

Page 44: Lap Trinh ARM - Ngo Vinh

Trang 44

IOCLR0=0x00000001 ;

delay(0x100000);

} }

void delay(unsigned int a){

unsigned int i;

for (i=0;i<a;i++){;}

}

Thí dụ 2: Chƣơng trình hiển thị chữ trên LCD

Sơ đồ trên proteus:

Chƣơng trình điều khiển:

Tổ chức các tệp trong chƣơng trình nhƣ sau:

Page 45: Lap Trinh ARM - Ngo Vinh

Trang 45

Tệp lcd.h định nghĩa địa chỉ dành cho lcd:

/***************************************/

/* LCD routines for OLIMEX LPC-MT-2106 */

/* 16x2 Character LCD 1602K */

/* 4-bit mode operation */

/***************************************/

/* DEFINE IOMASK */

#define LCD_D4 0x10 //P0.04

#define LCD_D5 0x20 //P0.05

Page 46: Lap Trinh ARM - Ngo Vinh

Trang 46

#define LCD_D6 0x40 //P0.06

#define LCD_D7 0x80 //P0.07

#define LCD_EN 0x400000 //P0.22

#define LCD_RS 0x800000 //P0.23

#define LCD_RW 0x1000000 //P0.24

#define LCD_DATA (LCD_D4|LCD_D5|LCD_D6|LCD_D7)

#define LCD_IOALL

(LCD_D4|LCD_D5|LCD_D6|LCD_D7|LCD_EN|LCD_RS|LCD_RW)

#define LCD_GPIO_SEL0 0x0000FF00 //MASK for P0.04-P0.07

#define LCD_GPIO_SEL1 0x0003F000 //MASK for P0.22-P0.24

/* Functions Header */

/* internal I/O functions */

#define lcd_rs_set() IOSET |= LCD_RS

#define lcd_rs_clr() IOCLR |= LCD_RS

#define lcd_en_set() IOSET |= LCD_EN

#define lcd_en_clr() IOCLR |= LCD_EN

#define lcd_rw_set() IOSET |= LCD_RW

#define lcd_rw_clr() IOCLR |= LCD_RW

/* wait until lcd controller is free */

void lcd_wait();

void lcd_out_data4(unsigned char);

void lcd_write_nibbles(unsigned char);

void lcd_write_control(unsigned char);

/* initialize both the GPIO of lpc and LCD */

void lcd_init();

#define lcd_clear() lcd_write_control(0x01)

#define lcd_cursor_home() lcd_write_control(0x02)

#define lcd_display_on() lcd_write_control(0x0E)

#define lcd_display_off() lcd_write_control(0x08)

#define lcd_cursor_blink() lcd_write_control(0x0F)

#define lcd_cursor_on() lcd_write_control(0x0E)

Page 47: Lap Trinh ARM - Ngo Vinh

Trang 47

#define lcd_cursor_off() lcd_write_control(0x0C)

#define lcd_cursor_left() lcd_write_control(0x10)

#define lcd_cursor_right() lcd_write_control(0x14)

#define lcd_display_sleft() lcd_write_control(0x18)

#define lcd_display_sright() lcd_write_control(0x1C)

/* put a character out to lcd */

void lcd_putchar(unsigned char);

/* print a string */

void lcd_print(unsigned char*);

Tệp lcd.c định nghĩa các phƣơng thức liên quan đến các thao tác trên LCD:

#include "lcd.h"

#include "lpc210x.h"

void lcd_wait(){

int loop=2800; //more than enough

//busy loop

while(loop--);

}

void lcd_out_data4(unsigned char val){

IOCLR |= (LCD_DATA);

IOSET |= (val<<4);

}

void lcd_write_nibbles(unsigned char val){

//higher-order byte

lcd_en_set();

lcd_out_data4((val>>4)&0x0F);

lcd_en_clr();

lcd_wait();

//lower-order byte

lcd_en_set();

lcd_out_data4((val)&0x0F);

lcd_en_clr();

Page 48: Lap Trinh ARM - Ngo Vinh

Trang 48

lcd_wait();

}

void lcd_write_control(unsigned char val){

lcd_rs_clr();

lcd_write_nibbles(val);

}

void lcd_init(){

PINSEL0 &= (~LCD_GPIO_SEL0);

PINSEL1 &= (~LCD_GPIO_SEL1);

/* we only work on OUTPUT so far */

IODIR |= LCD_IOALL;

/* IO init complete, init LCD */

/* init 4-bit ops*/

lcd_rs_clr();

lcd_rw_clr();

lcd_en_clr();

//wait VDD raise > 4.5V

lcd_wait();

//dummy inst

lcd_write_nibbles(0x30);

lcd_write_nibbles(0x30);

lcd_write_nibbles(0x30);

//FUNCTION SET

//001DL N F XX

//DL=1: 8bit

//DL=0: 4bit

//N=0: 1 line display

//N=1: 2 line display

//F=0: 5x7 dots

//F=1: 5x10 dots

//our case:

Page 49: Lap Trinh ARM - Ngo Vinh

Trang 49

//0010 1000

lcd_en_set();

lcd_out_data4(0x2);

lcd_en_clr();

lcd_wait();

lcd_write_nibbles(0x28);

//LCD ON

lcd_write_nibbles(0x0E);

//Clear Display

lcd_write_nibbles(0x01);

//Entry mode

lcd_write_nibbles(0x06);

}

void lcd_putchar(unsigned char c){

lcd_rs_set();

lcd_write_nibbles(c);

}

void lcd_print(unsigned char* str){

int i;

//limit 1 line display for prints

for (i=0;i<16 && str[i]!=0;i++){

lcd_putchar(str[i]);

}}

Tệp test.c chứa chƣơng trình chính:

#include "lpc210x.h"

#include "lcd.h"

int main(void)

{

lcd_init();

lcd_print("Trieu Dai Gia");

return 1;

Page 50: Lap Trinh ARM - Ngo Vinh

Trang 50

}

3.3. Lập trình ngắt

Trong phần này sẽ trình bày 2 loại ngắt ngoài: ngắt sinh ra qua các chân vào ra

(IRQ) và ngắt nhanh (FIQ).

- Cấu trúc tổng quát của một chƣơng trình con phục vụ ngắt:

void tên_ctcpvn (void) __Kiểu_chương_trình_phục_vụ_ngắt

{

// các lệnh thân chương trình con phục vụ ngắt

}

- Có 3 kiểu chƣơng trình con phục vụ ngắt: _IRQ, _SWI, _ABORT,

- Chân EINT1 đƣợc kết nối tới một công tác trên board cho phép bầy lỗi nhanh một

ngắt và quan sát trên trình debug.

3.3.1. Chân Connect Block

- Tất cả các chân trên LPC2000 đƣợc kết nối tới một số chức năng ở bên trong qua

một bộ đa khối đa thành phần đƣợc gọi là chân select block. Chân select block cho

phép một user cấu hình một chân qua GPIO hoặc chọn 3 chân khác.

Hình 3.2. Chân I/O qua khối đa thành phần

- Khi khởi động thì tất cả các chân qua khối đa thành phần là chân GPIO, chức

năng thứ 2 sẽ đƣợc chọn nhờ thanh ghi PINSEL. Chân ngắt EINT1 vừa là chân I/O,

vừa là chân GPIO 0.14 và là đƣờng điều khiển UART1. Do vậy, để sử dụng EINT1

phải cấu hình chân chọn thanh ghi chuyển từ GPIO sang EINT1.

Page 51: Lap Trinh ARM - Ngo Vinh

Trang 51

Các thanh ghi PINSEL khi đƣợc khởi động lên có giá trị mặc định là 0 và cấu hình

các chân dành cho mục đích và ra.

Các chân của thanh ghi PINSEL cấu hình cho mục đích ngắt:

PINSEL0: (Thí dụ cho LPC213x)

STT Chân Kí hiệu Giá trị Loại ngắt

1 3:2 P0.1 11 EINT0

2 7:6 P0.3 11 EINT1

3 15:14 P0.7 11 EINT2

4 19:18 P0.9 11 EINT3

5 29:28 P0.14 10 EINT1

6 31:30 P0.15 10 EINT2

PINSEL1: (Thí dụ cho LPC213x)

STT Chân Kí hiệu Giá trị Loại ngắt

1 1:0 P0.16 11 EINT0

2 9:8 P0.20 11 EINT3

3 29:28 P0.30 11 EINT3

3.3.2. Các chân ngắt ngoài

Các ngắt ngoài đƣợc điều khiển bởi 4 thanh ghi nhƣ hình dƣới. Thanh ghi

EXMODE chọn ngắt kích theo mức hoặc theo sƣờn. Nếu một ngắt ngoài đƣợc cấu

hình là kích theo sƣờn thì thanh ghi EXPOL đƣợc sử dụng để theo dõi ngắt hoạt động

tăng lên hay giảm xuống. Trong trƣờng hợp kích theo mức, ngắt ngoài có thể chỉ ở

mức logic 0. Nếu ở chế độ tiết kiệm nguồn thì thanh ghi EXWAKE có thể cho phép

một ngắt đánh thức CPU. Để cài đặt một nguồn ngắt đơn giản chƣơng trình cần cấu

hình chân EINT1 kích theo mức và kết nối tới CPU qua thanh ghi PINSEL0.

Page 52: Lap Trinh ARM - Ngo Vinh

Trang 52

Hình 3.3. Chân ngắt ngoài dễ dàng đƣợc cấu hình để tạo nguồn ngắt.

3.3.3. Cấu trúc ngắt

- ARM7 có 2 chân ngắt ngoài cho yêu cầu ngắt nhanh (FIQ) và yêu cầu chế độ ngắt

đa mục đích. Tất cả các ngắt đều phải kết nối tới ngắt IRQ. Trong một hệ thống đơn

giản có thể kết nối qua cổng OR.

- VIC cho phép điều khiển ngắt một cách hiệu quả:

Hình 3.4 Bộ điều khiển ngắt VIC cho phép điều khiển ngắt hiệu quả

- Các ngắt phát sinh trong ứng dụng đƣợc đƣa đên VIC và đƣợc điều khiển nhƣ ngắt

FIQ hoặc một vecto ngắt hoặc không có vecto ngắt.

Page 53: Lap Trinh ARM - Ngo Vinh

Trang 53

Hình 3.5.

Các thanh ghi điều khiển ngắt:

VICIRQStatus: Trạng thái các ngắt IRQ

VICFIQStatus: Trạng thái các ngắt FIQ

VICIntSelect: Thanh ghi chọn ngắt FIQ hay IRQ với các chân từ 14 đến 17:

Nếu các chân có giá trị 0 tƣơng ứng với ngắt IRQ đƣợc chọn, bằng 1 tƣơng ứng với

ngát FIQ đƣợc chọn:

STT Bít Loại ngắt Giá trị

1 14 EINT0

=0 loại ngắt IRQ

=1 loại ngắt FIQ

2 5 EINT1

3 16 EINT2

4 17 EINT3

VICIntEnable: Thanh ghi cho phép ngắt.

Sử dụng các bít từ bít 14 đến bít 17 để cho phép các ngắt từ EINT0 đến EINT3:

STT Bít Loại ngắt Giá trị

1 14 EINT0

=0 không cho phép ngắt

=1 cho phép ngắt

2 5 EINT1

3 16 EINT2

4 17 EINT3

VICIntEnClr: Xóa các ngắt sử dụng các bít từ 14 đến 17 tƣơng ứng với các ngắt từ

EINT0 đến EINT3:

STT Bít Loại ngắt Giá trị

1 14 EINT0

=1 cho phép xóa ngắt 2 5 EINT1

Page 54: Lap Trinh ARM - Ngo Vinh

Trang 54

3 16 EINT2

4 17 EINT3

VICProtection: Thanh ghi bảo vệ ngắt, sử dụng bít 0:

Bít Ý nghĩa

0

=0: VIC cho phép truy cập các thanh ghi ở chế độ phân quyền hoặc ngƣời

dùng.

=1: VIC chỉ cho phép truy cập các thanh ghi ở chế độ phân quyền.

VICVectAddr : Chứa địc chỉ chƣơng trình con phục vụ ngắt khi xảy ra ngắt.

VICDefVectAddr: Chứa địa chỉ chƣơng trình con phục vụ ngắt đối với loại ngắt không

vecto.

VICVectAddr0 đến VICVectAddr16: Chứa địa chị chƣơng trình con phục vụ ngắt

tƣơng ứng với các slot từ 0 đến 15.

VICVectCntl0 đến VICVectCntl15: Cho phép ngắt:

Bít Ý nghĩa

5 = 1 cho phép ngắt tại slot tƣơng ứng

4:0 Chứa số lƣợng ngắt tại slot

Nguồn ngắt

Nguồn ngắt và quy định kênh ngắt trên LPC213x:

Nguồn ngắt Cờ ngắt Kênh phục

vụ qua VIC

WDT Watchdog Interrupt (WDINT) 0

- Chỉ dùng cho ngắt mềm 1

ARM Core Embedded ICE, DbgCommRx 2

ARM Core Embedded ICE, DbgCommRx 3

TIMER0 Match 0 - 3 (MR0, MR1, MR2, MR3)

Capture 0 - 3 (CR0, CR1, CR2, CR3)

4

TIMER1 Match 0 - 3 (MR0, MR1, MR2, MR3) 5

Page 55: Lap Trinh ARM - Ngo Vinh

Trang 55

Capture 0 - 3 (CR0, CR1, CR2, CR3)

UART0 Rx Line Status (RLS)

Transmit Holding Register Empty (THRE)

Rx Data Available (RDA)

Character Time-out Indicator (CTI)

6

UART1

PWM0

Rx Line Status (RLS)

Transmit Holding Register Empty (THRE)

Rx Data Available (RDA)

Character Time-out Indicator (CTI)

Modem Status Interrupt (MSI)

7

PWM0 Match 0 - 6 (MR0, MR1, MR2, MR3,

MR4, MR5, MR6)

8

I2C0 SI (state change 9

SPI0 SPI Interrupt Flag (SPIF)

Mode Fault (MODF)

10

SPI1(SSP) TX FIFO at le ast half empty (TXRIS)

Rx FIFO at least half full (RXRIS)

Receive Timeout condition (RTRIS)

Receive overrun (RORRIS)

11

PLL PLL Lock (PLOCK) 12

RTC Counter Increment (RTCCIF)

Alarm (RTCALF)

13

System

Control

External Interrupt 0 (EINT0)

External Interrupt 1 (EINT1)

External Interrupt 2 (EINT2)

External Interrupt 3 (EINT3)

14

15

16

17

ADC0 A/D Converter 0 end of conversion 18

I2C1 SI (state change) 19

BOD Brown Out detect 20

ADC1 A/D Converter 1 end of conversion 21

Page 56: Lap Trinh ARM - Ngo Vinh

Trang 56

3.3.4. Ngắt FIQ

- Nếu có nhiều ngắt FIQ thì tƣơng ứng với các bít trong trong thanh ghi ISR thì

thanh ghi trạnh thái VIC FIQ sẽ chọn chƣơng trình cọn phục vụ ngắt phù hợp để thực

thi.

- Khi một ngắt FIQ sinh ra, CPU sẽ chuyển sang chế độ FIQ và PC nhảy tới địa chỉ

0x0000001C và nhảy tới địa chỉ chƣơng trình con pvn.

3.3.5. Kết thúc ngắt

- Trƣớc khi kết thúc chƣơng trình con phục vu ngắt phải đảm xóa cờ ngắt ở phía

thiết bị không ngắt lại tiếp tục sinh ra.

Thí dụ ngắt FIQ:

void main (void)

{

IODIR1 = 0x00FF0000; //Thiet lap chan LED la chan ra

PINSEL0 = 0x20000000; //Chon chuc nang EINT1 tai chan connect block

VICIntSelect = 0x00008000; //Cho phep mot kenh qua VIC la FIQ

VICIntEnable = 0x00008000; //Cho phép ngat tu EINT1 vào VIC

IOCLR1 = 0x00FF0000; // Xoa LED

while(1); //Lap mai mai

}

void fiqint (void) __fiq //chuong trinh pvn

{

IOSET1 = 0x00FF0000; //thiet lap chan led

EXTINT = 0x00000002; //xoa co ngat tu phia thiet bi ngoai

}

3.3.6. Vecto IRQ

- Nếu có một nguồn ngắt là FIQ thì tất cả các nguồn con lại phải đƣợc kết nối tới

đƣờng IRQ. Để quá trình xử lý ngắt hiệu quả, VIC cung cấp một bảng tìm kiếm để

phân phát địa chỉ của các hàm C cho từng nguồn ngắt.

- VIC chứa đựng 16 khe cho địa chỉ. Mỗi khe chứa đựng một địa chỉ vecto và một

thanh ghi điều khiển vecto.

Page 57: Lap Trinh ARM - Ngo Vinh

Trang 57

Hình 3.6

- Thanh ghi điều khiển ngắt chứa đựng 2 trƣờng: một trƣờng kênh và một bít cho

phép. Bằng cách lập trình trƣờng kênh, bất kỳ một kệnh ngắt nào cũng có thể đƣợc kết

nối đến một khe (slot) đƣợc đƣa ra và kích hoạt bít cho phép ngắt. Thứ tự ƣu tiên của

một vecto ngắt đƣợc đƣa ra bởi số slot,slot càng thấp thì ngắt càng đƣợc ƣu tiên.

Hình 3.7

- Một thanh ghi khác trong VIC slot là thanh ghi địa chỉ vecto (Vector Address

Register). Thanh ghi này chứa địa chỉ của một chƣơng trình con phục vụ ngắt.

3.3.7. Kết thúc một ngắt IRQ

- Khi kết thúc một ngắt thì gửi một tín hiệu đến thanh ghi địa chỉ vecto:

void main (void)

Page 58: Lap Trinh ARM - Ngo Vinh

Trang 58

{

IODIR1 = 0x000FF000; //thiet lap chan ra

PINSEL0 = 0x20000000; //cho phep ngat ngoai EXTINT1

VICVectCntl0 = 0x0000002F; //chon 1 khe uu tien cho ngat

VICVectAddr0 = (unsigned)EXTINTVectoredIRQ; //lay dia chi chuong

//trinh phuc vu ngat

VICIntEnable = 0x00008000; //cho phep ngat

while(1);

}

void EXTINTVectoredIRQ (void) __irq

{

IOSET1 = 0x000FF000; //bat led

EXTINT = 0x00000002; //xoa co ngat ngoai

VICVectAddr = 0x00000000; //gui 1 tin hieu ket thuc ngat

}

3.3.8. Ngắt không có địa chỉ

VIC có thể điều khiển đƣợc 16 ngắt, nếu có nhiều hơn 16 ngắt thì phải mở rộng

ngắt. Các ngắt này đƣợc phụ bởi một ISR. Địa chỉ của ISR đƣợc lƣu trong trong một

thanh ghi địa chỉ ngắt mặc định. Nêu một ngắt đƣợc cho phép bởi VIC mà không

đƣợc cấu hình là FIQ hoặc IRQ thì sẽ đƣợc xếp vào ngắt không có địa chỉ. Khi ngắt

này xảy ra thì một địa chỉ sẽ đƣợc tải vào trong thanh ghi địa chỉ ngắt. Và CPU phải

đọc thanh ghi trạng thái IRQ để xem nguyên nhân ngắt.

Hình 3.8. Một địa chỉ mặc định đƣợc tải vào thanh ghi địa chỉ ngắt

Page 59: Lap Trinh ARM - Ngo Vinh

Trang 59

3.3.9. Kết thúc ngắt không địa chỉ

- Khi kết thúc ngắt phải xóa cờ trạng thái và viết thanh ghi địa chỉ ngắt.

Thí dụ ngắt không địa chỉ:

void main (void)

{

IODIR1 = 0x000FF000; //cau hinh cac chan ra

PINSEL0 = 0x20000000; //cho phap ngat ngoai EXTINT0

VICDefVectAddr = (unsigned)NonVectoredIRQ; //dua dia chi ngat IRQ

//vao VIC slot

VICIntEnable = 0x8000; //cho phep ngat ngoai EXTINT0 trong VIC

while(1);

}

void NonVectoredIRQ (void) __irq

{

if(VICIRQStatus&0x00008000) //kiem tra nguon sinh ngat

{

IOSET1 = 0x00FF0000; //bat led

EXTINT = 0x00000002; //xoa co ngat

update++;

}

VICVectAddr = 0x00000000; //gui tin hieu ket thuc ngat

}

3.4. Lập trình Timer

3.4.1. Các Timer

- Họ vi điều khiển ARM có số lƣợng các Timer dùng cho mục đích chung là khác

nhau, tùy vào từng loại, nhƣng ít nhất là có 2 Timer.

- Mỗi Timer 32 bít và một mạch đếm 32 bít.

- Nguồn xung clock cho tất cả các Timer là một mạch tạo xung cỡ lớn VLSI.

Page 60: Lap Trinh ARM - Ngo Vinh

Trang 60

Hình 3.9. Cấu trúc Timer 32 bít của ARM

Thangh ghi PINSEL0 cấu hình cho các chân của TIMER:

STT Chân Kí hiệu Giá trị Chọn chân

1 5:4 P0.2 10 Capture 0.0 (Timer 0)

2 9:8 P0.4 10 Capture 0.1 (Timer 0)

3 13:12 P0.6 10 Capture 0.2 (Timer 0)

4 21:20 P0.10 10 Capture 1.0 (Timer 1)

5 23:22 P0.11 10 Capture 1.1 (Timer 1)

6 7:6 P0.3 10 Match 0.0 (Timer 0)

7 11:10 P0.5 10 Match 0.1 (Timer 0)

8 25:24 P0.12 10 Match 1.0 (Timer 1)

9 27:26 P0.13 10 Match 1.1 (Timer 1)

Thanh ghi VICIntEnable cho phép ngắt của TIMER:

- Bít D5: cho phép ngắt của Timer 1

- Bít D4: cho phép ngắt của Timer 0

Giá trị các bít này có thể đọc hoặc ghi đƣợc.

Thanh ghi VICIntSelect cho phép chọn loại ngắt của TIMER:

- Bít D5: cho phép chọn loại ngắt của Timer 1

- Bít D4: cho phép chọn loại ngắt của Timer 0

Page 61: Lap Trinh ARM - Ngo Vinh

Trang 61

Giá trị các bít này có thể đọc hoặc ghi đƣợc, nếu bằng 0-là loại ngắt IRQ, 1-loại ngắt

FIQ.

Các thanh ghi của Timer:

Thanh ghi ngắt: TxIR (T0IR, T1IR)

Bít Kí hiệu Ý nghĩa Giá trị khi

khởi động

0 MR0 Cờ ngắt cho kênh so khớp 0 0

1 MR1 Cờ ngắt cho kênh so khớp 1 0

2 MR2 Cờ ngắt cho kênh so khớp 2 0

3 MR3 Cờ ngắt cho kênh so khớp 3 0

4 CR0 Cờ ngắt cho sự khiện chụp trên kênh so khớp 0 0

5 CR1 Cờ ngắt cho sự khiện chụp trên kênh so khớp 1 0

6 CR2 Cờ ngắt cho sự khiện chụp trên kênh so khớp 2 0

7 CR3 Cờ ngắt cho sự khiện chụp trên kênh so khớp 3 0

Thanh ghi điều khiển Timer – TCR: TIMER0: T0TCR, TIMER1: T1TCR:

Bít Ý nghĩa

0 =1: Cho phép đếm

1 =1: Reset bộ đếm

7:2 Không dùng

Thanh ghi điều khiển đếm - CTCR: TIMER0: T0CTCR và TIMER1:T1CTCR:

Thanh ghi này cho phép chọn giữa chế độ định thời và chế độ đếm:

Bít Mục đích Ý nghĩa các bít

1:0 Cho phép

chọn chế

độ đếm

hoặc định

thời

00: Chọn chế độ định thời

01-Chế độ đếm: TC tăng trên chân chụp đƣợc chọn bởi bít 3:2 có

tăng theo sƣờn

10-Chế độ đếm: TC tăng trên chân chụp đƣợc chọn bởi bít 3:2 có

giảm theo sƣờn

11-Chế độ đếm: TC tăng trên chân chụp đƣợc chọn bởi bít 3:2 theo

cả sƣờn tăng và sƣờn giảm

Page 62: Lap Trinh ARM - Ngo Vinh

Trang 62

3:2 Cho phép

chọn đầu

vào đếm

00-Chọn kệnh CAPn.0 (CAP0.0 cho TIMER0 và CAP1.0 cho

TIMER1)

00-Chọn kênh CAPn.1 (CAP0.1 cho TIMER0 và CAP1.1 cho

TIMER1)

00-Chọn kệnh CAPn.2 (CAP0.2 cho TIMER0 và CAP1.2 cho

TIMER1)

00-Chọn kệnh CAPn.3 (CAP0.3 cho TIMER0 và CAP1.3 cho

TIMER1)

7:4 Không dùng

Thanh ghi đếm – TC: T0TC và T1TC: Chứa giá trị đếm, giá trị trong TC sẽ tăng

lên khi bộ đếm Prescale Counter đạt tới giá trị tới hạn. Khi đạt đến giá trị

0xFFFFFFFF thì TC lại quay về 0.

Thanh ghi Prescale Register – PR: TIME R0: T0PR và TIMER1: T1PR: Là

thanh ghi 32 bít, chứa giá trị cực đại cho Prescale Counter.

Thanh ghi Prescale Counter Register –PC: TIMER0: T0PC và TIMER1: T1PC:

Là thanh ghi 32 bít, giá trị của PC sẽ tăng lên theo mỗi xung nhịp, khi PC đạt

tới giá trị lƣu trong thanh ghi PR và trở về 0 thì TC sẽ tăng lên 1.

Thanh ghi so khớp MR0 đến MR3: Giá trị liên tiếp đƣợc so sánh với giá trị của

TC trên các kênh tƣơng ứng.

Thanh ghi điều khiển so khớp - MCR, TIMER0: T0MCR và TIMER1:

T1MCR:

Điều khiển hành động xảy ra khi có sự kiện chụp trên các kênh tƣơng ứng:

Bít Kí hiệu Ý nghĩa

0 MR0I Cho phép sinh ra ngắt khi TC=MR0

1 MR0R Reset TC khi TC=MR0

2 MR0S Dừng TC và PC khi TC=MR0

3 MR1I Cho phép sinh ra ngắt khi TC=MR1

4 MR1R Reset TC khi TC=MR1

5 MR1S Dừng TC và PC khi TC=MR1

Page 63: Lap Trinh ARM - Ngo Vinh

Trang 63

6 MR2I Cho phép sinh ra ngắt khi TC=MR2

7 MR2R Reset TC khi TC=MR2

8 MR2S Dừng TC và PC khi TC=MR2

9 MR3I Cho phép sinh ra ngắt khi TC=MR3

10 MR3R Reset TC khi TC=MR3

11 MR3S Dừng TC và PC khi TC=MR3

15:12 - Không dùng

Các thanh ghi chụp - CR0-CR3: Chứa giá trị chụp đƣợc trên các kênh tƣơng

ứng.

Thanh ghi điều khiển chụp – CCR: TIMER0: T0CCR và TIMER1: T1CCR:

Bít Kí hiệu Ý nghĩa

0 CAP0RE Chụp khi có tín hiệu tăng từ 0 lên 1 tại kênh CAPn.0

1 CAP0FE Chụp khi có tín hiệu giảm từ 1 lên 0 tại kênh CAPn.0

2 CAP0I Cho phép sinh ra ngắt xảy ra tại kênh CAPn.0

3 CAP1RE Chụp khi có tín hiệu tăng từ 0 lên 1 tại kênh CAPn.1

4 CAP1FE Chụp khi có tín hiệu giảm từ 1 lên 0 tại kênh CAPn.1

5 CAP1I Cho phép sinh ra ngắt xảy ra tại kênh CAPn.1

6 CAP2RE Chụp khi có tín hiệu tăng từ 0 lên 1 tại kênh CAPn.2

7 CAP2FE Chụp khi có tín hiệu giảm từ 1 lên 0 tại kênh CAPn.2

8 CAP2I Cho phép sinh ra ngắt xảy ra tại kênh CAPn.2

9 CAP3RE Chụp khi có tín hiệu tăng từ 0 lên 1 tại kênh CAPn.3

10 CAP3FE Chụp khi có tín hiệu giảm từ 1 lên 0 tại kênh CAPn.3

11 CAP3I Cho phép sinh ra ngắt ngắt xảy ra tại kênh CAPn.3

15:12 - Không dùng

Thanh ghi so khớp ngoài External Match Register – EMR: TIMER0: T0EMR

và TIMER1: T1EMR: Cung cấp cả tín hiệu điều khiển và trạng thái của các

chân so khớp ngoài, đảo trạng thái của các chân MAT.

Hoạt động của timer:

-Tốc độ của Timer đƣợc điều khiển bởi giá trị lƣu trữ trong thanh ghi prescaler

Reg (TxPR).

Page 64: Lap Trinh ARM - Ngo Vinh

Trang 64

- Bộ đếm sẽ tăng lên cho đến khi đạt tới giá trị lƣu trữ trong thanh ghi thanh ghi

đếm.

- Khi đạt tới giá trị tối đa, bộ đếm sẽ đƣợc reset lại và trở lại giá trị 0.

- Thanh ghi điều khiển đếm TxTCR chỉ có 2 bít (D1D0), một bít để điều khiển

cho phép đếm(D0), một bít để reset bộ đếm(D1).

- Mỗi bộ đếm có 4 kênh cho phép chụp lại giá trị của bộ đếm tại thời điểm khi có

tín hiệu đầu vào tác động tạo ra sự dịch chuyển giá trị.

Hình 3.10.

- Thanh ghi điều khiển chụp (TxCCR) có thể đƣợc cấu hình để điều khiển chụp, khi

giá trị bộ đếm tăng lên hoặc giảm.

- Khi xảy ra sự kiện chụp, giá trị của bộ đếm đƣợc chuyển vào thanh ghi chụp

(TxCRx )và có thể sinh ra một ngắt nếu cần thiết.

Thí dụ sau cấu hình Timer 0 cho phép chụp tại 2, khi có sự kiện chụp thì sẽ sinh ra một

ngắt.

int main(void)

{

VPBDIV = 0x00000002; //thiet lap pclk co tan so 30 MHz

PINSEL0 = 0x00000020; //cho phep chân P0.2 de chup tai kenh 0

T0PR = 0x00007530; //Toc do cua timer là 1 Msec

T0TCR = 0x00000002; //reset bo dem va prescaler

T0CCR = 0x00000005; //Chup theo suon tăng 0->1 và sinh ra ngắt.

T0TCR = 0x00000001; //cho phep timer

VICVectAddr4 = (unsigned)T0isr; //Thiet lap dia chi vecto ngat cho ISR cua

time

VICVectCntl4 = 0x00000024; //Thiet lap kenh

Page 65: Lap Trinh ARM - Ngo Vinh

Trang 65

VICIntEnable = 0x00000010; //Cho phep ngat

while(1);

}

void T0isr (void) __irq

{

static int value;

value = T0CR0; // Đọc giá trị chụp đƣợc tại kenh 0

T0IR |= 0x00000001; // xoa ngat

VICVectAddr = 0x00000000; //Gia ghi mot tin hieu ket thuc ngat

}

- Mỗi kênh của Timer co một thanh ghi so khớp 32 bít, giá trị chụp đƣợc sẽ đƣợc so

sánh với giá trị trong thanh ghi so khớp, khi hai giá trị trùng nhau thì Timer sẽ thực

hiện một trong các hành động nhƣ: khởi động lại, dừng hoặc sinh ra ngắt và tác động

đến chân ngắt ngoài có thể set =1 hoặc xóa bằng 0 hoặc lơ lửng.

Hình 3.11.

- Để cấu hình Timer có sự kiện so khớp và nạp giá trị của thanh ghi so khớp mong

muốn. Sự kiện so khớp có thể có thể đƣợc điều khiển bởi thanh ghi điều khiển so

khớp. Trong thanh ghi nay mỗi kênh đƣợc điều khiển bởi một nhóm bít cho phép các

sự kiện so khớp xảy ra: sinh ra ngắt, khởi động timer và dừng timer.

- Mỗi kênh so khớp đƣợc kết hợp với một chân so khớp có thể thay đổi đƣợc khi có

một sự kiện xảy ra. Các chân so khớp có thể đƣợc điều khiển bởi 4 bít đầu trong thanh

ghi so khớp ngoài.

Page 66: Lap Trinh ARM - Ngo Vinh

Trang 66

Hình 3.12. Thanh ghi so khớp ngoài

- Thanh ghi so khớp ngoài chứa đựng các trƣờng cấu hình cho mỗi kênh. Lập trình

các trƣờng này để quyết định hành động sẽ xảy ra khi có sự kiện so khớp. Mỗi chân so

khớp ứng với một bít có thể lập trình trực tiếp để thay đổi mức logic.

- Thí dụ sau mô phỏng cách tạo một xung đơn giản sử dụng 2 kênh so khớp. Kệnh 0

đƣợc sử dụng để sinh ra chu kỳ tín hiệu PWM. Khi sự kiện so khớp xảy ra, timer khởi

động lại và sinh ra một ngắt. Ngắt đƣợc sử dụng để thiết lập chân Match 1 lên mức

cao. Kệnh 1 đƣợc sử dụng để điều khiển hoàn thành chu kỳ. Khi sự kiện match 1 xảy

ra, chân Match 1 đƣợc xoa về 0. Bởi vậy, sự thay đổi giá trị trong thanh ghi Match 1 để

tạo ra tín hiệu PWM.

Thí dụ:

int main(void)

{

VPBDIV = 0x00000002; // Cấu hình bộ chia tần VPB

PINSEL0 |= 0x00000800; // Match1 là đầu ra

T0PR = 0x0000001E; //Tải presaler

T0TCR = 0x00000002; //Reset counter và presale

T0MCR = 0x00000003; //Khi so khớp thì khởi động lại và sinh ra ngắt

T0MR0 = 0x00000010; //Thiết lập chu kỳ timer

T0MR1 = 0x00000008; // Thiết lập 50% chu kỳ

T0EMR = 0x00000042; //Thiết lập châp MAT1 lên 1 trong chu kỳ đầu

Page 67: Lap Trinh ARM - Ngo Vinh

Trang 67

T0TCR = 0x00000001; //cho phép timer

VICVectAddr4 = (unsigned)T0isr; //Thiết lập địa chỉ ISR của timer

VICVectCntl4 = 0x00000024; //Thiết lập kệnh

VICIntEnable |= 0x00000010; //Cho phép ngắt

while(1);

}

void T0isr (void) __irq

{

T0EMR |= 0x00000002;// Thiết lệp MAT1 lên mức cao để bắt đầu chu kỳ

T0IR |= 0x00000001; // Xóa ngắt tại match 0

VICVectAddr = 0x00000000; // Giả tin hiệu kết thúc ngắt

}

3.4.2. Đồng hồ thời gian thực (Real Time Clock - RTC)

- Đồng hồ thời gian thực LPCxxx là một lịch biểu chính xác đến năm 2099 và

không hoạt động với tần sô Pclk. RTC tiêu thụ một năng lƣợng thấp. RTC có một tập

các thanh ghi cảnh báo đƣợc sử dụng để lƣu trữ ngày tháng hoặc giá trị cụ thể trong

thanh ghi đếm thời gian (time-count register).

Hinh 3.13.

- RTC hoạt động ở xung nhịp chuẩn với tần số 32.7 KHz. Để có đƣợc số này thì

Pclk cần đƣợc kết nối tới bộ chia tần tham chiếu.

Page 68: Lap Trinh ARM - Ngo Vinh

Trang 68

Hình 3.14. Tạo xung clock cho RTC

- Để đảm bảo xung clock đƣợc tạo ra chính xác từ Pclk, prescaler đƣợc lập trình

bởi 2 thanh ghi PREINT và PREFRAC. Tính toán giá trị cho mỗi thanh ghi nhƣ sau:

PREINT = (int)(pclk/32768)-1

PREFRAC = pclk – ((PREINT+1) x 32768

Với một xung Pclk 30MHz thì:

PREINT = (int)( 30,000,000/32768)-1 = 914

PREFRAC = 30,000,000 – ((914+1) x 32768) = 17280

Các giá trị có thể đƣợc lập trình trực tiếp vào thanh ghi prescaler của RTC, sau đó cho

phép xung clock trong thanh ghi điều khiển clock và các bộ đếm timer sẽ bắt đầu,

PREINT = 0x00000392; //Thiết lập prescaler RTC với tần số Pclk

//là 30.000 MHz

PREFRAC = 0x00004380;

CCR = 0x00000001; //Bắt đầu RTC

Có 8 thanh ghi đếm thời gian (time-counter), mỗi thanh ghi chứa một con số thời gian

đơn có thể đƣợc đọc bất kỳ lúc nào. Ngoài ra, có một tập các thanh ghi tổng hợp biểu

diễn cùng giá trị thời gian trong 3 từ cho phép tất cả các thông tin đƣợc đọc trong 3

thao tác.

Page 69: Lap Trinh ARM - Ngo Vinh

Trang 69

Hình 3.15. Các thanh ghi tổng hợp của RTC

- RTC có thể sinh ra một sự kiện ngắt. Có 2 bộ tạo ngắt, Ngƣời lập trình có thể tạo

ra ngắt khi giá trị của thanh ghi time-counter đƣợc tăng lên, hoặc khi bộ giây đƣợc cập

nhật hoặc khi năm đƣợc tăng lên. Thanh ghi ngắt cho chép 8 ngắt có thể.

- Cách thứ 2 có thể sinh ra ngắt RTC các thanh ghi cảnh báo. Mỗi thanh ghi time-

counter có một thanh ghi cảnh báo (Alarm register), và có thể cảnh báo trong khoảng

thời gian hiện tại đến năm 2099 một cách chính xác.

- Thanh ghi Alarm Mask điều khiển sự so sánh. Thanh ghi ngắt location có 2 bít

đƣợc sử dụng để cho biết nguyên nhân sinh ra ngắt.

Thí dụ minh họa:

int main(void)

{

VPBDIV = 0x00000002;

IODIR1 = 0x00FF0000; // Thiết lập các chân đầu ra nối với led

IOSET1 = 0x00020000;

PREINT = 0x00000392; //Thiết lập RTC prescaler với Pclk 30MHz

PREFRAC = 0x00004380;

CIIR = 0x00000001; //Cho phép ngắt khi đến số giây

ALSEC = 0x00000003; //Thiết lập thanh ghi cảnh báo 3

AMR = 0x000000FE; //Cho phép cảnh báo theo số giây Alarm

CCR = 0x00000001; //Khởi động RTC

VICVectAddr13 = (unsigned)RTC_isr; //Lấy địa chỉ chƣơng trình phục vụ ngắt

VICVectCntl13 = 0x0000002D; //Thiết lập kệnh

VICIntEnable = 0x00002000; //Cho phép ngắt

Page 70: Lap Trinh ARM - Ngo Vinh

Trang 70

while(1);

}

void RTC_isr(void){

unsigned led;

if(ILR&0x00000001) //Kiểm tra ngắt RTC

{

led = IOPIN1; //Đọc trạng thái của các chân vào ra IO

IOCLR1 = led&0x00030000; //tắt LED

IOSET1 = ~led&0x00030000; // bật LED

ILR = 0x00000001; //xóa ngắt

}

if(ILR & 0x00000002)

{

IOSET1 = 0x00100000; //set led 0.7

ILR = 0x00000002; //xóa thanh ghi ngắt

}

VICVectAddr = 0x00000000; /*Giả lập kết thúc ngắt */

}

3.5. Lập trình qua UART

- LPCxxx có 2 chíp UARTs. UART1 có những tính năng hiện đại. Các thiết bị kết

nối phù hợp với chuẩn công nghiệp 550. 16 bytes truyền và nhận theo kiểu FIFOs.

Hình 3.16. Sơ đồ chân UART

Page 71: Lap Trinh ARM - Ngo Vinh

Trang 71

Thanh ghi PINSEL0 cấu hình cho UART:

STT Chân Kí hiệu Giá trị Chọn chân

1 1:0 P0.0 01 TxD của UART0

2 3:2 P0.1 01 RxD của UART0

3 17:16 P0.8 01 TxD của UART1

4 19:18 P0.9 01 RxD của UART1

5 21:20 P0.10 01 Có thể RTS của UART1

6 23:22 P0.11 01 Có thể CTS của UART1

7 25:24 P0.12 01 Có thể DST của UART1

8 27:26 P0.13 01 Có thể DTR của UART1

9 29:28 P0.14 01 Có thể DCDcủa UART1

31:30 P0.15 01 Có thể RI của UART1

Các thanh ghi của UART:

- Thanh ghi Receiver Buffer Register – UxRBR: là thanh ghi đệm nhận dữ liệu 8 bít.

Khi bít DLAB (Divisor Latch Access Bit) trong thanh ghi UxLCR thì cho phép đọc giá

trị thanh ghi này. Thanh ghi này chỉ cho phép đọc, không đƣợc phép ghi.

- Thanh ghi Transmit Holding Register UxTHR: Là thanh ghi đệm truyền 8 bít dữ liệu.

Khi bít DLAB = 0 cho phép ghi kí tự lên thanh ghi này mà không cho phép đọc dữ liệu

từ thanh ghi.

- Thanh ghi chốt phần chia Divisor Latch Registers – UxDLL: Chứa tốc độ truyền dữ

liệu, gồm 2 thanh ghi 8 bít là DLL và DLM. Các thanh ghi này đƣợc truy cập khi bít

DLAB=1.

- Thanh ghi Fractional Divider Register –UxFDR: Là thanh ghi 31 bít dùng để điều

khiển tốc độ truyền dữ liệu theo xung nhịp hệ thống và có thể đọc ghi theo ý của ngƣời

dùng. Các bít 3:0 chứa giá trị DIVADDVAL, các bít 7:4 chứa giá trị MULVAL, với 0

<= DIVADDVAL<=15 và 0< MULVAL <=15. Khi đó tốc độ truyền đƣợc tính theo

công thức sau:

Page 72: Lap Trinh ARM - Ngo Vinh

Trang 72

Thanh ghi này chir đƣợc sử dụng trong một số phiên bản của LPC từ 213x trở lên.

Tính toán tốc độ của UART:

Thí dụ 1: Tính toán tốc độ của UART0 theo PCLK của hệ thống. Khi PCLK = 20

MHz, U0DL = 130 (U0DLM = 0x00 and U0DLL = 0x82), DIVADDVAL = 0

và MULVAL = 1 sẽ cho phép UART0 đạt tới tốc độ 9615 bauds.

Example 2: Tính toán tốc độ của UART0 theo PCLK của hệ thống. Khi PCLK = 20

MHz, U0DL = 93 (U0DLM = 0x00 and U0DLL = 0x5D), DIVADDVAL = 2 và

MULVAL = 5 sẽ cho tốc độ UART0 là 9600 bauds.

- Thanh ghi cho phép ngắt Interrupt Enable Regi ster – UxIER: Hoạt động khi

DLAB=0.

Bít Ý nghĩa

0 =1 cho phép sinh ra ngắt khi nhận dữ liệu

1 =1 cho phép sinh ra ngắt khi truyền dữ liệu

2 =1 Cho phép ngắt khi thay đổi trạng thái chân Rx

- Thanh ghi điều khiển hàng đợi FIFO Control Register - UxFCR:

- Thanh ghi điều khiển đƣờng truyền: Line Control Register - U0LCR: Là thanh ghi 8

bít với chức năng cụ thể của các bít nhƣ sau:

Bít Giá trị và ý nghĩa

1:0 Chứa số bít dữ liệu

00- 5 bít

01-6 bít

10-7 bít

11-8 bít

2 Bít stop

0- 1 bít

1-2 bít (1.5 bít nếu bít 1:0=00)

3 0-Không kiểm tra chắn/lẻ

1-Cho phép kiểm tra chẵn/lẻ

5:4 00-Kiểm tra lẻ

01-Kiểm tra chắn

Page 73: Lap Trinh ARM - Ngo Vinh

Trang 73

10-bắt buộc kết quả bằng 0

11-bắt buộc kết quả bằng 1

6 Cho phép ngắt khi truyền

0-không cho phép

1- chân TxD=0 khi UxLCR[6]=1

7 DLAB-bít chốt

0-Không cho phép truy cập thanh ghi tốc độc DLL và

DLM

1-Cho phép truy cập thanh ghi DLL và DLM

Thanh ghi trạng thái đƣờng truyền Line Status Register – UxLSR: Là thanh ghi chỉ

đcoj cung cấp trạng thái của quá trình nhận và gửi dữ liệu.

Bít Kí hiệu Giá trị, ý nghĩa

0 RBR 0-UxRBR rỗng

1- UxRBR có dữ liệu

1 OE 0-Không kích hoạt lỗi tràn FIFO nhận

1-Kích hoạt lỗi tràn FIFO nhận

2 PE 0-Không kích hoạt lỗi kiểm tra chẵn lẻ

1-Kích hoạt lỗi kiểm tra chẵn lẻ

3 FE 0-không kích hoạt lỗi bít stop=0

1- kích hoạt lỗi bít stop=0

4 BI 0-không kích hoạt ngắt break

1-kích hoạt ngắt break

5 THRE 0-Đệm truyền UxTHR có dữ liệu

1-Đệm truyền UxTHR rỗng

6 TEMT 0-Đệm truyền UxTHR hoặc UxTSR có dữ liệu

1-Đệm truyền UxTHR hoặc UxTSR rỗng

7 RxFE 0-UxRBR không có lỗi

1- UxRBR có ít nhất một lỗi

Cài đặt UART0 nhƣ sau:

void init_serial (void) /* khởi tạo giao dien cong uart */

Page 74: Lap Trinh ARM - Ngo Vinh

Trang 74

{

PINSEL0 = 0x00050000; /* cho phep RxD1 va TxD1*/

U1LCR = 0x00000083; /* 8 bít dữ liệu, không bít Parity, 1 Stop bit */

U1DLL = 0x000000C2; /* tốc độ 9600, xung nhịp clock 30MHz VPB */

U1LCR = 0x00000003; /* DLAB = 0*/

}

- Chân chọn khối phải đƣợc lập trình để vi xử lý chuyển từ chức năng GPIO sang

UART. Thanh ghi điều khiển đƣờng truyền ( line control register ) UART đƣợc sử

dụng để định dạng khung truyền dữ liệu.

Hình 3.17. Thanh ghi điều khiển đƣờng truyền LCR của UART

- Tần số hoạt động của UART đƣợc chia từ Pclk, gấp 16 lần tốc độ truyền dữ liệu

và tính theo công thức:

Divisor = Pclk/16 x BAUD

- Giả sử Pclk=30MHz: Divisor = 30,000,000/16 x 9600 = (approx) 194 or 0xC2

Không thể lấy tốc độ chính xác của UART, tuy nhiện các cổng này có thể hoạt

động với sai số tốc độ 5%. Nếu muốn điều chỉnh Pclk để nhân đƣợc tốc độ chính xác

thì phải sử dụng đến CAN.

- Giá trị Divisor đƣợc tổ chức thành 2 thanh ghi Divisor latch MSB (DLM) và

Divisor latch LSB (DLL). 8 bít đầu tiên của cả 2 thanh ghi chứa nửa giá trị chia nhƣ

hình dƣới, cuối cùng, bít DLAB đƣợc set =0 để bảo vệ nội dung của thanh ghi chia tốc

độ:

Page 75: Lap Trinh ARM - Ngo Vinh

Trang 75

Hình 3.18. Thiết lập tốc độ của UART

- Khi UART đƣợc khởi tạo, các kí tự có thể đƣợc truyền bằng cách ghi tới thanh

ghi Transmit Holding Register. Các kí tự nhận đƣợc có thể đọc đƣợc từ thanh ghi đệm

nhận (receive buffer register). Thực chất cả hai thanh ghi này là 1, và việc đọc ghi theo

cơ chế FIFO. Hai chƣơng trình con dƣới đây mô tả việc gửi và nhậ kí tự.\

int putchar (int ch) /* Ghi một ký tự tới cổng Serial */

{

if (ch == '\n') {

while (!(U1LSR & 0x20));

U1THR = CR; /* output CR */

}

while (!(U1LSR & 0x20));

return (U1THR = ch);

}

int getchar (void) /* Đọc từ cổng Serial */

{

while (!(U1LSR & 0x01));

return (U1RBR);

Page 76: Lap Trinh ARM - Ngo Vinh

Trang 76

}

Trong thƣ viện STDIO của Keil C có thể sử dụng hàm printf() và scanf(). Cả hai hàm

putchar() và getchar() đều đọc thanh ghi liên kết trạng thái (LSR) để kiểm tra lỗi và

trạng thái truyền và nhận.

Hình 3.19. Thanh ghi liên kết trạng thái cho phép kiểm tra lỗi

UART có 1 ngắt tới VIC, nhƣng có 3 nguồn ngắt. Các ngắt đƣợc sinh ra khi thay đổi

trạng thái đƣờng nhận (receive line status). Nếu có một lỗi phát sinh thì một ngắt sẽ

đƣợc sinh ra và thanh ghi liên kết trạng thái sẽ đƣợc đọc để tìm nguyên nhân lỗi, Hai

loại ngắt còn lại sinh ra do nhận và truyền dữ liệu. Ngắt sinh ra sẽ đƣợc theo dõi bởi

các ký tự nhận đƣợc trong chân RX FIFO. Các ngắt đƣợc theo dõi trong thanh ghi điều

khiển UART FIFO.

Page 77: Lap Trinh ARM - Ngo Vinh

Trang 77

Hình 3.20. Bảng theo dõi các ngắt

Khi truyền sinh ra ngắt khi thanh ghi đệm truyền và thanh ghi dịch truyền là rỗng:

Hình 3.21. Ngắt tạo ra khi truyền

UART1 có cấu trúc giống UART0 nhƣng có hỗ trợ thêm modem điều khiển. Có

thêm các chân mở rộng để hỗ trợ giao diện modem: CTS, DCD, DSR, DTR, RI, RTS,

có thêm 2 thanh ghi: điều khiển modem và trạng thái modem; và một nguồn ngắt để

cung cấp thêm trạng thái ngắt của modem.

Page 78: Lap Trinh ARM - Ngo Vinh

Trang 78

Hình 3.22. Cấu trúc chân mở rộng của UART1

3.6. Giao diện I2C

- I2C có thể hoạt động ở chế độ chủ hoặc khách với tốc độ 400K bit/s và chế độ

chủ sẽ tự động đƣợc phân xử trong hệ thống có nhiều thiết bị chủ.

Hình 3.23. Bus I2C

Hai đƣờng Serial Clock (SCL) và Data line (SDA) phải đƣợc chuyển đổi từ chân GPIO

sang I2C qua bộ kết nối.

Page 79: Lap Trinh ARM - Ngo Vinh

Trang 79

Hình 3.24. Các thanh ghi của I2C

Giao diện I2C đƣợc điều khiển bởi 7 thanh ghi. Thanh ghi điều khiển có 2 thanh ghi

riêng biệt đƣợc sử dụng để set và clear thanh ghi điều khiển (I2CONSET và

I2CONCLR). Tốc độ bít đƣợc quyết định bởi hai thanh ghi (I2SCLH và I2CLL); thanh

ghi trạng thái trả lại mã điều khiển có liện quan tới các sự kiện trên bus. Thanh ghi ghi

đệm phát và đêm truyền, khi LPC đƣợc cấu hình là thiết bị slave thì địa chỉ mạng đƣợc

lƣu trong thanh ghi I2ADR.

Các lệnh khởi tạo giao diện I2C:

VICVectCntl1 = 0x00000029; //Chọn độ ƣu tiên cho ngắt

VICVectAddr1 = (unsigned)I2CISR //Đƣa địa chỉ ngắt và vecto ngát VIC

VICIntEnable = 0x00000200; //cho phép ngắt

PINSEL0 = 0x50; //chuyển chân GPIO sang chân I2C

I2SCLH = 0x08; //Tốc độ bít to 57.6KHz

I2SCLL = 0x08

- Tốc độ bít đƣợc lƣu trong 2 thanh ghi I2SCLH và I2CSLL:

Bit Rate = Pclk/(I2SCLH+I2CSLL

- Giả sử trong ví dụ trên PLL không đƣợc sử dụng và xung nhịp bên ngoài là

14.1456MHz thì tốc độ bít là:

Bit Rate = 14.7456/B ( 8 + 8) = 937500

- Cấu hình thanh ghi điều khiển bus I2C để đọc hoặc ghi dữ liệu nhƣ là bus chủ hoặc

nhận hoặc trả lời từ bus chủ nhƣ sau:

Page 80: Lap Trinh ARM - Ngo Vinh

Trang 80

Hình 3.25. Cấu hình thanh ghi điều khiển I2C

Chƣơng trình truyền dữ liệu I2C ở chế độ master nhƣ sau:

void I2CTransferByte(unsigned Addr,unsigned Data)

{

I2CAddress = Addr; //Place address and data in Globals to be used by

//the interrupt

I2CData = Data;

I2CONCLR = 0x000000FF; //Clear all I2C settings

I2CONSET = 0x00000040; //Enable the I2C interface

I2CONSET = 0x00000020; //Start condition

}

Hình 3.26. Thanh ghi trạng thái của I2C:

Chƣơng trình gửi một kí tự qua I2C:

void I2CISR (void) //I2C interrupt routine

{

switch (I2STAT) //Read result code and switch to next action{

case ( 0x08): //Start bit

Page 81: Lap Trinh ARM - Ngo Vinh

Trang 81

I2CONCLR = 0x20; //Clear start bit

I2DAT = I2CAddress; //Send address and //write bit

break;

case (0x18): //Slave address+W, ACK

I2DAT = I2Cdata; //Write data to tx register

break;

case (0x20): //Slave address +W, Not ACK

I2DAT = I2CAddress; //Resend address and write bit

break;

case (0x28): //Data sent, Ack

I2CONSET = 0x10; //Stop condition

break;

default :

break;

}

I2CONCLR = 0x08; //Clear I2C interrupt flag

VICVectAddr = 0x00000000; //Clear interrupt in

}

3.7. Giao diện SPI

Cũng giống nhƣ I2C, SPI cũng là một giao diện bus cho phép truyền và nhận dữ

liệu với thiết bị bên ngoài nhƣng chƣa đủ thông minh để quản lý bus:

Page 82: Lap Trinh ARM - Ngo Vinh

Trang 82

Hình 3.27. Giao diện SPI

Giao diện SPI có 4 chân: một chân clock, một chận chọn slave và hai chân dữ liệu

master in/slave out và master out/slave in. Chân clock cung cấp một xung 400kbits/s

khi ở chế độ master, hoặc nhận nguồn xung từ bên ngoài khi ở chế độ slave. Bus SPI

hoàn toàn chỉ để truyền dữ liệu nối tiếp với tốc độ cao và không giống nhƣ giao diện

I2C, nó không có sơ đồ địa chỉ đƣợc xây dựng khi truyền nối tiếp.

Một thiết bị ngoại vi ngoài đƣợc chọn qua chân slave. Thông thƣờng LPC2000 đƣợc

kích hoạt ở chế độ chủ và sử dụng các chân vào ra chung để chọn thiết bị SPI mong

muốn. Khi SPI ở chế độ slave, chân slave của nó đƣợc đẩy về mức 0 để cho phép SPI

chủ truyền thông với nó. Hai chân dữ liệu đƣợc kết nối với thiết bị SPI từ xa và chiều

truyền phụ thuộc vào thiết bị hoạt động ở chế độ chủ hay khách (master hay slave).

Lập trình qua giao diện SPI có 5 thanh ghi:

- Thanh ghi đến xung (clock counter register) quyết định tốc độ, Pclk đƣợc chia ở

giá trị trong bộ đến xung tạo tốc độ cho SPI. Thanh ghi này giữ giá trị nhỏ nhất trong 8

bít.

- Thanh ghi điều khiển đƣợc sử dụng để cấu hình hoạt động của bus SPI. Do các

thiết bị SPI chỉ để truyền dữ liệu và có giải rộng các thiết bị có thể kết nối, xung SPI và

Page 83: Lap Trinh ARM - Ngo Vinh

Trang 83

đƣờng dữ liệu có thể đƣợc cấu hình để hoạt động trong chế độ cấu hình riêng. Trƣớc

hết cần tạo cực (mức thấp hay cao hoặc ở giữa) phân đoạn và xung nhƣ hình sau:

Hình 3.28. Tạo cực và phân đoạn xung clock

Cuối cùng cấu hình hƣớng dữ liệu cho biết MSB hay LSB đƣợc truyền trƣớc.

Hình 3.29. Cấu hình hƣớng dữ liệu qua SPI

- Từng bít trong thanh ghi cấu hình đƣợc cấu hình để kết nối truyền thông với từng

thiết bị qua SPI và đƣợc set bởi ngƣời lập trình.

- Dữ liệu đƣợc gửi đi sẽ đƣợc đƣa vào thanh ghi dữ liệu và truyền theo từng byte.

3.8. Chuyển đổi ADC và DAC

3.8.1. Chuyển đổi ADC

- Chuyển đổi A/D trong một số biến thể của LPC2000 là một bộ chuyển đổi 10 bít

với tốc độ chuyển đổi 2.44 uSec hoặc 410KSps. Bộ chuyển đổi A/D có 4 hoặc 8 bít

đầu ra tùy từng phiên bản.

Page 84: Lap Trinh ARM - Ngo Vinh

Trang 84

Hình 3.30 Chuyển đổi A/D có 4 hoặc 8 kênh đầu ra với độ phân giải 10 bít

-Thanh ghi điều khiển A/D thiết lập cấu hình chuyển đổi và khởi động bộ chuyển

đổi.

- Trƣớc hết phải cài đặt xung clock cho thiết bị, xung clock A/D sẽ phân phối xung

clock tới tất cả các thiết bị từ nguồn xung PCLK. Xung PCLK phải đƣợc chia xuống

4.5MHz. Đây là giá trị xung cực đại, nếu PCLK không thể đƣợc chia xuống 4.5MHz

thì giá trị gần nhất với 4.5MHz sẽ đƣợc chọn.

Hình3.31. Các bít của thanh ghi điều khiển AD

PCLK đƣợc chia theo giá trị lƣu trong CLKDIV và theo công thức sau:

CLKDIV = ( PCLK/Adclk) - 1

Thí dụ: Mô phỏng chuyển đồi A/D trong chế độ phần cứng

int main(void)

{

VPBDIV = 0x00000002; //thiet lap Pclk la 30 MHz

IODIR1 = 0x00FF0000; // P1.16..23 dinh nghia cac chan ra

ADCR = 0x00270607; // khoi dong A/D: 10-bit AIN0 @ 3MHz

VICVectCntl0 = 0x00000032; //ket noi toi A/D qua slot 0

VICVectAddr0 = (unsigned)AD_ISR; //lay dia chi cua ngat IRQ dua vao

Page 85: Lap Trinh ARM - Ngo Vinh

Trang 85

//VIC slot

VICIntEnable = 0x00040000; //cho phep ngat

while(1) {;}

}

void AD_ISR (void)

{

unsigned val,chan;

static unsigned result[4];

val = ADDR;

val = ((val >> 6) & 0x03FF); //Trich ket qua A/D

chan = ((ADCR >>0x18) & 0x07);

result[chan] = val;

}

3.8.2. Chuyển đổi D/A

- Biến thể LPC2132/2138 bộ chuyển đổi DA 10 bít.

- Bộ chuyển đổi này đơn giản chỉ có 1 thanh ghi.

- DAC đƣợc cho phép bằng cách ghi tới bít 18 và 19 của PINSEL1 chuyển chân

0.25 từ GPIO thành chức năng AOUT. Chú ý rằng một kênh của bộ chuyển

A/D cũng sử dụng chân này.

Hình 3.32. Thanh ghi điều khiển D/A

Bộ điều khiển D/A đƣợc khởi động bằng cách ghi giá trị tới bít VALUE trong thanh

ghi điều khiển. Thời gian chuyển đổi phụ thuộc vào bít BIAS. Nếu =1 thì thời gian

chuyển đổi là 2.5uSec nhƣng có thể đạt tới 700uA. Nếu =0 thì thời gian chuyển đổi là

1uSec nhƣng có thể đạt đến 350uA. Tuy nhiên, tổng thời gian thiết lập phụ thuộc vào

trở kháng bên ngoài.

3.9. Truyền dữ liệu qua CAN(Controller Area Network)

Page 86: Lap Trinh ARM - Ngo Vinh

Trang 86

- Các biến thể của LPC có thể có 4 bộ điều khiển can độc lập trên board.

Giao thức CAN (Controller Area Network) đƣợc phát triển bởi Robert Bosch cho

mạng tự động (Automotive Networking) vào năm 1982. Trải qua 22 năm sau, CAN trở

thành một chuẩn cho mạng tự động và trở lên hấp dẫn đối với các hệ thống không tự

động mà muốn yêu cầu một số nút đƣợc nhúng vào. CAN có những đặc tính hấp dẫn

đối với những ngƣời phát triển hệ nhúng. Nó có chi phí thấp, dễ hiện thực hóa, các

mạng ngang hàng với đặc tính kiểm tra lỗi mạnh và tốc độ truyền cao, hàng Mbit/s. Mỗi

gói CAN khá nhỏ và có thể giữ một khối lƣợng cực đại là 8 byte dữ liệu. Do đó, CAN

rất phù hợp với các mạng nhúng nhỏ để truyền một lƣợng dữ liệu nhỏ giữa các nút một

cách tin cậy.

Thiết kế node CAN:

Một nút CAN điển hình đƣợc thiết kế nhƣ sau:

Hình 3.33. Cấu trúc CAN

- Một đặc tính quan trọng khi thiết kế CAN là bộ điều kiển CAN có đƣờng truyền

và nhận dữ liệu riêng biệt và từ thiết bị vật lý. Bởi vậy một nút đang ghi dữ liệu lên

bus, đồng thời cũng lắng nghe phản hồi trên bus. Do vậy cần có cơ chế phân xử và

phát hiện lỗi trên bus.

Hai mức logic đƣợc ghi lên 2 cặp cáp nhƣ hình dƣới, hai mức logic 0 thể hiện trạng

thái rỗi của bus.

Page 87: Lap Trinh ARM - Ngo Vinh

Trang 87

Hình 3.34.

Cấu trúc một thông điệp CAN:

Hình 3.35. Cấu trúc thông điệp CAN

Các bít định danh dùng để dịnh danh gói tin: theo chuẩn 20A có 11 bít định danh, 20B

thụ động thì có bít định danh và 20B chủ động có 29 bít định danh.

RTR luôn bằng 0.

Bít DLC chứa độ dài dữ liệu

Bít CRC chứa mã lỗi khi truyền

Bít ACK: cho phép chấp nhận gói tin

Để truyền một thông điệp CAN, Bộ điều khiển CAN có một tập các thanh ghi điều

khiển và thanh ghi trạng thái nhƣ sau:

Page 88: Lap Trinh ARM - Ngo Vinh

Trang 88

Hình 3.36 Các thanh ghi bộ điều khiển CAN

Tốc độ truyền tính theo công thức: Tốc độ baund=PCLK/(RBRx(1+Tseg1+Tseg2))

Với RBR là tốc đô prescaler.

Cấu trúc thanh ghi định thời prescaler:

Page 89: Lap Trinh ARM - Ngo Vinh

Trang 89

Đoạn chƣơng trình sau mô tả khởi tạo CAN và truyền thông điệp:

C2MOD = 0x00000001; //Khoi dong bo dieu khien CAN

C2BTR = 0x001C001D; //thiet lap bi Timing la 125k

C2MOD = 0x00000000; //dung bo dieu khie CAN

if(C2SR & 0x00000004) //neu bo dem Tx Buffer 1 rong

{

C2TFI1 = 0x00040000; //thiet lap DLC la 4 byte

C2TID1 = 0x00000022; //dia chi Standard Frame la 0x22

C2TDA1 = NetworkData; //copy du lieu vao 4 byte dau tien

C2CMR = 0x00000001; //truyen thong diep

}

Nhận dữ liệu qua CAN:

Page 90: Lap Trinh ARM - Ngo Vinh

Trang 90

Cấu trúc vùng đệm nhận dữ liệu

Hình 3.37. Các thanh ghi dùng khi nhận dữ liệu từ CAN

int main(void)

{

VPBDIV = 0x00000001; //thiet lap PClk la 60MHz

IODIR1 = 0x00FF0000; // thiet lap cac chan ra

PINSEL1|= 0x00040000; //cho phep chan 0.25 la CAN1 RX

C1MOD = 0x00000001; //reset CAN

C1BTR = 0x001C001D; //thiet lap bit Timing la 125k

C1IER =0x00000001; //cho phep nhan ngat

Page 91: Lap Trinh ARM - Ngo Vinh

Trang 91

VICVectCntl0 = 0x0000003A; //chon thu tu uu tien ngat

VICVectAddr0 = (unsigned)CAN1IRQ; //lay dia chi ngat IRQ

//into the VIC slot

VICIntEnable = 0x04000000; //cho phep ngat

AFMR = 0x00000001; //Cam bo loc

C1MOD = 0x00000000; //ket thuc CAM

while(1){;}

}

Page 92: Lap Trinh ARM - Ngo Vinh

Trang 92

TÀI LIỆU THAM KHẢO

[1]. Philips (2005), The insider‟s guide to the Philips ARM7 based microcontroller.

[2]. Jean J. Labrosse (2000), Embbeded System Building Block Second Edition:

Commplete and ready to use in module C, R&D Books

[3]. Michael Barr, Anthony Massa (2006), Programming Embedded Systems, O'Reilly