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

tóm tắt luận văn thạc sĩ kỹ thuật nghiên cứu thiết kế thiết bị huấn luyện báo vụ trên công nghệ DSPIC

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

Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
LỜI MỞ ĐẦU
Đối với quân đội ta nhiệm vụ trọng tâm trong thời bình là huấn luyện chiến
đấu để đảm bảo cho bộ đội có đủ sức mạnh tinh thần, vật chất sẵn sàng hoàn thành
các nhiệm vụ được giao.
Quán triệt chủ trương hiện đại hoá quân đội. Đáp ứng các yêu cầu ngày càng
tăng của công tác huấn luyện quân sự trong thời kỳ đổi mới và hiện đại.
Sự phát triển vượt bậc của khoa học kỹ thuật trong những năm gần đây. Đối
với lĩnh vực quân sự, công nghệ điện tử, tin học nói chung và kỹ thuật vi xử lý nói
riêng được ứng dụng để cải tiến, nâng cấp và chế tạo ra các trang thiết bị mới phục
vụ huấn luyện chiến đấu và sẵn sàng chiến đấu.
Hiện nay phương thức truyền tin vô tuyến điện báo MORSE (Bảng mã
MORSE chính là cở sở để mã hoá / giải mã thông tin khi thực hiện truyền tin vô
tuyến điện báo) vẫn là phổ biến. Qua quá trình học tập, cùng với sự tìm hiểu tại các
đơn vị thông tin. Tôi nhận thấy rằng các trang thiết bị dùng cho huấn luyện báo vụ
hiện nay còn rất thô sơ. Chính vì vậy, phải sử dụng phương pháp huấn luyện thủ
công là chủ yếu. Từ đó chất lượng huấn luyện báo vụ, cũng như trình độ của đội
ngũ nhân viên báo vụ hiện nay còn nhiều hạn chế.
Thông qua nội dung các môn học của khoá học, Đã trang bị các kiến thức rất
đầy đủ về lập trình chương trình điều khiển cho các ONCHIP, cũng như các kiến
thức về thiết kế các mạch điện chức năng có ứng dụng các ONCHIP. Trên cơ sở của
bộ vi xử lý cơ bản của hãng Intel, ngày nay với công nghệ cao người ta đã chế tạo
ra các bộ vi xử lý ONCHIP có tốc độ xử lý nhanh, dung lượng bộ nhớ ROM, RAM
lớn và tích hợp sẵn nhiều chức năng. Tiểu biểu là các ONCHIP như 89, AVR,
đặc biệt là PIC và DSPIC do hãng MICROCHIP sản xuất.
PIC, DSPIC phù hợp với tất cả các ứng dụng từ đơn giản đến phức tạp. Đặc
biệt nó rất phù hợp khi giải quyết các bài toán về điều khiển, nên người ta còn gọi
nó là vi điều khiển PIC, DSPIC.
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
1


Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
Ngoài việc dùng ngôn ngữ lập trình ASM thông dụng, chúng ta còn có thể sử
dụng các ngôn ngữ lập trình khác như : C, PASCAL, BASIC để lập trình cho hệ
thống của mình.
Tất cả các nội dung trên là lý do chính thúc đẩy tôi đi đến chọn đề tài cho luận văn
tốt nghiệp có tên là: "Nghiên cứu thiết kế thiết bị huấn luyện báo vụ trên công
nghệ DSPIC".
Đề tài gồm có các chương:
+ Chương một: Tổng quan về công nghệ vi điều khiển PIC, DSPIC.
+ Chương hai: Lập trình cho các chức năng của PIC, DSPIC.
+ Chương ba: Tổng quan về thiết bị huấn luyện báo vụ chuyên dùng.
+ Chương bốn: Thiết kế và chế tạo phần cứng.
+ Chương năm: Thiết kế và lập trình phần mềm.
Kết quả nghiên cứu của đề tài là một sản phẩm sẽ được ứng dụng tại các đơn
vị huấn luyện trong quân đội, đảm bảo thông tin vô tuyến điện báo.
Ngoài ra kết quả nghiên cứu của đề tài còn mở ra một hướng mới trong việc
ứng dụng công nghệ PIC, DSPIC để nghiên cứu thiết kế, chế tạo các trang thiết bị
mới trong quân sự hiện nay.
Nội dung của luận văn còn là một nguồn tài liệu tương đối đầy đủ về công
nghệ PIC, DSPIC, cách đưa công nghệ này và các ứng dụng thực tế Giúp cho các
sinh viên khác, hoặc cho những ai muốn học tập và nghiên cứu để ứng dụng công
nghệ này.
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
2
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
Chương 1
TỔNG QUAN VỀ CÔNG NGHỆ VI ĐIỀU KHIỂN PIC, DSPIC
1.1. Giới thiệu về hệ vi điều khiển PIC, DSPIC

Vi điều khiển thực chất là một cấu trúc siêu nhỏ, nó bao gồm các linh kiện
điện tử có kích thước cỡ MICRO hoặc NANO. Các linh kiện này được kết hợp với
nhau, sau đó được nối tới các thiết bị bên ngoài thông qua các chân của vi điều
khiển. Chính vì vậy khi hiểu được kiến trúc của vi điều khiển, chúng ta sẽ rất thuận
tiện khi sử dụng chúng vào ứng dụng của mình.
Kiến trúc của vi điều khiển, cũng giống như kiến trúc máy tính. Các vi điều
khiển hiện nay, thường phổ biến ở một trong hai dạng kiến trúc sau. Kiến trúc VON
NEUMANN, và kiến trúc HARVARD. Sự khác nhau giữa hai kiến trúc này, là ở
chỗ việc tổ chức bộ nhớ dữ liệu và bộ nhớ chương trình.
Kiến trúc VON NEUMANN tổ chức bộ nhớ dữ liệu và bộ chương trình
chung với nhau, do vậy vi điều khiển có kiến trúc này sẽ sử dụng chung đường
truyền (BUS). Ưu điểm của vi điều khiển có kiến trúc này là tận dụng được tài
nguyên bộ nhớ, nhưng nhược điểm là tốc độ xử lý không đạt cao.
Còn kiến trúc HARVARD lại tách rời bộ nhớ dữ liệu và bộ nhớ chương
trình, do đó đường truyền (BUS) của nó được tách riêng ra. Vì vậy vi điều khiển có
kiến trúc này là đạt tốc độ xử lý cao, nhưng nhược điểm là không tận dụng được tài
nguyên bộ nhớ. Mặt khác đường truyền dữ liệu và đường truyền lệnh điều khiển, có
thể có dung lượng khác nhau.
Hiện nay có 3 họ vi điều khiển nổi tiếng, đó là 8051 (Bao gồm cả AVR),
MOTOROLA và PIC (Bao gồm cả DSPIC). Để hiểu được vi điều khiển, sử dụng
thành thạo nó chúng ta cần phải có các kiến thức sau:
- Tìm hiểu về kiến trúc máy tính, cơ bản về kiến trúc VON MEUMANN,
kiến trúc HARVARD;
- Tìm hiểu khái niệm RISC, CISC;
- Khái niệm thanh ghi;
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
3
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
- Khái niệm STACK;

- Khái niệm con trỏ POINTER;
- Khái niệm địa chỉ, địa chỉ gián tiếp của một thanh ghi;
- Khái niệm về định thời (TIMER);
- Khái niệm về ngắt trong, ngắt ngoài.
- Các chuẩn giao tiếp RS232, USB, I2C
- Thành thạo một trong số các ngôn ngữ lập trình cho vi điều khiển.
PIC là tên viết tắt của "Máy tính thông minh" (PROGRAMMABLE
INTELLIGENT COMPUTER) do hãng GENERAL INSTRUMENT đặt tên cho
con vi điều khiển đầu tiên của hãng là PIC1650. Đây là con vi điều khiển đầu tiên,
đồng thời nó còn là tiền đề cho sự ra đời của các vi điều khiển họ PIC sau này của
hãng.
Họ vi điều khiển PIC có cấu trúc HARVARD, do vậy nó có tốc độ xử lý rất
cao. Đồng thời dung lượng bộ nhớ dữ liệu, bộ nhớ chương trình tương đối lớn. Họ
vi điều khiển PIC phù hợp với các ứng dụng từ đơn giản đến các ứng dụng phức
tạp, đặc biệt nó phù hợp với các ứng dụng có liên quan đến các cơ cấu điều khiển.
Đến ngày nay, PIC1650 được phát triển thành PIC16C54. Hãng
MICROCHIP (WWW.MICROCHIP.COM) đang tiếp tục phát triển các sản phẩm vi
điều khiển, trong đó có vi điều khiển PIC.
Cho đến nay, các sản phẩm vi điều khiển PIC của MICROCHIP đã gần 100
loại sản phẩm từ họ 10Fxxx, 18LFxxx, 18Fxxx đến các họ 12Cxxx, 12Fxxx,
16Cxxx, 17Cxxx, 16Fxxx, 16Fxxx,16FxxxA, 16LFxxxA, 18Fxxx, 18LFxxx Tuy
nhiên có một số họ PIC hiện nay không còn được sản xuất nữa. Hiện nay hãng
MICROCHIP đã có các họ vi điều khiển 16-BIT, gồm PIC24H và PIC24F. Tiếp
đến là họ vi điều khiển 32-BIT có tên là PIC32MX, và mới đây nhất là họ vi điều
khiển DSPIC30F và DSPIC33F.
Phân loại PIC theo các chữ cái: Các họ PIC xxCxx được đưa vào một nhóm,
gọi là nhóm OTP (ONE TIME PROGRAMMANBLE). Nhóm này chỉ có thể lập
trình và nạp chương trình cho nó được một lần duy nhất, và không thể thay đổi
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
4

Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
chương trình bên trong của nó bằng mạch điện thông thường. Nhóm thứ hai theo
cách phân chia này, đó là số còn lại với các chữ cái F, hoặc LF và duy nhất 16C84.
Nhóm này là nhóm FLASH, cho phép ghi xoá bằng các mạch điện tử thông thường
(Ngày nay người ta còn sản xuất các loại này). Chúng ta gọi nhóm này là nhóm
FLASH, nhưng thực tế thì nó bao gồm cả nhóm EEPROM và FLASH. Tuy nhiên,
vì chung đặc điểm là có thể ghi xoá nhiều lần nên chúng ta gọi chung thành nhóm
FLASH.
Phân loại PIC theo hai con số đầu tiên của sản phẩm: Đây là cách phân loại
thông dụng, bởi vì các họ PIC và DSPIC hiện này đều thuộc nhóm FLASH. Do vậy
cách phân loại này sẽ nói lên được sự khác nhau của các họ vi điều khiển PIC và
DSPIC. Loại thứ nhất là dòng PIC cơ bản (BASE-LINE), gồm các PIC 12Cxxx,
loại thứ hai là các dòng PIC 10,12F và 16, gọi là dòng phổ thông (MID-RANGE).
Loại thứ ba là dòng PIC 18 (HIGH-END). Sự khác nhau của các dòng này chính là
độ dài lệnh (INSTRUCTION WORD LENGTH), với dòng BASE-LINE có độ dài
lệnh là 12 BIT, MID-RANGE có độ dài lệnh là 14 BIT và HIGH-END có độ dài từ
lệnh là 16-BIT. Tuy nhiên các dòng PIC có độ dài từ lệnh lớn hơn thì thường có bộ
nhớ ROM, RAM lớn hơn, tích hợp sẵn nhiều chuẩn giao tiếp ví dụ:
Dòng PIC 16F8xxA đây là dòng PIC MID-RANGE, thông dụng nhất hiện
nay ở Việt Nam là PIC 16F877A. Cấu hình cụ thể của dòng này như sau:
Bảng 1-1. Cấu hình của PIC16FxxxA
Từ bảng trên chúng ta thấy rằng PIC 16F877A có cấu hình như sau:
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
5
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
- Bộ nhớ chương trình (PROGRAM MEMORY): 14.3 KBYTES.
- Số lệnh điều khiển (WORD INSTRUCTIONS): 8192 lệnh.
- Bộ nhớ SRAM: 368 BYTES.

- Bộ nhớ EEPROM (bộ nhớ EPROM nội): 256 BYTES.
- Số chân I/O = 33 chân.
- Số chân nhận tín hiệu vào để chuyển đổi A/D 10 BIT: 8 chân.
- Tích hợp sẵn 2 bộ giao tiếp PWM (Điều khiển động cơ).
- Tích hợp sẵn 1 giao tiếp SPI.
- Tích hợp sẵn 1 giao tiếp I2C.
- Tích hợp sẵn 1 giao tiếp USART.
- Tích hợp sẵn 2 bộ định thời 8 BIT, và 1 bộ định thời 10 BIT.
- Tích hợp sẵn 2 bộ so sánh.
Dòng PIC 18Fxxxx đây là dòng PIC HIGH-END, thông dụng nhất hiện nay
ở Việt Nam là PIC 18F4550. Cấu hình cụ thể của dòng này như sau:
Bảng 1-2. Cấu hình của PIC18Fxxxx
Từ bảng trên chúng ta thấy rằng PIC 18F4550 có cấu hình như sau:
- Bộ nhớ chương trình (PROGRAM MEMORY): 32 KBYTES (Lớn gấp 2
lần so với dòng 16F877A).
- Số lệnh điều khiển (WORD INSTRUCTIONS): 16384 lệnh.
- Bộ nhớ SRAM: 2048 BYTES.
- Bộ nhớ EEPROM (bộ nhớ EPROM nội): 256 BYTES.
- Số chân I/O = 35 chân.
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
6
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
- Số chân nhận tín hiệu vào để chuyển đổi A/D 10 BIT: 13 chân.
- Tích hợp sẵn 2 bộ giao tiếp PWM (Điều khiển động cơ).
- Tích hợp sẵn 1 giao tiếp SPI. Tích hợp sẵn 1 giao tiếp I2C.
- Tích hợp sẵn 1 giao tiếp USART.
- Tích hợp sẵn 1 bộ định thời 8 BIT, và 3 bộ định thời 16 BIT.
- Tích hợp sẵn 2 bộ so sánh.
- Tích hợp sẵn 1 chuẩn giao tiếp USB.

Còn đối với dòng DSPIC cũng có cấu hình cụ thể như sau:
Bảng 1-3. Cấu hình của DSPIC30Fxxxx
1.2. Cấu trúc của PIC, DSPIC
1.2.1. Cấu trúc bộ chân cắm
PIC và DSPIC thường có cấu trúc vỏ chíp (Bộ chân cắm) kiểu QFN, TQFP nhưng
thông dụng nhất vẫn là kiểu PDIP. Cụ thể như sau:
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
7
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
Hình 1-1. Cấu trúc bộ chân cắm QFN, TQFP của PIC
Hình 1-2. Cấu trúc bộ chân cắm PDIP của DSPIC và PIC
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
8
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
1.2.2. Chức năng các chân của vi điều khiển
Một chân của vi điều khiển thường có nhiều chức năng, nhưng tại một thời
điểm nó chỉ thực hiện được một chức năng cụ thể. Việc thực hiện chức năng nào là
do người lập trình quy định, chức năng của một chân có thể được thay đổi khi vi
điều khiển đang hoạt động. Thông thường các chân của vi điều khiển được chia
thành các nhóm sau đây:
- Các chân dùng để cấp nguồn.
- Các chân dùng để nối tới thạch anh.
- Các cổng I/O.
- Các chân chức năng.
Ví dụ vi điều khiển 18F4550, chức năng của các chân cơ bản như sau:
Trong đó các chân cơ bản có chức năng như sau:
+ Các chân cấp nguồn:
- Chân 11, 32 (VDD).

- Chân 12, 31(VSS).
+ Các chân nối tới thạch anh, hoặc bộ dao động ngoài:
- Chân 13 (Osc1).
Hình 1-3. Cấu trúc chi tiết bộ chân cắm của PIC 18F4550
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
9
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
- Chân 14(Osc2).
+ Các cổng I/O bao gồm:
- Cổng A (A0 A5), từ chân 2 đến chân 7; 6 pin
- Cổng B (B0 B7), từ chân 33 đến chân 40; 8 pin
- Cổng C (C0 C7), từ chân 15 đến chân 18 và từ chân 23 đến chân 26; 8 pin
- Cổng D (D0 D7), từ chân 19 đến chân 22 và từ chân 27 đến chân 30; 8 pin
- Cổng E (E0 E2), từ chân 8 đến chân 10;. 3 pin
+ Các chân chức năng cơ bản bao gồm:
- Chân 1 (RESET);
- Chân 18, 23, 24 (Giao tiếp USB);
- Chân 25, 26 (Giao tiếp USART); (25=TxD=RC6; 26=RxD=RC7)
- Chân 33, 34 (Giao tiếp I2C);
Ngoài ra còn có các chân thực hiện các chức năng khác như: Nạp
chương trình, giao tiếp PWM, A/D, ngắt ngoài. Mỗi một cổng, một chân của
vi điều khiển đều có một địa chỉ PORT, và một địa chỉ SET_TRIS. Thao tác
trên hai địa chỉ này, cho phép chúng ta sử dụng được các cổng, các chân đúng theo
mục đích sử dụng.
1.3. Các loại mạch nạp và phần mềm điều khiển nạp cho PIC, DSPIC
Có rất nhiều loại mạch nạp cho PIC, DSPIC. Mỗi một loại mạch nạp thường
đi kèm với một phần mềm, để điều khiển mạch nạp này hoạt động. Thông thường
các mạch nạp cho PIC thì cũng nạp được cho DSPIC. Tuy nhiên cũng có một số
mạch nạp cho PIC có cấu tạo đơn giản, hoặc phần mềm điều khiển không hỗ trợ do

vậy sẽ không nạp được cho DSPIC.
+ Các kiểu mạch nạp phổ biến hiện nay
- Mạch nạp kết nối qua cổng song song (Hay còn gọi là LPT): Ưu điểm của
loại mạch nạp có kết nối kiểu này là tốc độ nạp nhanh, an toàn cho PIC. Nhược
điểm là do các máy tính hiện nay thường không có cổng LPT, do vậy mạch nạp này
ít được sử dụng; Đồng thời thường không hỗ trợ nạp cho DSPIC.
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
10
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
Hình 1-4. Mạch nạp PIC-PG3
Hình 1-5. Phần mềm điều khiển nạp WINPIC800
- Mạch nạp kết nối qua cổng nối tiếp (COM): Mạch nạp loại này thường có
kết cấu đơn giản nhất trong tất cả các loại mạch nạp, do vậy nó rất gọn nhẹ. Đồng
thời mạch nạp loại này thường lấy điện áp từ cổng COM, để làm nguồn cung cấp
cho mạch hoạt động. Loại mạch nạp này có nhược điểm là thường không hỗ trợ nạp
cho DSPIC, không đảm bảo an toàn cho PIC khi nạp. Bởi vì chúng sử dụng trực
tiếp nguồn điện từ cổng COM, để làm điện áp lập trình khi nạp.
Mặt khác các LAPTOP hiện nay, thường không có sẵn cổng COM. Khi sử
dụng bộ chuyển đổi USB to COM, thì mạch nạp loại này không thể hoạt động được.
Mạch nạp có kết nối cổng COM, cũng sử dụng phần mềm điều khiển
WINPIC, hoặc ICPROG. Ngoài nạp được cho hầu hết các loại PIC, mạch này còn
có thể nạp được cho các loại EPROM loại 24Cxxx và tương đương.
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
11
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
Hình 1-6. Mạch nạp PIC-PG1 Hình 1-7. PIC-ICS/ICD Connector
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
12

Hình 1-9. Mạch nạp PIC-PG2
Hình 1-8. Mạch nạp PIC-PG3
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến


Hình 1-10. Phần mềm điều khiển nạp IC-PROG 1.01
- Mạch nạp kết nối qua cổng USB: Đây là loại mạch nạp cho PIC phổ biến
nhất hiện nay, được thiết kế bởi hãng MICROCHIP. Loại mạch nạp này được kết
nối trực tiếp với cổng USB của máy tính, sử dụng nguồn từ cổng USB để làm
nguồn nuôi cho mạch nạp.
Nó có cấu tạo tương đối phức tạp, nên nạp được hầu hết tất cả các loại PIC,
EPROM và hỗ trợ nạp cho cả DSPIC. Tốc độ nạp nhanh, đảm bảo an toàn cho PIC.
Tự động giám sát điện áp nạp thích hợp với từng loại PIC, DSPIC. Nhưng nhược
điểm của nó là: Việc kết nối với máy tính cần phải có DRIVE, và hay sảy ra xung
đột; Quá trình nạp phải tuân thủ nghiêm ngặt các bước thực hiện, nếu không sẽ bị
lỗi (Hỏng) mạch nạp.
Các mạch nạp kết nối qua cổng USB, thường sử dụng phần mềm điều khiển
nạp MPLAB-IDE của hãng MICROCHIP.
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
13
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến

Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
14
Hình 1-11. Mạch nạp PIC-MCP-USB
Hình 1-12. Mạch nạp ICD2-USB
Hình 1-13. Mạch nạp GTP-USB
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân

Tiến

1.4. Các chương trình hỗ trợ viết mã và biên dịch cho PIC, DSPIC
Sự ra đời của một loại vi điều khiển, đi kèm với việc phát triển phần mềm
ứng dụng cho việc lập trình cho con vi điều khiển đó. Vi điều khiển chỉ hiểu và làm
việc với hai con số 0 và 1. Ban đầu để lập trình cho vi điều khiển là làm việc với
dãy các con số 0 và 1. Sau này khi kiến trúc của vi điều khiển ngày càng phức tạp,
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
15
Hình 1-14. Mạch nạp GTP-USB
Hình 1-15. Phần mềm điều khiển nạp MPLAB-IDE
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
số lượng thanh ghi lệnh nhiều lên. Việc lập trình với dãy các số 0 và 1 không còn
phù hợp nữa, đòi hỏi phải có sự ra đời của các ngôn ngữ lập trình cho vi điều khiển.
Chúng ta có thể viết mã lệnh cho PIC, DSPIC bằng bất cứ một phần mềm
soạn thảo nào đó. Sau đó sử dụng trình biên dịch phù hợp để dịch sang dạng Hex,
rồi nạp cho PIC hoặc DSPIC. Nhưng chúng ta muốn nhận được sự hỗ trợ khi lập
trình, thì chúng ta phải sử dụng một trong các phần mềm chuyên dùng sau đây:
- MPLAB: Đây là phần mềm viết mã, biên dịch và điều khiển nạp của hãng
MICROCHIP. Nguyên bản của phần mềm này chỉ cho phép chúng ta viết mã lệnh
cho PIC, và chỉ dùng ngôn ngữ AMSEMBLY (ASM). Tuy nhiên khi kết hợp
(Nhúng) thêm với CCS, thì MPLAB cho phép viết mã với ngôn ngữ C và cho cả
được với DSPIC.
Ưu điểm của MPLAB, khi viết mã bằng ASM là khi biên dịch file *.Hex có
kích thước nhỏ. Đây là ưu điểm nổi trội, duy nhất chỉ có được ở MPLAB.
Nhưng nhược điểm của MPLAB là việc lập trình thường rất khó khăn, đòi
hỏi người lập trình phải nắm chắc được cấu trúc của PIC; Cũng như các kiến thức
về vi xử lý Mặt khác trong MPLAB thường không có sẵn các thư viện (Hàm và
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp

16
Hình 1-16. Phần mềm biên dịch MPLAB
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
thủ tục), do vậy để truy xuất đến các thiết bị ngoại vi như LCD, EPROM, USART,
USB
thường phải thực hiện thủ công. Do vậy lại đỏi hỏi người lập trình phải hiểu tường
tận được cả cấu trúc của thiết bị ngoại vi liên quan.
Cấu trúc một chương trình viết bằng ASM trong môi trường MPLAB như
sau:
#include <P18F4431.inc> 1) header file
org 0x000000 2) Địa chỉ vector ngắt :
goto MAIN Khi cú ngắt xảy ra thỡ pointer sẽ nhảy
org 0x000008 đến nhón ISR_HIGH hoặc ISR_LOW
goto ISR_HIGH ISR: viết tắt của Interrupt Service
org 0x000018 Rountine . Địa chỉ ngắt cụ thể của từng
goto ISR_LOW loại chip, loại ngắt cao hay thấp do
org 0x000030 datasheet cung cấp.
MAIN 3) Bắt đầu chương trỡnh chớnh
…………………
…………………
. ………………
“chương trỡnh con 1” Chương trỡnh con bắt đầu bằng TấN (
“chương trỡnh con 2” lable) của chương trỡnh đó và kết thúc
bằng bằng chữ RETURN. Chương trỡnh
ngắt được xem là chương trỡnh con, kết
thỳc bằng RETFIE
END
- CCS C: Là một phần mềm cho phép lập trình và biên dịch cho vi điều
khiển bằng ngôn ngữ C. `

Ưu điểm của CCS là dùng ngôn ngữ C, nên chương trình rất mạch lạc, rõ
ràng. Câu lệnh lập trình đơn giản, ngắn gọn. Có rất nhiều các thư viện, để hỗ trợ
viết mã. Sau cùng là kích thước file *.Hex khi biên dich xong cũng vừa phải (Trong
giới hạn chấp nhận được).
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
17
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
Nhược điểm lớn nhất của CCS là trong quá trình biên dịch có thể phát sinh
mã dạng Hex sai; Do vậy nhiều khi chúng ta lập trình rất rõ ràng nhưng PIC vẫn
làm việc không đúng theo yêu cầu, hoặc cho kết quả sai. Để tránh được điều này,
đòi hỏi
người lập trình phải có nhiều kinh nghiệm. Đơn giản hoá các thuật toán phức tạp,
tránh những cấu trúc lệnh có thể dẫn đến lỗi phát sinh mã Hex sai.
Cấu trúc một chương trình viết bằng C trong môi trường CCS như sau:
#include <18F4431.h> //header file
#use delay //khai báo tần số thạch anh.
#fuses //khai báo cấu hình cần sử dụng
Khai báo các biến toàn cục.
Chương trình ngắt.
Các chương trình con.
Main //Chương trình chính.
{
Gọi các chương trình con.

}
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
18
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến

Hình 1-17. Phần mềm biên dịch CCS
Ngoài các phần mềm soạn thảo và biên dịch nêu trên, hiện nay còn có rất
nhiều các phần mềm khác soạn thảo và biên dịch cho PIC. Các phần mềm này sử
dụng ngôn ngữ lập trình như: PASCAL, BASIC Nhìn chung các phần mềm này ít
được sử dụng bởi vì ba nguyên nhân sau: Một là phải mua bản quyền hợp pháp thì
mới có thể biên dịch được; Hai là *.Hex sau khi biên dịch thường có kích thước lớn,
nên đòi hỏi phải sử dụng PIC có bộ nhớ chương trình lớn; Ba là do lập trình trên các
công cụ, đối tượng có sẵn nên người lập trình không can thiệp sâu được vào cấu
trúc bên trong của vi điều khiển.
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
19
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
Chương 2
LẬP TRÌNH CHO CÁC CHỨC NĂNG CỦA PIC, DSPIC
2.1. Ngôn ngữ lập trình CCS
Sự ra đời của một loại vi điều khiển đi kèm với việc phát triển phần mềm
ứng dụng, cho việc lập trình cho con vi điều khiển đó. Vi điều khiển chỉ hiểu và làm
việc với hai con số 0 và 1. Ban đầu để việc lập trình cho vi điều khiển, người ta
phải làm việc với dãy các con số 0 và 1. Sau này khi kiến trúc của vi điều khiển
ngày càng phức tạp, số lượng thanh ghi lệnh nhiều lên. Do đó việc lập trình với dãy
các số 0 và 1 không còn phù hợp nữa, đòi hỏi ra đời một ngôn ngữ mới thay thế. Từ
đó ngôn ngữ lập trình ASSEMBLY ra đời, sau đó là ngôn ngữ C ra đời. Nhu cầu
dùng ngôn ngữ C để thay cho ASSEMBLY trong việc mô tả các lệnh lập trình cho
vi điều khiển một cách ngắn gọn, dễ hiểu hơn đã dẫn đến sự ra đời của nhiều
chương trình soạn thảo và biên dịch C cho vi điều khiển: KEIL C, HT-PIC,
MIKROC, CCS
CCS là trình biên dịch lập trình ngôn ngữ C cho vi điều khiển PIC của hãng
MICROCHIP. Chương trình là sự tích hợp của 3 trình biên dịch riêng biệt cho 3
dòng PIC khác nhau đó là:

- PCB biên dịch cho dòng PIC 12-BIT.
- PCM biên dịch cho dòng PIC 14-BIT.
- PCH biên dịch cho dòng PIC 16 và 18-BIT.
Tất cả 3 trình biên dịch này được tích hợp lại vào trong một chương trình bao
gồm cả soạn thảo và biên dịch là CCS, phiên bản mới nhất hiện nay là PCWH
COMPILER VER 3.227 cho phép biên dịch được cả cho DSPIC.
Giống như nhiều trình biên dịch C khác cho PIC, CCS giúp cho chúng ta
nắm bắt nhanh chóng được vi điều khiển PIC, DSPIC và sử dụng chúng trong các
dự án. Các chương trình điều khiển sẽ được thực hiện nhanh chóng và đạt hiệu quả
cao thông qua việc sử dụng ngôn ngữ lập trình cấp cao - ngôn ngữ C.
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
20
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
Ngoài ra CCS còn cho phép chèn các đoạn mã ASSEMBLY trong chương
trình, hoặc nhúng CCS vào trong môi trường lập trình và biên dịch MPLAB, để cho
MPLAB có thể lập trình và biên dịch được bằng ngôn ngữ C.
2.2. Lập trình ghi đọc trên các PORT
Việc lập trình ghi / đọc trên các cổng, hay còn gọi là lập trình nhập / xuất dữ
liệu trên các cổng của PIC là dạng lập trình đơn giản nhất. Một PIC thông dụng
thường có các PORT sau:
Tuỳ từng loại PIC mà số lượng các PORT và số chân của từng PORT sẽ
khác nhau. Đồng thời cũng tuỳ từng loại PIC mà địa chỉ của từng PORT cũng khác
nhau, chẳng hạn với PIC 16F877A thì PORT B có địa chỉ cổng là 0x6, còn với PIC
18F4550 thì PORT B lại có địa chỉ là 0xF81.
Một PORT có hai địa chỉ đó là địa chỉ cổng và địa chỉ SET_TRIS; Địa chỉ
SET_TRIS cho phép chúng ta xác định PORT đó là nhập hay xuất dữ liệu ra. Nếu
gán cho các chân của PORT trong địa chỉ SET_TRIS đều bằng 1, thì PORT chỉ có
thể nhận dữ liệu vào. Ngược lại nếu gán các chân của PORT trong địa chỉ
SET_TRIS đều bằng 0, thì PORT đó chỉ có thể xuất dữ liệu ra.

* Các hàm sau sẽ thực hiện xuất / nhập dữ liệu ra PORT:
+ Output_low(PIN) và Output_high(PIN):
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
21
P I C 1 8 F 4 5 5 0 - 1
2
3
4
5
6
7
3 3
3 4
3 5
3 6
3 7
3 8
3 9
4 0
1 5
1 6
1 7
1 8
2 3
2 4
2 5
2 6
1 9
2 0
2 1

2 2
2 7
2 8
2 9
3 0
1 3
1 4
3 2
1 1
3 1
1 2
1
8
9
1 0
R A 0 / A N 0
R A 1 / A N 1
R A 2 / A N 2 / V R E F - / C V R E F
R A 3 / A N 3 / V R E F +
R A 4 / T 0 C K I / C 1 O U T / R C V
R A 5 / A N 4 / S S / H L V D I N / C 2 O U T
R B 0 / A N 1 2 / I N T 0 / F L T 0 / S D I / S D A
R B 1 / A N 1 0 / I N T 1 / S C K / S C L
R B 2 / A N 8 / I N T 2 / V M O
R B 3 / A N 9 / C P P 2 / V P O
R B 4 / A N 1 1 / K B I 0 / C S S P P
R B 5 / K B I 1 / P G M
R B 6 / K B I 2 / P G C
R B 7 / K B I 3 / P G D
R C 0 / T 1 O S O / T 1 3 C K I

R C 1 / T 1 O S I / C C P 2 / U O E
R C 2 / C C P 1 / P 1 A
V u s b
R C 4 / D - / V M
R C 5 / D + / V P
R C 6 / T X / C K
R C 7 / R X / D T
R D 0 / S P P 0
R D 1 / S P P 1
R D 2 / S P P 2
R D 3 / S P P 3
R D 4 / S P P 4
R D 5 / S P P 5 / P 1 D
R D 6 / S P P 6 / P 1 C
R D 7 / S P P 7 / P 1 B
O S C 1 / C L K I
O S C 2 / C L K O / R A 6
V D D
V D D
V S S
V S S
M C L R / V P P
R E 0 / A N 5 / C K 1 S P P
R E 1 / A N 6 / C K 2 S P P
R E 2 / A N 7 / O E S P P
Port A từ A0 A5
Port E từ E0 E2
Port C từ C0 C7
Port B từ B0 B7
Port D từ D0 D7

Hình 2-1. Các Port của PIC 18F4550
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
- Trong đó: PIN là tên chân của PIC.
- Chức năng: Thiết lập mức thấp, hoặc mức cao cho một chân của PIC.
- Ví dụ: Output_low(C0): Thiết lập mức thấp cho chân C0 của PIC.
+ Output_BIT(PIN,value):
- Trong đó: Value bằng 0 hoặc 1.
- Chức năng: Hàm này xuất giá trị 0 hoặc 1 ra 1 chân của PIC. Thường dùng
nó khi giá trị ra tuỳ thuộc vào giá trị của một biến nào đó.
- Ví dụ: Output_BIT(C0,docphim): Xuất ra chân Co giá trị của biến docphim
(kiểu biên int1).
+ Input(PIN):
- Chức năng: Hàm này trả về giá trị o hay 1chính là trạng thái của 1 chân của
PIC.
- Ví dụ: a=input(C1): Đọc trạng thái của chân C1 gán vào biên a (Biến a có
thể là int1, hoặc int8).
+ Output_X(value):
- Trong đó: X là tên của PORT.
- Chức năng: Xuất giá trị của một biến ra một cổng có tên được xác định bởi
X.
- Ví dụ: Output_D(docphim): Xuất giá trị của biến docphim ra PORT D
(Biến docphim phải là int8).
+ Input_X():
- Chức năng: Hàm này trả về một giá trị 8 BIT chính là trạng thái của PORT
được xác định bởi X.
- Vi dụ: doc_PORT=input_A: Lấy giá trị của PORT A gán vào biến
doc_PORT (biến doc_PORT phải là int8).
Ngoài các cách xuất / nhập trực tiếp nêu trên, chúng ta còn có thể gán một
PIN hay một PORT của PIC cho một biến nào đó. Sau đó chỉ việc thao tác trên biến

đó, mà không cần phải thực hiện các lệnh xuất nhập nêu trên, chẳng hạn như sau:
Phần khai báo:
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
22
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
#BYTE lcd = 0xf83 //sử dụng PORT D của PIC 18F4550
struct lcd_PIN_map //gán các biến vào các chân của PIC
{
BOOLEAN unused; // chân D0 = không sử dụng
BOOLEAN rw; // chân D1 gán vào biến rw (đọc ghi).
BOOLEAN rs; // chân D2 gán vào biến rs (reset).
BOOLEAN en; // chân D3 gán vào biến en (enable).
int data : 4; // từ D4 D7 gán làm biến dữ liệu data (4 BIT).
}
Phần sử dụng:
void lcd_send_BYTE ( BYTE address, BYTE n )
{
lcd.rs = 0; //chân D2 = 0
delay_ms(1);
lcd.rs = address; //chân D2= biến address.
delay_us(1);
lcd.rw = 0; //chân D1 = 0
delay_us(1);
lcd.en = 0; //chân D3 = 0
lcd.data = n; //chân D4 D7 = có giá trị bằng biến n
}
2.3. Lập trình giao tiếp với máy tính qua cổng RS232
Việc lập trình giao tiếp giữa vi điều khiển và máy vi tính là rất cần thiết. Khi
chúng ta muốn vi điều khiển khi đang hoạt động có thể truyền dữ liệu cho PC xử lý,

hoặc nhận các giá trị từ PC để xử lý và điều khiển. Chẳng hạn khi chúng ta dùng PC
để điều khiển động cơ, nhiệt độ, hay biến PC thành dụng cụ đo các đại lượng điện
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
23
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
2.3.1. Mạch điện giao tiếp
Trong PIC, DSPIC có hỗ trợ sẵn một MODUL để giao tiếp với PC thông qua
cổng RS232. Với các PIC thường sử dụng chân C6 là chân phát dữ liệu lên PC (Tx),
chân C7 là chân thu dữ liệu từ PC về PIC (Rx). Còn với DSPIC thì tuỳ từng loại,
đồng thời có loại DSPIC còn có sẵn 2 MODUL giao tiếp RS232.
Tuy nhiên do PIC và máy tính không có sự thống nhất về mức LOGIC, nên
chúng ta phải sử dụng thêm mạch điện giao tiếp bên ngoài.
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
24
P I C 1 8 F 4 5 5 0 - 1
2
3
4
5
6
7
3 3
3 4
3 5
3 6
3 7
3 8
3 9
4 0

1 5
1 6
1 7
1 8
2 3
2 4
2 5
2 6
1 9
2 0
2 1
2 2
2 7
2 8
2 9
3 0
1 3
1 4
3 2
1 1
3 1
1 2
1
8
9
1 0
R A 0 / A N 0
R A 1 / A N 1
R A 2 / A N 2 / V R E F - / C V R E F
R A 3 / A N 3 / V R E F +

R A 4 / T 0 C K I / C 1 O U T / R C V
R A 5 / A N 4 / S S / H L V D I N / C 2 O U T
R B 0 / A N 1 2 / I N T 0 / F L T 0 / S D I / S D A
R B 1 / A N 1 0 / I N T 1 / S C K / S C L
R B 2 / A N 8 / I N T 2 / V M O
R B 3 / A N 9 / C P P 2 / V P O
R B 4 / A N 1 1 / K B I 0 / C S S P P
R B 5 / K B I 1 / P G M
R B 6 / K B I 2 / P G C
R B 7 / K B I 3 / P G D
R C 0 / T 1 O S O / T 1 3 C K I
R C 1 / T 1 O S I / C C P 2 / U O E
R C 2 / C C P 1 / P 1 A
V u s b
R C 4 / D - / V M
R C 5 / D + / V P
R C 6 / T X / C K
R C 7 / R X / D T
R D 0 / S P P 0
R D 1 / S P P 1
R D 2 / S P P 2
R D 3 / S P P 3
R D 4 / S P P 4
R D 5 / S P P 5 / P 1 D
R D 6 / S P P 6 / P 1 C
R D 7 / S P P 7 / P 1 B
O S C 1 / C L K I
O S C 2 / C L K O / R A 6
V D D
V D D

V S S
V S S
M C L R / V P P
R E 0 / A N 5 / C K 1 S P P
R E 1 / A N 6 / C K 2 S P P
R E 2 / A N 7 / O E S P P
Tx
Rx
Rx
Tx
Hình 2-2. Các chân chức năng dùng cho giáo tiếp RS232
L O
U M A X
M A X 2 3 2
1
3
4
5
1 61 5
2
6
1 2
9
1 1
1 0
1 3
8
1 4
7
C 1 +

C 1 -
C 2 +
C 2 -
V C CG N D
V +
V -
R 1 O U T
R 2 O U T
T 1 I N
T 2 I N
R 1 I N
R 2 I N
T 1 O U T
T 2 O U T
C 2 C 3
+ 5 V c c P
P I C 1 8 F 4 5 5 0 - 1
2
3
4
5
6
7
3 3
3 4
3 5
3 6
3 7
3 8
3 9

4 0
1 5
1 6
1 7
1 8
2 3
2 4
2 5
2 6
1 9
2 0
2 1
2 2
2 7
2 8
2 9
3 0
1 3
1 4
3 2
1 1
3 1
1 2
1
8
9
1 0
R A 0 / A N 0
R A 1 / A N 1
R A 2 / A N 2 / V R E F - / C V R E F

R A 3 / A N 3 / V R E F +
R A 4 / T 0 C K I / C 1 O U T / R C V
R A 5 / A N 4 / S S / H L V D I N / C 2 O U T
R B 0 / A N 1 2 / I N T 0 / F L T 0 / S D I / S D A
R B 1 / A N 1 0 / I N T 1 / S C K / S C L
R B 2 / A N 8 / I N T 2 / V M O
R B 3 / A N 9 / C P P 2 / V P O
R B 4 / A N 1 1 / K B I 0 / C S S P P
R B 5 / K B I 1 / P G M
R B 6 / K B I 2 / P G C
R B 7 / K B I 3 / P G D
R C 0 / T 1 O S O / T 1 3 C K I
R C 1 / T 1 O S I / C C P 2 / U O E
R C 2 / C C P 1 / P 1 A
V u s b
R C 4 / D - / V M
R C 5 / D + / V P
R C 6 / T X / C K
R C 7 / R X / D T
R D 0 / S P P 0
R D 1 / S P P 1
R D 2 / S P P 2
R D 3 / S P P 3
R D 4 / S P P 4
R D 5 / S P P 5 / P 1 D
R D 6 / S P P 6 / P 1 C
R D 7 / S P P 7 / P 1 B
O S C 1 / C L K I
O S C 2 / C L K O / R A 6
V D D

V D D
V S S
V S S
M C L R / V P P
R E 0 / A N 5 / C K 1 S P P
R E 1 / A N 6 / C K 2 S P P
R E 2 / A N 7 / O E S P P
C 1
C 4
1
2
3
Hình 2-3. Mạch điện giao tiếp PIC với PC qua RS232
Luận văn thạc sỹ kỹ thuật Hướng dẫn KH: PGS . TS: Đỗ Xuân
Tiến
Trong đó các tụ C1, C2, C3, C4 dùng để phóng nạp điện để tạo ra mức điện
áp LOGIC cho cổng RS232 của PC. Với cổng COM của PC sử dụng 3 chân, trong
đó: Chân 3 là chân phát dữ liệu tới PIC, chân 2 là chân thu dữ liệu từ PIC về PC,
chân 5 là chân GND.
Để sử dụng được giao tiếp RS232 của PIC trong phần đầu của chương trình
chúng ta phải khai báo tiền xử lý:
#use rs232 (baud=9600,xmit=PIN_C6,rcv=PIN_C7)
Trong đó: BAUD là tốc độ truyền thông, thông thường 110, 300, 600, 1200,
4800, 9600, 14400, 19200, 28800, 38400 XMIT xác định chân của PIC dùng để
là chân phát dữ liệu. RCV xác định chân của PIC dùng để thu dữ liệu.
2.3.2. Các hàm và thủ tục phục vụ cho truyền thông qua cổng COM
+ Printf(string, values ):
- Trong đó: STRING là chuỗi ký tự (kết thúc bằng ký tự Null).
VALUES là danh sách các biến, cách nhau một dấu phẩy.
- Chức năng: Gửi chuỗi string tới cổng COM của PC.

Thông thường nếu dữ liệu cần truyền là một biến, thì chúng ta phải khai báo
định dạng (FORMAT ) của dữ liệu cần truyền trước sau đó mới đưa dữ liệu vào. Ví
dụ:
int8 k;
k=8;
Printf("%U",k);
- Các định dạng có thể là: %S = chuỗi ký tự, %C = 1 ký tự, %D = biến 8 BIT
có dấu, %U = biến 8 BIT không dấu.
- Ngoài ra một số ngôn ngữ lập trình phần mềm trên máy tính, chỉ cho phép
nhận dữ liệu từ cổng COM với định dạng chuỗi ký tự (Ví dụ ngôn ngữ VISUAL
BASIC). Do vậy ở trong PIC, các dữ liệu cần truyền lên PC phải chuyển thành dạng
chuỗi sau đó mới được gửi lên PC.
+ Getc():
Học viên: Hoàng Việt Sơn – K12 KT ĐT – ĐH Kỹ thuật công nghiệp
25

×