Professional Documents
Culture Documents
MCR Car PDF
MCR Car PDF
Hình 1 - 2: Sơ đồ khối kết nối các mạch trên TDC MCR ................................................. 1
Hình 1 - 10: Bảng trạng thái tín hiệu điều khiển 1 kênh DC Motor .................................. 5
Hình 1 - 12: Sơ đồ nguyên lý board vi điều khiển PIC16F887 cho xe MCR. ................... 7
Hình 2- 12: Tín hiệu rung nhiễu khi nhấn nút ................................................................ 13
Hình 3- 9: Sensor báo hiệu lệch nhỏ về phía bên trái so với vị trí trung tâm ................. 21
Hình 3- 10: Sensor báo hiệu lệch về phía bên trái so với vị trí trung tâm ...................... 22
Hình 3- 12: Các bước qua vị trí line cắt ngang .............................................................. 23
Hình 3- 14: Các bước qua vị trí nửa line cắt ngang ....................................................... 24
Hình 3- 15: Vị trí queo trái – xe vượt qua đường đua .................................................... 25
Hình 3- 16: Vị trí xác định line cắt ngan, xe bị lệch ...................................................... 26
Hình 3- 20: Vị trí chuyển làn xe tiếp tục đi về phía trước ............................................... 28
Hình 3- 21: Các trạng thái sensor trước khi chuyển làn ................................................ 28
Hình 3- 22: Chạy theo line biên của đường đua ............................................................ 29
Hình 3- 23: Trạng thái quẹo bám line trung tâm và line biên ......................................... 29
Hình 3- 24: Trạng thái sensor thay đổi chính xác .......................................................... 30
Hình 3- 25: Trạng thái sensor thay đổi không chính xác ............................................... 30
Hình 3- 26: Thay đổi trạng thái 0x83, 0x81, 0xC1 ......................................................... 30
Hình 3- 27: Các trạng thái chuyển line biên về line trung tâm ....................................... 31
Hình 3- 28: Xe chuyển làn sau đó vượt khỏi đường đua ............................................... 31
Hình 3- 29: Trạng thái chuyển làn đúng và không đúng ................................................ 32
Hình 4. 4: Chấp nhận các điều khoản khi sử dụng phần mềm.............................................. 34
Hình 4. 12: Tiếp tục cài đặt phần mềm hỗ trợ HI – TECH C ................................................. 37
Hình 4. 14: Lựa chọn thư mục cài đặt HI – TECH C ............................................................ 38
Hình 4. 17: Hoàn thành quá trình cài đặt HI-TECH C .......................................................... 39
Hình 4. 18: Hoàn thành quá trình cài đặt MPLAB ................................................................ 39
Hình 6. 7: Nối mạch nạp với board vi điều khiển pic16f887 .......................................... 61
Mạch dò đường
DC Motor Bus
RC Servo
Mạch xử lý sensor
Xe TDC MCR bao gồm board cảm biến dò đường, board xử lý cảm biến, board MCU
PIC16F887, board công suất 2 DC Motor L298 kết hợp với nhau để điều khiển sự di
chuyển của xe, tức là điều khiển hệ thống động cơ trái, phải và động cơ rc servo.
Mạch dò
Led Buttons Động Động
đường
Buzzer DIPSW4 cơ trái cơ phải
RC
Mạch xử VĐK PIC 16F887 Mạch công suất Servo
lý sensor
1
1.2. Board cảm biến dò đƣờng:
a. Hình dáng:
2
1.3. Board xử lý sensor:
a. Hình dáng:
3
là điện áp V-, V-<V+ nên ngõ ra OUT1 của opam =1. Qua cổng đệm không đảo
74HC245 thì T1=5V làm led D10 sáng, tín hiệu T1 này được đưa đến board MCU để
xử lý.
1.4. Board công suất 2 DC Motor L298:
a. Hình dáng:
b. Sơ đồ nguyên lý:
4
Hình 1 - 9: Nguyên lý board công suất 2 DC Motor L298
Hình 1 - 10: Bảng trạng thái tín hiệu điều khiển 1 kênh DC Motor
Trong bảng trên ta thấy: để Motor có thể quay thuận, quay ngược và thay đổi tốc độ ta
cần 2 kênh điều chế xung PWM, điều này lại hạn chế đối với vi điều khiển hỗ trợ ít
kênh PWM. Để giải quyết điều này thì khối logic đã đảm nhiệm, với ngõ vào PWM và
DIR ta dễ dàng điều khiển DC Motor, lúc này ta chỉ cần một kênh PWM để thay đổi tốc
độ và 1 chân tín hiệu số để đảo chiều quay.
5
1.5. Boar vi điều khiển PIC16F887:
a. Hình dáng:
b. Sơ đồ nguyên lý:
Khối nguồn vào Khối báo yếu nguồn:
6
Khối vi điều khiển: Các kết nối:
7
c. Nguyên lý hoạt động:
Khối nguồn: nguồn vào từ pin Lipo 11.1V, có led báo nguồn, zenner 12V hạn
quá áp. Ổn áp 5V dùng LM2576, dòng 3A, nguồn này sử dụng cấp cho board vi
điều khiển và board cảm biến.
Khối báo yếu pin: việc sử dụng pin Lipo cấp cho xe có nhiều ưu điểm nổi trội:
dung lượng cao 1500mA ( thời gian sử dụng xe lâu hơn), khối lượng nhẹ; nhưng
nó cũng có những hạn chế nhất định: giá thành cao, nếu sử dụng không đúng qui
cách ( sử dụng dưới áp giới hạn của pin) thì tuổi thọ của pin sẽ giảm đáng kể,
thậm chí sẽ bị hỏng. Do đó, mạch báo yếu pin trong quá trình sử dụng xe là hết
sức cần thiết. Ngưỡng điện áp so sánh yếu pin đã được chỉnh trước là 10VDC,
nếu điện áp pin dưới ngưỡng này thì đèn đỏ sẽ sáng lên và pin phải cần đem đi
sạc.
Khối vi điều khiển: MCU sử dụng là PIC 16F887, dao động xung clock 20Mhz.
Các cổng kết nối: ICSP dùng cho nạp chíp, SENSOR dùng cho kết nối với board
xử lý sensor, DC MOTOR dùng kết nối board công suất.
Các chức năng phụ: BUTA, BUTB, BUTC sử dụng cho các chức năng như
START, MODE….; còi BUZZER dùng cho gỡ rối chương trình; LEDA, LEDB là
các user led dùng chung với DIPSW4 để hiển thị các trạng thái test xe; DIPSW4
sử dụng mục đích test các chức năng trên xe.
8
CHƢƠNG 2: ĐIỀU KHIỂN MODULE CỦA XE TDC MCR
Led (diốt phát quang) thường dùng trên các mạch điện tử để hiển thị thông tin, với 2
trạng thái tắt/sáng. Led thường được mắc nối tiếp với một điện trở (có giá trị khoảng từ
100Ω đến 2kΩ) để hạn dòng (tránh làm hỏng led), thành một đoaạn mạch AB nối tiếp.
9
Khi đó để làm led sáng, ta đặt điện thế +5V vào đầu A và điện áp 0V vào đầu B còn lại.
Xem hình 2-4
Để điều khiển led bằng VĐK ta cũng áp dụng tương tự. Đầu A ta nối vào 1 chân vi điều
khiển (LEDA nối vào chân RC5, LEDB nối vào chân RD7), đầu B ta nối GND (0V). Khi
RC5 = 1 (5V) thì LEDA sáng, và khi RC5 = 0 (0V) LEDA tắt (tương tự LEDB).
10
Khối Loa beep tắt/mở bằng một khóa điện tử và được điều khiển bởi chân RD6 của
VĐK. Khi RD6 = 1 (+5V): OFF, loa không phát ra tiếng kêu; khi RD6 = 0 (0V): ON, loa
phát ra tiếng kêu.
b. Sơ đồ nguyên lý dipswitch
Dipsw gồm nhiều công tắc hoạt động độc lập nhưng được gắn chung với nhau thành
một thanh. Có nhiều loại Dipsw, khác biệt lớn nhất giữa chúng là số lượng công tắc.
Trong mạch VĐK dùng Dipsw-4, tức là Dipsw có 4 công tắc.
Về nguyên lý thì rất đơn giản, khi gạt một công tắc lên ON thì hai chân tương ứng với
hai phía công tắc đó sẽ nối với nhau.
11
SW0 nối với chân RB1 của VĐK
Khi các SW ở vị trí OFF các chân RB1, RB2, RB4, RB5 = 1(+5V), các SW tương ứng ở
vị trí ON thì các chân tương ứng của VĐK = 0(0V). SW0 ở vị trí ON thì RB1 = 0(0V).
Mỗi nút nhấn có hai chân, nguyên lý hoạt động rất đơn giản, khi không nhấn nút (OFF)
thì hai chân của nút không nối nhau, và ngược lại khi nhấn nút (ON), hai chân của nút
sẽ nối nhau.
Trên mạch VĐK có 3 nút nhấn được kết nối theo sơ đồ, BUTA nối với chân RB3, BUTB
nối với chân RB6, BUTC nối với chân RB7 của VĐK. Đồng thời chân của các nút nhấn
cũng được nối với chân INT (chân tạo sự kiện ngắt) của VĐK (chân này dùng để báo
12
cho VĐK biết có nút nhấn vừa mới nhấn, tạm dừng các chương trình đang chạy để
xem rằng nút nào được nhấn từ đó xử lý. Sau quá trình xử lý chương trình tiếp tục
chạy tại vị trí bị dừng trước đó).
Khi không nhấn (OFF) các chân nối với nút nhấn của VĐK sẽ nhận được mức 1 (+5V),
và khi nút nhấn được nhấn (ON) ta nhận được mức 0 (0V).
Có hai giải pháp thường được đưa ra để lựa chọn là giải pháp phần cứng (thực hiện
trong giai đoạn thiết kế mạch), và giải pháp phần mềm (lúc lập trình). Ở đây hướng dẫn
các bạn một giải thuật chống rung nút nhấn bằng phần mềm
RC Servo là hệ thống gồm động cơ DC, hộp số, và vi mạch điều khiển. Tùy theo tín
hiệu điều khiển mà nó nhận được, RC Servo sẽ quay trục đến một góc xác định trong
khoảng từ 00 đến 1800.
13
a. Hình thực tế RC servor
Đen GND
Đỏ +6V
Trắng PWM
Điều khiển RC Servo chính là điều khiển tín hiệu vào dây PWM để RC Servo quay theo
góc mà mình mong muốn. Tín hiệu PWM cho RC Servo có chu kỳ 16ms, độ rộng xung
từ 0,7ms đến 2.3ms, mô tả theo hình bên dưới:
Động cơ điện một chiều (hay động cơ DC) là một động cơ hoạt động với dòng điện một
chiều
14
a. Hình động cơ DC
Khi ta cấp điện thế đương (+) vào một cực của động cơ và cấp điện thế âm (-) vào cực
còn lại thì động cơ sẽ quay theo một chiều cố định. Và khi ta cấp điện thế ngược lại,
đảo chiều dương âm thì động cơ sẽ quay theo chiều ngược lại.
Hình 2- 16: Điều khiển chiều quay động cơ điện một chiều
Để điều khiển tốc động động cơ điện một chiều ta dùng phương pháp điều xung
(PWM). Như trên ta đã biết, khi được cấp điện thì động cơ quay, và khi không cấp điện
nữa thì động cơ ngừng hoạt động. Trong một khoảng thời gian rất ngắn 128us (gọi là
chu kỳ điều xung T), và chia khoảng thời gian này thành 2 phần, ta sẽ cấp điện cho một
động cơ một phần thời gian đầu, và ngừng cấp điện ở phần thời gian sau. Lặp lại chu
kỳ đó liên tục, như thế động cơ sẽ liên tục ở trạng thái quay-ngừng-quay-ngừng-quay…
Vì chu kỳ điều xung là rất nhỏ nên ta sẽ thấy động cơ quay liên tục. Tốc độ của động
cơ phụ thuộc vào tỷ lệ thời gian động cơ được cấp điện trong một chu kỳ.
15
Hình 2- 17: PWM điều khiển tốc độ động cơ
b. Tín hiệu
8 Sensor được nối với board xử lý. Tín hiệu từ board xử lý (T1-T8) được đưa về VĐK.
Ví dụ về trạng thái của sensor tương ứng với màu đen, trắng trên đường đua
1 0 0 0 0 1 1 0
16
CHƢƠNG 3: XÂY DỰNG GIẢI THUẬT ĐIỀU KHIỂN
3.1. Cấu trúc chƣơng trình
Xử lý các
đoạn đường 4
2 thẳng và
đường cong
(I)
1 3
Xử lý đoạn 6 Xử lý đoạn
đường chuyển đường chuyển
làn bên trái làn bên phải
(II) (III)
5
7 8
Xử lý các
đoạn đường
cua vuông 900
(IV)
Bước chuyển 2 (II I): khi đã đi qua được đoạn đường chuyển làn trái.
17
Hình 3- 3: Chạy qua đoạn chuyển làn trái
Bước chuyển 3 (I III): khi thấy được nửa line bên phải.
Bước chuyển 4 (III I): khi chạy qua đoạn chuyển làn phải
18
Bước chuyển 5 (I IV), bước chuyển 7 (II IV), bước chuyển 8 (III IV): ngay
khi thấy được một line.
Bước chuyển 6 (IV I): khi chạy xong đoạn đường cua 900.
3.2. Giải thuật xử lý khi qua các đoạn đƣờng thẳng và cong.
Các trạng thái sensor có thể gặp thể hiện tương đối độ lệch hướng của xe với phương
đường đua:
Ta dựa vào trạng thái sensor để biết được độ lệch hướng chạy của xe so với phương
của đường đua, ứng với một trạng thái sensor ta chọn một góc bẻ hợp lý sao cho xe có
xu hướng di chuyển về phía chính giữa đường đua, với độ lệch hướng càng lớn thì ta
chọn góc bẻ lái càng lớn.
19
Giá trị Góc Động Động
Trạng thái sensor của sensor Hexadecimal quay cơ trái cơ phải
RC PWM PWM
ervo
1 00000000 0x00 0 100 100
3 00000110 0x06 15 80 67
5 00000011 0x03 30 30 19
Bảng 3- 1: Các trạng thái led gặp trên đường đua và góc cua tương ứng
20
Đặc tính và quá trình Các hàm cần phải xây
Trạng thái sensor
xử lý dựng để kiểm tra trạng
thái
Bảng 3- 2: Các trạng thái led gặp trên đường đua báo hiệu chuyển làn, cua 900
Động cơ trái và phải chạy với công suất 100%, RC servo góc 00
Ở trạng thái này giá trị của sensor là 0x04. Vị trí của xe lệch về phía bên trái so với
trung tâm tương đối ít nên lúc này ta chỉnh RC servo về phía bên phải 1 góc 7,50, vận
tốc của 2 động cơ DC vẫn 100%
Hình 3- 9: Sensor báo hiệu lệch nhỏ về phía bên trái so với vị trí trung tâm
21
Ở trạng thái này giá trị của sensor là 0x06. Vị trí của xe lệch về phía bên trái so với
trung tâm tương đối nên lúc này ta chỉnh RC servo về phía bên phải 1 góc 140, vận tốc
động cơ trái bằng 80% và vận tốc động cơ phải bằng 69%
Hình 3- 10: Sensor báo hiệu lệch về phía bên trái so với vị trí trung tâm
Như vậy khi xe lệch càng nhiều về phía bên trái của trung tâm thì RC servo được điều
chỉnh về phía bên phải với 1 góc càng lớn, vận tốc của động cơ bên trái và bên phải
giảm dần, tuy nhiên do lệch về phía bên trái nên vận tốc của động cơ bên trái lớn hơn
bên phải.
Tương tự ngược lại với xe lệch về phía bên phải so với trung tâm.
22
[1] : Hàm check_crosline phát hiện sự hiện diện của line cắt ngang. Báo hiệu rằng còn
500mm đến 1000mm nữa là đến đoạn đường cua 900 (bên trái hoặc bên phải). Lúc này
ta phải giảm tốc độ của xe để đảm bảo điều hướng thành công. Tin hiệu sensor lúc này
không được tham chiếu cho đến vị trí [2] để ngăn chặn phát hiện sai lầm tại line cắt
ngang thứ hai.
[2] Xe tiến đến vị trí này một cách từ từ, xe chạy thẳng tới trước theo đường trung tâm.
[3] khi mà vị trí cua 900 được phát hiện, xe tiến hành quay theo hướng (trái hoặc phải).
[4] khi đường trung tâm được phát hiện, xe trở lại chương trình đi đường thẳng và
đường cong.
Khi mà line cắt ngang được phát hiện (thông qua hàm check_crosline). Đầu tiên xe sẽ
di chuyển qua đoạn line cắt ngang này, sau đó mới kiểm tra nửa line cắt ngang báo
hiệu cua phải hay trái. Như hình bên dưới
[4] chạy thẳng, chạy chậm để xe bám vị trí đường trung tâm.
23
Hình 3- 13: Các bước chuyển làn bên phải
[1] Hàm check_rightline phát hiện nửa line cắt ngang bên phải. Xe phải đổi làn đường
bên phải sau 500mm đến 1200mm, do đó xe phải thắng lại. Sensor bỏ qua vị trí [2] để
ngăn chặn phát hiện sai lầm tại nửa line cắt ngang bên phải thứ hai.
[3] khi vị trí quay được phát hiện, xe quay theo hướng quay (trái, phải)
[4] khi line trung tâm được nhận diện, xe thực hiện chạy theo chương trình đi thẳng và
đường cong.
Khi phát hiện nửa line bên phải. Đầu tiên xe đi qua các line cắt ngang. Các đặc tính
theo dõi đường line từ vị trí line thứ hai được thể hiện trong hình sau đây:
Hình 3- 14: Các bước qua vị trí nửa line cắt ngang
24
[1] Line đầu tiên
[4] chạy thẳng, chạy chậm để xe bám vị trí đường trung tâm.
Mô tả vấn đề.
Sau khi gặp tín hiệu quẹo 900 xe không quẹo mà tiếp tục đi thẳng rời khỏi đường đua.
Thu thập và phân tích dữ liệu cho thấy tại thời điểm phát hiện line cắt ngang, trạng thái
sensor là 0x1F, không phải là giá trị dự đoán 0xE7.
25
Hình 3- 16: Vị trí xác định line cắt ngang, xe bị lệch
Trong quá trình phát hiện nửa line, ta cần sử dụng cả tám bộ cảm biến.
Vì dữ liệu sensor nhận về tương ứng với dữ liệu phát hiện nửa line nên tất nhiên sẽ
xảy ra sự cố.
Giải quyết
Sử dụng lập trình để giải quyết tình huống này không thể thực hiện được. Một cách
tương đối khi sensor phát hiện nửa line, không xử lý sự kiện ngay lập tức mà đợi 1 thời
gian ngắn. Sau đó sensor nhận line có thể rõ ràng hơn.
Mô tả vấn đề
26
Phân tích nguyên nhân
Thu thập và phân tích dữ liệu đang chạy cho thấy tại thời điểm chuẩn bị quay bên phải,
trạng thái cảm biến là 0x0F, 0x3F, 0x7F, không giống như giá trị dự đoán 0x1F.
Mặc dù đã gặp phải vị trí cần phải quay bên phải, nhưng dữ liệu cảm biến không phù
hợp với trạng thái cảm biến dự kiến cho quay phải và xe tiến thẳng ra đường đua.
Giải quyết.
Trong chương trình thay vì khi phát hiện quay bên phải là 0x1F. Trong thực thế gặp
phải các trạng thái khác như 0x0F, 0x3F hoặc 0x7F. Vì vậy, những trạng thái cảm biến
nên được bổ sung vào chương trình khi phát hiện quay bên phải.
Mô tả vấn đề
Tại vị trí chuyển làn thay vì xe chuyển làn, xe lại tiếp tục đi thẳng về phía trước.
27
Hình 3- 20: Vị trí chuyển làn xe tiếp tục đi về phía trước
Thu thập và phân tích các dữ liệu của xe đang chạy cho thấy tại thời điểm phát hiện
nửa line, trạng thái cảm biến là 0x0F, 0x3F, 0x7F không giống như trạng thái dự đoán
là 0x1F.
Hình 3- 21: Các trạng thái sensor trước khi chuyển làn
Giải quyết.
Trong chương trình thay vì khi phát hiện chuyển làn bên phải là 0x1F. Trong thực thế
gặp phải các trạng thái khác như 0x0F, 0x3F hoặc 0x7F. Vì vậy, những trạng thái cảm
biến nên được bổ sung vào chương trình khi phát hiện chuyển làn phải.
28
d. Xe chạy theo line biên của đƣờng đua.
Mô tả vấn đề
Khi vị trí quay bên trái được phát hiện, xe quay bên trái. Sau khi di chuyển trong một
thời gian với 1 vòng cung hơi rộng, xe bắt đầu theo dõi line biên của đường đua và di
chuyển theo line này.
Trạng thái quẹo bám line trung tâm Trạng thái quẹo bám line biên
Hình 3- 23: Trạng thái quẹo bám line trung tâm và line biên
Xem lại những thay đổi trạng thái của cảm biến khi đường trung tâm được phát hiện
chính xác. Trạng thái sensor thay đổi từ 0x00 đến 0xC0 đến 0x60, cuối cùng quay về
chạy bình thường.
29
Hình 3- 24: Trạng thái sensor thay đổi chính xác
Hình 3- 25: Trạng thái sensor thay đổi không chính xác
Giải quyết.
So sánh 2 chuỗi trạng thái cho thấy sự cố này xảy ra khi một trạng thái sensor 0x07
tiếp theo là 0x60. Vì vậy, làm thế nào để sửa đổi mã chương trình để khi gặp phải trạng
thái sensor 0x07, xe tiếp tục chạy cho đến khi thay đổi trạng thái 0x83, 0x81,0xC1
Chúng ta thử mô phỏng một tình huống. Khi trạng thái sensor là 0x07, xe tiếp tục chạy
cho đến khi thay đổi trạng thái 0x83, 0x81, hoặc 0xC1. Điều này có nghĩa là xe tiếp tục
chạy ngay cả khi xảy ra trạng thái cảm biến là 0x60. Trước đây, kiểm soát sẽ trở lại
chương trình đi thẳng tại thời điểm này xe không tiếp tục dò line. Bây giờ tiếp tục chạy
cho đến khi trạng thái sensor 0x80, sau đó chương trình kiểm tra trạng thái 0x60. Khi
mà trạng thái 0x60 thay đổi, trạng thái này đánh giá là trở về đường trung tâm, chương
trình quay về chương trình đi thẳng.
30
Hình 3- 27: Các trạng thái chuyển line biên về line trung tâm
Mô tả vấn đề
Khi xe chuyển làn, thay vì bắt đƣờng đƣợc đƣờng line trung tâm thì xe lại chạy
vƣợt qua và chạy ra khỏi đƣờng đua.
31
Phân tích nguyên nhân
Phân tích trạng thái sensor cho thấy một chuỗi giá trị 0x38 đến 0x70 đến 0xE0 khi đó
đường trung tâm mới được phát hiện.
Theo phân tích, sự thay đổi làn đường bên phải được xác định khi đã hoàn thành trạng
thái cảm biến 0x3C. Tuy nhiên, tùy thuộc vào góc độ mà tại đó các xe đang di chuyển,
trạng thái của sensor 0x3C có thể không bao giờ xảy ra.
Giải quyết.
Trạng thái sensor 0x3C cho biết phát hiện đường trung tâm mới, thêm vào một số trạng
thái sensor được xác định trong các kết quả phân tích. Ngoài ra, một số sửa đổi khác,
thay đổi trạng thái phát hiện sensor với một giá trị hoàn toàn khác nhau, hoặc chuyển
đổi góc lái RC servo khi đường trung tâm được phát hiện và tiến hành xử lý. Hãy cố
thử một số phương pháp tiếp cận khác nhau và xác định phương pháp nào cho phép
xe hoạt động nhanh hơn và độ ổn định khi đổi làn đường.
32
CHƢƠNG 4: CÀI ĐẶT CÔNG CỤ LẬP TRÌNH
4.1. Cài đặt phần mềm MPLAB
Bước 1: Download chương trình MPLAB IDE
- Download theo đường link http://www.mediafire.com/?iu6tgcsgsdbdlqv
- Giải nén file MPLAB_IDE_V8_56.zip vừa download về máy tính.
Bước 2: Tiến hành cài đặt
- Mở Folder vừa giải nén bên trên
- Click vào file setup để tiến hành cài đặt
- Nhấn next
33
Hình 4. 3: Đồng ý tiếp tục cài đặt phần mềm
Hình 4. 4: Chấp nhận các điều khoản khi sử dụng phần mềm
34
- Lựa chọn thư mục chứa phần mềm. Nhấn next
35
- Nhấn next
- Chọn Yes (chấp nhận cài HI – TECH C, hỗ trợ lập trình C cho chip pic 16)
36
- Nhấn next
Hình 4. 12: Tiếp tục cài đặt phần mềm hổ trợ HI – TECH C
37
Hình 4. 14: Lựa chọn thư mục cài đặt HI – TECH C
38
- Quá trình cài đặt HI-TECH C hoàn thành. Nhấn Finish
39
4.2. Mở dự án mẫu
Bước 1: Download code mẫu MCR_Ver2.zip
- Chọn vào đường dẫn
- http://www.mediafire.com/?wfn1oc9oo7qfu9o
- Giải nén folder MCR_Ver2.zip
Bước 2: Mở dự án mẫu
- Mở folder MCR_Ver2.zip
40
Bước 3: Biên dịch dự án mẫu
- Từ đây ta có thể chỉnh sửa code theo yêu cầu của cuộc thi.
41
CHƢƠNG 5: CHƢƠNG TRÌNH MẪU MCR
5.1. Mã chƣơng trình
Sau đây là đoạn mã chương trình điều khiển xe TCD MCR (điều khiển cơ bản) sử dụng
vi điều khiển pic 16f887. Code viết trên môi trường MPLAB kết hợp HI – TECH C.
1: /*======================================*/
2: /* Include */
3: /*======================================*/
4: #include<htc.h>
5: __CONFIG (INTIO & WDTDIS & PWRTEN & MCLREN & UNPROTECT & DUNPROTECT& BORDIS & IESODIS & FCMDIS & LVPDIS);
6: #define _XTAL_FREQ 20000000
7: /*======================================*/
8: /* Symbol definition */
9: /*======================================*/
10: /* Hardware number : Khai bao phan cung */
11: #define LEDA RC5
12: #define LEDB RD7
13: #define DIR_L RC3
14: #define DIR_R RC4
15: #define BUTA RB3
16: #define BUTB RB6
17: #define BUTC RB7
18: #define FORWARD 0
19: #define REVERSE 1
20: #define CENTER 17
21: ///////////////////////////////////////////////////
22: /* Masked value settings: x: masked (disabled), o: not masked (enabled) */
23: #define MASK3_3 0xe7
24: #define MASK4_4 0xff
25: /* Test values : gia tri sw de test xe */
26: #define LED_Test 0x00 //0000
27: #define BUT_Test 0x20 //0001
28: #define Servo_Test 0x10 //0010
29: #define MRight_FW 0x04 //0100
30: #define MRight_RE 0x24 //0101
31: #define MLeft_FW 0x14 //0110
32: #define MLeft_RE 0x34 //0111
37: #define LP2 0b00000100 //lech phai so voi duong trung tam
38: #define LP3 0b00000110
39: #define LP4 0b00000010
42
40: #define LP5 0b00000011
41: #define LP6 0b10000000
42: #define LP7 0b11100000 //gia tri dac biet
43: #define LT2 0b00100000 //lech trai so voi duong trung tam
44: #define LT3 0b01100000
45: #define LT4 0b01000000
46: #define LT5 0b11000000
47: #define LT6 0b00000001
48: #define LT7 0b00000111 //gia tri dac biet
43
87: PS0=0;
88: TMR0=245;
89: T0IE=1;
90: T0IF=0;
91: GIE=1;
92: //Khoi tao PWM
93: PR2=255;
94: T2CKPS1=T2CKPS0=0;
95: TOUTPS3=TOUTPS2=TOUTPS1=TOUTPS0=0;
96: TRISC2=1;
97: CCP1CON=0b00001100;
98: CCPR1L=0;
99: TMR1IF=0;
100: TRISC1=1;
101: CCP2CON=0b00001100;
102: CCPR2L=0;
103: TMR2IF=0;
104: TMR2ON=1;
105: TRISC2=0;
106: TRISC1=0;
107: TRISC5=0;
108: TRISD7=0;
109:
110: //Khoi tao cac gia tri ban dau
111: TURN=CENTER; //DC servo quay ve vi tri trung tam (0 do)
112: DIR_L = FORWARD; //Dong co trai cho phep chay toi
113: DIR_R = FORWARD; //Dong co phai cho phep chay toi
114: LEDA = 0; //Den led A tat
115: LEDB = 0; //Den led B tat
116: Left_Wheel(0); // Dong co DC ben trai dung hoat dong
117: Right_Wheel(0); // Dong co DC ben phai dung hoat dong
118: /*================================================================================*/
119: while(1)
120: {
121: if( BUTA == 0) // Nhan nut A khoi dong xe
123: {
124: __delay_ms(20);
125: i=1000;
126: while (i>0)
127: {
128: if (BUTA==0) i=1000;
129: i--;
130: }
131: RUN();
132: }
133:
134: if( BUTB == 0) // Nhan nut B kiem tra cac bo phan xe
135: {
136: __delay_ms(20);
44
137: i=1000;
138: while (i>0)
139: {
140: if (BUTA==0) i=1000;
141: i--;
142: }
143: while (1)
144: {
145: Test_pro();
146: }
147: }
148: }
149: }
150: /*=========================================================
151: CAC CHUONG TRINH CON
152: =========================================================*/
153: /*======================================*/
154: /* DC control
155: /* Van toc motor trai va phai : 0-255 */
156: /*======================================*/
157: void Right_Wheel(unsigned Vel)
158: {
159: if(CCPR1L!=Vel)
160: {
161: TMR2ON=0;
162: TRISC1=1;
163: CCPR1L=Vel;
164: TMR2ON=1;
165: TRISC1=0;
166: }
167: }
168: void Left_Wheel(unsigned Vel)
169: {
170: if(CCPR2L!=Vel)
171: {
172: TMR2ON=0;
173: TRISC2=1;
174: CCPR2L=Vel;
175: TMR2ON=1;
176: TRISC2=0;
177: }
178: }
179: /*==============================================*/
180: /* Dieu khien RC Servo */
181: /*===============================================*/
182: void interrupt isr()
183: {
184: if(T0IE&T0IF)
185: {
45
186: n++;
187: if(n==380)
188: {
189: n=0;
190: }
191: if(n<TURN)RC0=1;
192: else RC0=0;
193: TMR0=245;
194: T0IF=0;
195: }
196: }
197: /*====================================================*/
198: /* Read_Inputs : chuong trinh doc sensors va switchs */
199: /*====================================================*/
200: unsigned char Read_Sensor()
201: {
202: unsigned char temp = 0;
203: temp = (PORTA&0X0F)|((PORTE<<5));
204: if(RA5)temp|=0x10;
205: // temp &=mask;
206: return temp;
207: }
208: /*====================================================*/
209: unsigned char Read_Switch(void)
230: {
231: unsigned char sw;
232: sw = PORTB; /* DIP switch read */
233: sw &= 0x36; /*CONVERTED HIGH BIT TO LOW BIT*/
234: return sw;
235: }
236: /*====================================================*/
237: /*Test Program : chuong trinh dung de test xe */
238: void Test_pro()
239: {
240: unsigned char var_sensor = Read_Sensor(MASK3_3);
241: switch (Read_Switch())
242: {
243: case LED_Test:
245: TURN = 0;
246: LEDA = 1;
247: LEDB=0;
248: __delay_ms(50);
249: LEDA = 0;
250: LEDB=1;
251: __delay_ms(50);
252: break;
253: case BUT_Test:
254: if((BUTA==1)||(BUTB==1)||(BUTC==1))
255: {
46
256: LEDA=0;
257: LEDB=0;
258: }
259: if (BUTA==0) LEDA=1;
260: if (BUTB==0) LEDB=1;
261: if (BUTC==0)
262: {
263: LEDA=1;
264: LEDB=1;
265: }
266: break;
267: case Servo_Test:
268: for (TURN = (CENTER-4); TURN < (CENTER+4); TURN ++)
269: {
270: __delay_ms(20);
271: }
272: for (TURN = (CENTER+4); TURN > (CENTER-4); TURN --)
273: {
274: __delay_ms(20);
275: }
276: break;
277: case MRight_FW:
278: Right_Wheel(250);
279: DIR_R = FORWARD;
280: __delay_ms(100);
281: Right_Wheel(0);
282: __delay_ms(30);
283: break;
284: case MRight_RE:
285: Right_Wheel(250);
286: DIR_R = REVERSE;
287: __delay_ms(100);
288: Right_Wheel(0);
289: __delay_ms(30);
290: break;
291: case MLeft_FW:
292: Left_Wheel(250);
293: DIR_L = FORWARD;
294: __delay_ms(100);
295: Left_Wheel(0);
296: __delay_ms(30);
297: break;
298: case MLeft_RE:
299: Left_Wheel(250);
300: DIR_L = REVERSE;
301: __delay_ms(100);
302: Left_Wheel(0);
303: __delay_ms(30);
304: break;
47
305: }
306: }
307: /*==============================================
308: CHUONG TRINH XE BAT DAU DO LINE
309: ================================================*/
310: void RUN()
311: {
312: while(1)
313: {
314: switch (pattern)
315: {
316: case 0: //Xe chay theo duong thang
317: if(Read_Sensor()==0)
318: {
319: pattern=1;
320: break;
321: }
322: //------------------------------------------------------------------------------------------------------------------------------------------
323: switch (Read_Sensor())
324: {
325: case ttam1: /* Center -> Straight */
326: TURN = CENTER;
327: Left_Wheel(230);
328: Right_Wheel(230);
329: break;
330: case ttam2: /* Center -> Straight */
331: TURN = CENTER;
332: Left_Wheel(230);
333: Right_Wheel(230);
334: break;
335: case ttam3: /* Center -> Straight */
336: TURN = CENTER;
337: Left_Wheel(230);
338: Right_Wheel(230);
339: break;
340:
341: /* RIGHT : xu ly xe lech phai*/
342: case LP2:
343: if (error == 0)
344: {
345: TURN = CENTER+1;
346: Left_Wheel(200);
347:
348: Right_Wheel(160);
349: }
350: if (error == 1)
351: {
352: error = 0;
353: TURN = CENTER-3;
48
354: }
355: break;
356: case LP3: /* Left inclined from the middle->Middle turn to the right */
357: if (TURN > CENTER)
358: {
359: TURN = CENTER+3;
360: Left_Wheel(190);
361: Right_Wheel(150);
362: }
363: if (TURN < CENTER)
364: {
365: TURN = CENTER-3;
366: Left_Wheel(150);
367: Right_Wheel(190);
368: }
369: break;
370: case LP4: /* Large inclined to the left->Large turn to the right */
371: if (TURN > CENTER)
372: {
373: TURN = CENTER+4;
374: Left_Wheel(180);
375: Right_Wheel(150);
376: }
377: if (TURN < CENTER)
378: {
379: TURN = CENTER-4;
380: Left_Wheel(150);
381: Right_Wheel(250);
382: }
383: break;
384: case LP5:
385: if (TURN > CENTER)
386: {
387: TURN = CENTER+3;
388: Left_Wheel(220);
389: Right_Wheel(170);
390: }
391: if (TURN < CENTER)
392: {
393: TURN = CENTER-3;
394: Left_Wheel(170);
395: Right_Wheel(220);
396: }
397: break;
398: case LP6:
399: if (TURN > CENTER)
390: {
391: TURN = CENTER+4;
392: Left_Wheel(210);
49
393: Right_Wheel(150);
394: }
395: if (TURN < CENTER)
396: {
397: TURN = CENTER-4;
398: Left_Wheel(150);
399: Right_Wheel(210);
400: }
401: break;
402: case LP7:
403: if (TURN > CENTER)
404: {
405: TURN = CENTER+4;
406: Left_Wheel(210);
407: Right_Wheel(150);
408: }
409: if (TURN < CENTER)
410:: {
411: TURN = CENTER-4;
412: Left_Wheel(150);
413: Right_Wheel(210);
414: }
415: break;
430: break;
431: case LT3: /* Left inclined from the middle->Middle turn to the right */
432: if (TURN > CENTER)
433: {
434: TURN = CENTER+3;
435: Left_Wheel(190);
436: Right_Wheel(150);
437: }
if (TURN < CENTER)
438: {
50
439: TURN = CENTER-3;
440: Left_Wheel(150);
441: Right_Wheel(190);
442: }
443: break;
444: case LT4: /* Large inclined to the left->Large turn to the right */
445: if (TURN > CENTER)
446: {
447: TURN = CENTER+4;
448: Left_Wheel(180);
449: Right_Wheel(150);
450: }
451: if (TURN < CENTER)
452: {
453: TURN = CENTER-4;
454: Left_Wheel(150);
455: Right_Wheel(250);
456: }
457: break;
458: case LT5:
469: if (TURN > CENTER)
460: {
461: TURN = CENTER+3;
462: Left_Wheel(220);
463: Right_Wheel(170);
464: }
465: if (TURN < CENTER)
466: {
467: TURN = CENTER-3;
468: Left_Wheel(170);
469: Right_Wheel(220);
470: }
471: break;
472: case LT6:
473: if (TURN > CENTER)
474: {
475: TURN = CENTER+4;
476: Left_Wheel(210);
477: Right_Wheel(150);
478: }
479: if (TURN < CENTER)
480: {
481: TURN = CENTER-4;
482: Left_Wheel(150);
483: Right_Wheel(210);
484: }
485: break;
486: case LT7:
487: if (TURN > CENTER)
51
488: {
489: TURN = CENTER+4;
480: Left_Wheel(210);
481: Right_Wheel(150);
482: }
483: if (TURN < CENTER)
484: {
485: TURN = CENTER-4;
486: Left_Wheel(150);
487: Right_Wheel(210);
488: }
489: break;
450: case Error:
451: error = 1;
452: if (TURN > CENTER)
453: {
454: TURN = CENTER+4;
455: Left_Wheel(220);
456: Right_Wheel(150);
457: }
458: if (TURN < CENTER)
459: {
460: TURN = CENTER-4;
461: Left_Wheel(150);
462: Right_Wheel(220);
463: }
464: break;
465: default:
466: if (TURN > CENTER)
467: {
468: TURN =CENTER+3;
469: Left_Wheel(210);
470: Right_Wheel(150);
471: }
472: if (TURN < CENTER)
473: {
474: TURN = CENTER-3 ;
475: Left_Wheel(150);
478: Right_Wheel(210);
479: }
480: break;
481: }
482: //-------------------------------------------------------------------------------------------------------------------------------
483: break;
484: case 1:
485: TURN=CENTER;
486: Left_Wheel(0);
487: Right_Wheel(0);
488: LEDB=1;
52
489: __delay_ms(20);
490: LEDB=0;
491: __delay_ms(20);
492: if ((Read_Sensor())!=0)
493: {
494: pattern=0;
495: error=0;
496: LEDB=0;
497: }
498: break;
499: default:
500: break;
501: }
502: }
503: }
504:
505:
53
Vel = 255 động cơ hoạt động với vận tốc tối đa. Kết hợp với biến DIR_L có thể
điều khiển động cơ chạy thuận, nghịch.
- Hàm Right_Wheel(unsigned Vel): hàm điều khiển tốc độ động cơ bên phải. Vel
có giá trị nằm trong khoảng 0…255. Giá trị Vel = 0 động cơ dừng hoạt động, giá
trị Vel = 255 động cơ hoạt động với vận tốc tối đa. Kết hợp với biến DIR_R có
thể điều khiển động cơ chạy thuận, nghịch.
- Hàm Test_pro(void): dùng để test các thành phần của động cơ
- Hàm RUN(void): hàm cho phép xe chạy theo line (đường thẳng và cong)
- Hàm Read_Sensor (): hàm này đưa về giá trị đọc được từ sensor..
- Hàm Read_Switch(void): hàm này đưa về giá trị của Switch (dùng trong hàm
Test_pro(void)) để test xe.
- Để điều khiển góc quay của RC Servo ta thay đổi giá trị TURN so với vị trí trung
tâm CENTER. (ví dụ: quay qua phải 1 góc 7,50 so với vị trí trung tâm: TURN =
CENTER + 1)
(3) Nút nhấn
Để xem nút nhấn có được nhấn hay không trong chương trình ta kiểm tra nút nhấn đó
có bằng 0. Nếu bằng 0 thì ta thực hiện chống dội cho nút nhấn rồi sau đó mới xử lý sự
kiện tiếp theo sau. (nếu không xử lý chống dội khi ta nhấn nút chương trình sẽ hiểu ta
nhấn nhiều lần, lúc này có thể làm cho hoạt động của chương trình không đúng với yêu
cầu đề ra).
54
142: }
143: while (1)
144: {
145: Test_pro();
146: }
147: }
Đoạn chương trình trên: nếu ta nhấn nút A thì chương trình thực hiện chống dội sau đó
cho phép hàm RUN() hoạt động. Nếu nhấn nút B thì chương trình thực hiện chống dội
sau đó cho phép hàm Test_pro() thực hiện.
(4) Test các thành phần của xe
Để test các thành phần của xe ta viết chương trình trong hàm Test_pro(). Chương
trình Switch sau đó so sánh tương ứng với các giá trị switch sẽ thực thi phần kiểm
tra bộ phận xe tương ứng.
55
260: if (BUTB==0) LEDB=1;
261: if (BUTC==0)
262: {
263: LEDA=1;
264: LEDB=1;
265: }
266: break;
Kiểm tra nút nhấn BUTA, B, C. Không nhấn các nút nhấn BUTA,B,C
thì LEDA, LEDB tắt.
Nhấn BUTA thì LEDA sáng.
Nhấn BUTB thì LEDB sáng.
Nhấn BUTC thì LEDA,B sáng.
Kiểm tra RC SERVO MOTOR. Servo sẽ lặp lại sau 1s theo trình tự
sau: “0độ -> phải 30 độ -> trái 30 độ”.
56
283: break;
284: case MRight_RE:
285: Right_Wheel(250);
286: DIR_R = REVERSE;
287: __delay_ms(100);
288: Right_Wheel(0);
289: __delay_ms(30);
290: break;
57
Kiểm tra MOTOR trái.
Motor bên trái sẽ lặp lại 1s theo trình
tự sau: quay thuận -> thắng lại.
switch(pattern)
Trong đường đua có rất nhiều tình huống, mỗi tình huống tương ứng với một pattern
(mô hình) nhất định. Do đó ta cần phân tích kỹ và lập trình cho mọi tình huống có thể
xảy ra từ đó xe đua sẽ đi với tốc độ nhanh nhất có thể và không chạy ra khỏi đường
đua. Mỗi pattern sẽ có một giá trị sensor để ta phân biệt, khi gặp đúng giá trị tương ứng
ta gán pattern tương ứng với đoạn chương trình xử lý tính huống đó. Kết thúc xử lý các
tình huống đặc biệt trên đường đua ta chuyền về pattern 0 là pattern xe chạy thẳng và
đường cong.
58
CHƢƠNG 6: NẠP CHƢƠNG TRÌNH VÀ SỬ DỤNG XE TDC MCR
Bƣớc 1: Cấp nguồn cho xe.
- Kết nối hai đầu nối nguồn lại với nhau.
Bƣớc 2: Mở nguồn
- Công tắc 1: Mở công tắc cấp nguồn cho xe. Kiểm tra đèn nguồn, nếu thấy đèn
sáng chứng tỏ mạch đã được cấp điện.
Ghi chú: Công tắc 1 mở nguồn cho board xử lý, công tắc 2 cấp nguồn cho động cơ xe.
(có một số xe ngược lại)
Công tắc 1
59
Ghi chú: Khi đèn báo pin yếu sáng, nếu tiếp tục sử dụng sẽ dẫn đến hư pin.
- Đèn báo pin yếu sáng, ta tiến hành nối pin với bộ sạc pin để sạc. Đợi đến khi đèn báo
sạc đầy (đèn sáng màu xanh), rút bộ sạc ra. Lúc này ta có thể tiếp tục sử dụng xe.
Ghi chú: Phải tháo jack cắm nguồn ra khỏi xe, quá trình sạc pin phải quan sát, không được bỏ
đi đâu. Vì pin rất dễ bị cháy, nổ. Quá trình sạc nếu pin nóng, phồng to bất thường phải ngưng
sạc ngay lập tức.
60
Hình 6. 5: Nối một đầu USB vào máy tính.
61
Bƣớc 5: Mở dự án mẫu
- Bên dưới cửa sổ phần mềm MPLAB có dòng chữ PICkit 2 Ready chứng tỏ
mạch nạp đã được kết nối với phần mềm. Nếu thấy dòng chữ PICkit 2 not
found, kiểm tra lại cáp USB kết nối với máy tính và card nạp, đóng dự án mẫu và
mở lại. Nếu thấy dòng chữ PICkit 2 Ready ta mới tiếp tục tiến hành bước kế tiếp
62
Bƣớc 6: Biên dịch và nạp chương trình xuống vi điều khiển
- Quá trình biên dịch thành công: Build successful; lúc này ta mới tiến hành nạp dữ liệu
xuống vi điều khiển
- Thấy dòng chữ Verifying Configuration Memory, quá trình nạp dữ liệu xuống vi điều
khiển thành công.
63
TÀI LIỆU THAM KHẢO
- Hướng dẫn tìm hiểu chương trình BKIT MCR – Bkit Hardware Club – Bkit4u
- www.renesas.com - Program_Explanation_Manual-kit07_38a
64