Sơ đồ ghép nối AT89S52với RAM

Một phần của tài liệu luận văn thạc sỹ khoa học ngiên cứu, thiết kế hệ điều hành trên bộ vi điều khiển 8 bit (Trang 34)

Hình 2.5. Giải m∙ địa chỉ cho các vi mạch nhớ

8051 A0-A7 RAM Port 0 D0-D7 EA 74HC373 ALE RD WR OE WE O G D Port 2 A8-A15 RAM RAM text Address Bus (A0- A15)

Data Bus (D0-D7) 74HC138 C B A E E E 7 6 5 4 3 2 1 0 CS CS CS CS CS CS A0-A12 A0-A12 D0-D7 D0-D7 OE OE WE WR RD PSEN RAM 8KBytes EPROM 8KBytes 2764 6264

Select another EPROM/RAM Tới các vi mạch ROM/RAM khác

Boọ nhụự dửừ lieọu ngoaứi laứ boọ nhụự RAM ủửụùc ủóc hoaởc ghi bụỷi tớn hieọu /RD vaứ WR.Caực RAM coự theồ giao tieỏp vụựi AT89S52 tửụng tửù caựch thửực nhử

EPROM ngối trửứ chãn /RD cuỷa AT89S52 noỏi vụựi chãn /OE (Output Enable)

cuỷa RAM vaứ /chãn WR cuỷa AT89S52 noỏi vụựi chãn /WE cuỷa RAM (hỡnh 2.10). Neỏu coự nhiều vi mách ROM vaứ RAM cuứng ủửụùc gheựp noỏi vụựi AT89S52 thỡ coự theồ duứng thẽm vi mách giaỷi maừ 74LS138 (hỡnh 2.5).

Nhử ủaừ noựi ụỷ trẽn, boọ nhụự chửụng trỡnh vaứ boọ nhụự dửừ lieọu cuỷa AT89S52 coự theồ truứng ủũa chổ, ủiều naứy cho pheựp ngửụứi thieỏt keỏ coự theồ xãy dửùng moọt boọ nhụự dửừ lieọu chửựa chửụng trỡnh thửùc thi (boọ nhụự dửừ lieọu ủóc nhử boọ nhụự chửụng trỡnh) nhử hỡnh 2.6.

Hình 2.6. Bộ nhớ dữ liệu đọc nh− bộ nhớ ch−ơng trình

2.1.3. Các bộ định thời.

Caực boọ ủũnh thụứi (Timer) coự theồ hieồu laứ moọt chuoĩi caực flip-flop chia ủõi tần soỏ noỏi tieỏp vụựi nhau, chuựng nhaọn tớn hieọu vaứo laứm nguồn xung nhũp, ngoừ ra cuỷa tần soỏ cuoỏi laứm nguồn xung nhũp cho flip-flop baựo traứn cuỷa Timer (flip-flop cụứ). Giaự trũ nhũ phãn trong caực flip-flop cuỷa Timer coự theồ

RAM W OE W RD PSEN

xem nhử soỏ ủeỏm soỏ xung nhũp (hoaởc caực sửù kieọn) tửứ khi khụỷi ủoọng Timer. Vớ dú Timer 16 bit seừ ủeỏm lẽn tửứ 0000H ủeỏn FFFFH, cụứ baựo traứn seừ lẽn 1 khi soỏ ủeỏm traứn tửứ FFFFH ủeỏn 0000H.

AT89S52 coự 3 Timer 16 bit, mi Timer coự boỏn cheỏ ủoọ hốt ủoọùng. Ngửụứi ta sửỷ dúng caực Timer ủeồ: ẹũnh khoaỷng thụứi gian, ủeỏm sửù kieọn hoaởc táo toỏc ủoọ baud cho port noỏi tieỏp trong.

Hình 2.7. Hoạt động của Timer0 và Timer1 ở chế độ 1.

Nguyên tắc hoạt động của các bộ định thời nh− sau:

Nguồn xung clock đ−ợc đ−a tới Timer từ một trong cách phụ thuộc vào bit C-T trong thanh ghi TMOD:

• Nếu C-/T = 1, xung clock sẽ đ−ợc lấy từ bộ tạo xung bên ngồi qua

chân Tx(T0,T1 hoặc T2).

• Nếu C-/T = 0, xung clock sẽ đ−ợc lấy từ bộ chia tần trong chip, tần

số của xung ở đây là 1/12 tần số của bộ dao động thạch anh (Fosc).

Nguồn xung clock nĩi trên sẽ đ−ợc điều khiển để đ−a tới các Timer bằng các bit: TR, GATE và mức logic trên các chân INTx:

• Nếu TRx=0, các Timer sẽ bị cấm mà khơng cần quan tâm tới GATE

• Nếu TRx=1, các Timer sẽ hoạt động với một trong 2 điều kiện sau xảy ra (thể hiện bằng cổng ‘OR”): Thứ nhất: bit GATE=1; thứ hai: trên chân INTx cĩ mức logic 1.

Giá trị lớn nhất mà các Timer chứa đ−ợc là 65535 (t−ơng ứng FFFF(H)), khi đếm quá giá trị này sẽ xảy ra tràn, khi cờ tràn TF sẽ đ−ợc đặt bằng 1 và gây ra ngắt do bộ định thời. Căn cứ vào sự kiện này bộ xử lý ngắt sẽ nạp dịa chỉ của vector ngắt cho con trỏ PC, bộ vi điều khiển sẽ thực hện ch−ơng trình ở đây.

Trong hệ điều hành thời gian thực, bộ định thời là một trong những tài nguyên phần cứng khơng thể thiếu. Bộ định thời dùng để xác định các khoảng thời gian thích hợp cho mỗi tiến trình hoạt động (gọi là timer tick). Khoảng thời gian này cĩ thể thay đổi dẽ dàng nhờ việc nạp các giá trị khác nhau cho bộ timer. Khoảng thời gian này cũng thay đổi tuỳ theo các ứng dụng thời gian thực sao cho nĩ ln nhỏ hơn thời gian đáp ứng của hệ thống với các kích thích bên ngồi.

2.1.4. Bộ xử lý ngắt.

Ngắt cĩ thể hiểu đơn giản là tạm dừng một hoạt động A nào đĩ và chuyển sang một hoạt động B khác cĩ nhu cầu cấp thiết hơn. Khi xảy ra ngắt, tồn bộ các cơng việc, trạng thái của hoạt động A sẽ đ−ợc cất vào ngăn xếp để làm căn cứ tiếp diễn khi bộ vi xử lý đã hồn thành xong hoạt động B và quay trở lại với hoạt động A.

AT89S52 cĩ 6 nguồn ngắt: - Ngắt ngồi đến từ chân /INT0. - Ngắt ngồi đến từ chân /INT1. - Ngắt do bộ timer 0.

- Ngắt do bộ timer 1. - Ngắt do bộ timer 2.

- Ngắt do Port nối tiếp.

6 nguồn ngắt này đ−ợc xố khi Reset và đ−ợc đặt riêng bằng phần mềm bởi các bit trong các thanh ghi cho phép ngắt (IE), thanh ghi −u tiên ngắt (IP).

Hình 2.8. Các nguồn ngắt của AT89S52

Nh− đã trình bày ở mục 2.3, các bộ định thời tạo ra các khoảng thời gian (time tick), theo đĩ các một tiến trình phải đ−ợc tạm dừng và một tiến trình khác sẽ đ−ợc thực hiện. Sự chuyển mạch sang tiến trình mới kéo theo việc phải l−u lại các cơng việc của tiến trình cũ. Ngắt do bộ định thời chính là cơ sở để cĩ thể thực hiện việc chuyển mạch giữa các tiến trình.

Ngồi ra trên vi điều khiển cịn cĩ một số các nguồn ngắt khác. Các nguồn ngắt này khi đ−ợc đặt ở các thứ tự −u tiên thích hợp sẽ là con đ−ờng để một hệ thống thời gian thực cĩ thể phản ứng kịp thời với các kích thích từ bên ngồi.

2.2. Ngơn ngữ lập trình cho vi điều khiển

2.2.1. Tổng quan về các ngơn ngữ lập trình cho vi điều khiển.

Cho đến nay khi lập trình cho các bộ vi điều khiển ng−ời ta th−ờng sử dụng 2 ngơn ngữ chính đĩ là hợp ngữ và C. Hợp ngữ (assembly) là ngơn ngữ lập trình bậc thấp (chỉ đứng trên ngơn ngữ máy một bậc). Hợp ngữ sử dụng chính ngay tập lệnh của bộ vi điều khiển t−ơng ứng để viết nên một ch−ơng trình. Để biên dịch thành mã máy cĩ thể sử dụng trình dịch hợp ngữ (assembler) hoặc cĩ thể dùng chính bảng mã lệnh do nhà sản xuất cung cấp để mã hố các lệnh và tổng hợp thành mã (code) của ch−ơng trình. Chúng ta cùng xem xét ví dụ sau:

MOV AL,80H ; chuyển số 80H vào AL MOV BL,12H ; chuyển số 12H vào BL ADD AL,BL ; cộng hai số với nhau.

Trong đoạn ch−ơng trình trên nếu tra bảng mã sẽ cĩ đ−ợc mã của 3 lệnh lần l−ợt là:

B0 80 B3 12 80 C0

Nếu tổng hợp lại thì mã của đoạn ch−ơng trình trên sẽ là B0 80 B3 12

80 C0.

Cách tra bảng mã lệnh và hố lệnh sau đĩ tổng hợp thành mã ch−ơng trình cĩ thể gây ra nhầm lẫn và mất rất nhiều thời gian chính vì vậy mà trình dịch hợp ngữ ra đời. Cĩ trong tay trình dịch hợp ngữ ng−ời lập trình cĩ thể đã giảm bớt

đ−ợc khá nhiều cơng sức khi lập trình cho vi điều khiển. Tuy nhiên chúng ta cùng xem xét ví dụ sau:

Thực hiện phép tốn AX=7 * 9 + 12 * 8. Hợp ngữ:

MOV AL,7 ;số hạng thứ nhất chứa trong AL MOV BL,9 ;số hạng thứ hai chứa trong BL MUL BL ;nhân 2 số, kết quả chứa trong AX MOV CX,AX ;chuyển kết quả vào thanh ghi khác để chuẩn bi cho phép ;nhân thứ hai

MOV AL,12 MOV BL,8 MUL BL

ADD AX,CX ;cộng hai tích với nhau

AINSI C:

AX=7*9+12*8;

Rõ ràng với cùng một nhiệm vụ nh−ng AINSI C chỉ cần 1 dịng lệnh trong khi hợp ngữ cần tới 8 dịng lệnh và cả 8 dịng lệnh trên đều phải thao tác trên các thanh ghi (phần cứng). Từ lý do này mà ng−ời ta nghĩ đến việc nên sử dụng một ngơn ngữ cấp cao hơn để thay thế cho hợp ngữ và xây dựng trình dịch (compiler) cho ngơn ngữ cấp cao đĩ.

Khi thiết kế phần mềm cho một hệ thống nhúng nhỏ sử dụng 8085, việc sử dụng mã hợp ngữ (assembly code) để phát triển tồn bộ sản phẩm đã trở thành chuyện bình th−ờng. Đối với nhiều đề tài, đây là tiếp cận khả thi vì l−ợng mã cần đ−ợc tạo ra th−ờng nhỏ hơn 8 Kbyte và t−ơng đối đơn giản về bản chất. Nếu một kỹ s− phần cứng đ−ợc giao nhiệm vụ thiết kế cả phần cứng lẫn phần mềm, ng−ời này th−ờng cĩ khuynh h−ớng viết phần mềm bằng hợp ngữ. Ng−ời kỹ s− phần

cứng th−ờng khơng quen với một ngơn ngữ cấp cao nh− C chẳng hạn hoặc ng−ời này khơng quan tâm đến ngơn ngữ cấp cao.

Khuyết điểm của các đề tài đ−ợc viết bằng hợp ngữ cĩ thể là khĩ đọc và khĩ bảo trì, đặc biệt khi các ch−ơng trình cho các đề tài này khơng đ−ợc chú thích tốt. Ngồi ra, l−ợng mã cĩ thể sử dụng lại từ một đề tài viết bằng hợp ngữ th−ờng rất thấp. Việc sử dụng ngơn ngữ cấp cao nh− C cĩ thể giải quyết các vấn đề này.

Một ch−ơng trình đ−ợc viết bằng C sẽ dễ đọc hơn so với ch−ơng trình đ−ợc viết bằng hợp ngữ. Do ch−ơng trình viết bằng C sở hữu các cấu trúc lớn hơn, ta dễ dàng hiểu và bảo trì ch−ơng trình. Do tính cĩ module của ngơn ngữ C, một ch−ơng trình viết bằng C cĩ thể sử dụng lại mã một cách tốt hơn khi đi từ đề tài khác. Việc chia ch−ơng trình thành nhiều hàm sẽ thúc đẩy cấu trúc phần mềm tốt hơn và dẫn đến các hàm cĩ thể đ−ợc lấy ra từ một đề tài và sử dụng vào đề tài khác, nh− vậy sẽ giảm tổng thời gian phát triển.

Một ngơn ngữ cấp cao chẳng hạn nh− C cho phép ng−ời phát triển viết ch−ơng trình t−ơng đồng nhiều hơn với suy nghĩ của con ng−ời so với ch−ơng trình viết bằng hợp ngữ. Ng−ời phát triển cĩ thể tập trung nhiều thời gian hơn vào việc thiết kế các giải thuật của hệ thống thay vì phải tập trung vào việc thực hiện riêng rẽ các giải thuật. Điều này sẽ làm giảm một cách đáng kể thời gian phát triển và làm giảm thời gian gỡ rối vì ch−ơng trình sẽ dễ hiểu hơn.

Bằng cách sử dụng ngơn ngữ giống nh− C, ng−ời lập trình khơng cần phải am t−ờng kiến trúc của bộ vi điều khiển. Điều này cĩ nghĩa là một ng−ời ch−a quen với một bộ vi điều khiển cho sẵn cĩ thể xây dựng một đề tài nhanh hơn vì tổ chức bên trong của bộ vi điều khiển đích cĩ thể khơng cần nghiên cứu. Ngồi ra ch−ơng trình đ−ợc phát triển bằng C sẽ dễ dàng sử dụng với các hệ thống khác so với ch−ơng trình đ−ợc phát triển bằng hợp ngữ.

Nhiều bộ vi điều khiển cĩ các trình dịch ngơn ngữ C, các trình dịch này hỗ trợ AINSI C.

Tất cả các điều này khơng cĩ ý muốn nĩi rằng hợp ngữ khơng cĩ vai trị của mình. Trên thực tế nhiều hệ thống nhúng (đặc biệt là các hệ thống thời gian thực) kết hợp ch−ơng trình C và ch−ơng trình hợp ngữ.

Đối với các thao tác cĩ thời gian tới hạn, ch−ơng trình hợp ngữ th−ờng là ph−ơng pháp duy nhất đ−ợc lựa chọn. Tuy nhiên theo kinh nghiệm, phần cịn lại của đề tài (bao gồm nhiều giao diện phần cứng) cĩ thể và nên đ−ợc phát triển bằng C. Một trong những điều quan trọng nhất về ngơn ngữ C là ngơn ngữ này cho phép ta thực hiện các thao tác mức thấp của phần cứng nếu cần, lại cịn cung cấp cho ta chức năng và khái niệm trừu t−ợng của ngơn ngữ cấp cao.

2.2.2. Những vấn đề với ngơn ngữ C viết cho các bộ vi điều khiển.

Ngơn ngữ lập trình C là một ngơn ngữ lập trình đ−ợc sử dụng rộng rãi trên thế giới. Nhiều ng−ời cho rằng đây là ngơn ngữ lập trình bậc cao vì C cĩ khá nhiều thuộc tính giống các ngơn ngữ lập trình bậc cao, ví dụ nh−: cấu trúc của ch−ơng trình, cách định nghĩa và gọi các thủ tục...,tuy nhiên sức mạnh thực sự của C khơng phải ở đĩ mà chính là khả năng truy nhập phần cứng, thao tác trên các bit, byte, word của phần cứng đối t−ợng. Cũng chính bởi lý do này mà C đ−ợc rất nhiều nhà thiết kế hệ điều hành sử dụng là ngơn ngữ lập trình bên cạnh hợp ngữ, cĩ thể kể ra các hệ điều hành cĩ sử dụng C để lập trình nh−: UNIX, LINUX, MS-Windows...

Trên bộ vi điều khiển 8bit, dễ hiểu là khơng thể đem so sánh về tài nguyên đối với các bộ vi xử lý đ−ợc chọn để viết hệ điều hành LINUX hay Windows. Cĩ thể kể ra một số dẫn chứng: tài nguyên về bộ nhớ của vi điều khiển chỉ vài Kbyte đối với bộ nhớ ch−ơng trình và vài trăm byte đối với bộ nhớ dữ liệu; khơng gian địa chỉ cũng chỉ là vài chục Kbyte...

Trình dịch C cĩ khả năng nhận mã nguồn C (C source code) của ng−ời lập trình và tạo ra mã đối t−ợng (object code) đ−ợc tối −u hố cao từ mã nguồn này. Tuy nhiên cĩ nhiều điều mà chúng ta, với t− cách là ng−ời thiết kế, cĩ thể thực hiện để giúp cho trình dịch tạo ra mã tốt hơn để cĩ thể tiết kiệm đợc tối đa các tài nguyên của vốn hạn chế của bộ vi điều khiển.

2.2.2.1. Giảm kích th−ớc biến.

Một trong những điều cơ bản nhất mà ta cần phải làm để cải thiện ch−ơng trình của ta là đặc biệt l−u ý đến kích th−ớc của các biến. Đối với ng−ời th−ờng lập trình bằng C trên các máy chẳng hạn nh− một mainframe hoặc PC, việc khai báo những điều nh− là các bộ đếm vịng lặp d−ới dạng các số nguyên là rất bình th−ờng, ngay cả đối với các biến mà giá trị của chúng khơng bao giờ v−ợt quá 255. Trên một máy 8 – bit nh− 8051, việc sử dụng rộng rãi các kiểu dữ liệu cĩ kích th−ớc lớn hơn 8 bít sẽ gây ra sự hoang phí lớn về khả năng xử lý và bộ nhớ. Ta cần phải cẩn thận xem xét tầm giá trị đối với biến mà ta khai báo và kế đến

chọn kiểu nhỏ nhất thoả yêu cầu. Hiển nhiên kiểu đ−ợc −a chuộng nhất đối với

các biến sẽ là unsigned char, do kiểu này chỉ sử dụng 1 byte.

2.2.2.2. Sử dụng kiểu unsigned.

Đến đây, ta cĩ thể ngạc nhiên vì kiểu đ−ợc −a chuộng là kiểu unsigned

char thay vì là kiểu char. Lập luận đằng sau điều này là 8051 khơng hỗ trợ số học cĩ dấu và đoạn mã phụ đ−ợc yêu cầu bởi một giá trị cĩ dấu, trái ng−ợc với một giá trị khơng dấu, sẽ lấy đi tồn bộ các tài nguyên của bộ vi điều khiển. Nh− vậy cùng với việc chọn lựa các kiểu biến t−ơng ứng với tầm giá trị, ta cũng phải xem xét xem cĩ phải biến sẽ đ−ợc sử dụng cho một thao tác nào đĩ sẽ yêu cầu các số âm. Nếu khơng, ta cần đảm bảo rằng ta chỉ ra biến cĩ kiểu unsigned. Ta cần loại bỏ các số âm ra khỏi một hàm hoặc tồn bộ ứng dụng của ta.

2.2.2.3. Khơng sử dụng số dấu chấm động.

Việc thực hiện các phép tốn số dấu chấm động trên các giá trị 32-bit với một bộ vi điều khiển 8 bit cũng giống nh− ta cắt một bãi cỏ bằng các đồ dùng cắt mĩng tay. Ta cĩ thể thực hiện đ−ợc điều này nh−ng sẽ hoang phí một l−ợng thời gian lớn khủng khiếp. Bất kỳ lúc nào ta dự định sử dụng dụng số dấu chấm động trong một ứng dụng, ta cần phải tự hỏi xem cĩ phải điều này là tuyệt đối cần thiết hay khơng? Thơng th−ờng, các số dấu chấm động cĩ thể đ−ợc loại bỏ bằng cách tăng cấp tất cả các giá trị bằng một cặp cùng bậc về độ lớn và sử dụng các phép tốn số nguyên. Ta sẽ xử lý tốt hơn các số kiểu int và long so với các số kiểu double và float. Ch−ơng trình của ta sẽ thực thi nhanh hơn và các th−ờng trình số dấu chấm động sẽ khơng đ−ợc liên kết vào trong ứng dụng của ta. Ngồi ra nếu ta cần phải sử dụng số dấu chấm động, ta cần xem xét việc sử dụng các phiên bản của 8051, các phiên bản này đã đ−ợc tối −u hố đối với các phép tốn số học chẳng hạn nh− Siemens 80517, 80537 hoặc Dallas Semiconductor 80320.

Cĩ nhiều khi ta bị ép buộc phải liên kết chặt chẽ với việc sử dụng các số dấu chấm động trong hệ thống của ta. Ta đã biết những bất lợi về kích th−ớc

Một phần của tài liệu luận văn thạc sỹ khoa học ngiên cứu, thiết kế hệ điều hành trên bộ vi điều khiển 8 bit (Trang 34)

Tải bản đầy đủ (PDF)

(86 trang)