Năm 1976 công ty INTEL INTelligent ELectronics cho ra đời bộ vi xử lý trên thế giới có tích hợp bộ xử lý, bộ nhớ dữ liệu, bộ đếm chương trình, bộ đếm/phát thời gian timer, các cổng vào/
Trang 1CHƯƠNG III : CẤU TRÚC PHẦN CỨNG HỆ VI ĐIỀU KHIỂN
Giới thiệu chung
Lịch sử phát triển của các bộ vi xử lý gắn liền với lịch sử của linh kiện bán dẫn, mà mốc quan trọng nhất là sự phát minh ra Transistor Chip vi xử lý đầu tiên 4004 được ra đời năm 1971 dành
cho mục đích tính toán thương mại bởi công ty nhật bản Busicom, sau đó được chắp cánh và phát triển vượt bậc bởi Intel Năm 1976 công ty INTEL (INTelligent ELectronics) cho ra đời bộ
vi xử lý trên thế giới có tích hợp bộ xử lý, bộ nhớ dữ liệu, bộ đếm chương trình, bộ đếm/phát thời gian (timer), các cổng vào/ra trên một chip silic đơn tinh thể và chỉ đóng gói trong một vỏ, với tên gọi 8048 Các công ty khác cũng lần lượt cho ra đời các bộ điều khiển 8 bit tương tự với
8048 và hình thành họ vi điều khiển MCS-48 (Microcontroller System 48) Bốn năm sau, năm
1980, Intel cho ra đời thế hệ thứ hai của bộ vi điều khiển đơn chip là 8051 và trở thành công ty hàng đầu trong lĩnh vực sản xuất các bộ vi xử lý Ít lâu sau hàng loạt các thế hệ vi xử lý dẫn xuất của 8051 ra đời hình thành họ vi xử lý mạnh MCS51 Đến nay họ vi xử lý MCS51 đã có trên
250 thành viên và được các công ty bán dẫn hàng đầu thế giới chế tạo như Intel, AMD, Atmel, Siemens, Philips, Dallas, OKI, Các dẫn xuất này đều có chung một kiến trúc giống với vi điều khiển Intel 8051 kinh điển Thêm vào đó, tùy theo từng loại mà các chip dẫn xuất được tích hợp thêm các ngoại vi khác nhau (như ADC, SPI, EEPROM, capture/compare channels…), tính năng cũng được nâng cao để phù hợp với các ứng dụng ngày càng phức tạp Ngoài ra đối với các loại chip có cấu trúc CPU ngoại vi cố định (fixel digital and analog penpherals) còn phải kể đến các công ty khác có các sản phẩm là những họ vi điều khiển riêng cũng khá mạnh và được tiêu thụ nhiều trên thị trường Tuy nhiên mỗi loại lại có cấu trúc phần cứng được tổ chức khác nhau,
bộ lệnh riêng và các cấu trúc lập trình khác nhau Có thể kể ra như:
- Họ 68HCxx và các dẫn xuất của Motorola
vi điều khiển (µC) mà gọi là thiết bị PSoC (PsoC Device - Thiết bị lập trình trên chip), với hy vọng rằng người sử dụng sẽ có được những thiết bị nhỏ gọn, giá rẻ , tin cậy bởi chỉ dùng riêng
Trang 2chip PSoC mà không cần các kết nối ngoại vi khác và sản phầm này sẽ thay thế dần các thiết bị
sử dụng vi xử lý kinh điển trước đây Một số dạng thiết kế chip nhằm mục đích chủ yếu cho các bài toán xử lý dữ liệu như CPLD (Complex Programmable Logic Device), FPGA (Field Programmable Logic Array) có hỗ trợ kết nối máy tính với các phần mềm tiêu chuẩn, tái cấu hình lại nhiều lần… Lập trình mảng tương tự đã xuất hiện trong nhiều năm, nhưng chỉ mới gần đây mới được phát triển mạnh, và nền công nghiệp điện tử đã chấp nhận phát triển đầy đủ các công cụ phát triển và các phiên bản phần mềm phát triển mới Lập trình mảng tương tự FPAAs (Field Programmable Analog Arrays) cung cấp cho nhà thiết kế tính mềm dẻo như trong phần thiết kế mạch tương tự của họ Những dạng linh kiện này giải quyết tốt hầu hết các vấn đề ứng dụng trong những thành phần của hệ thống (Vi xử lý lõi, khối logic, khối tương tự) Ví dụ, một mạch chứa đựng thành phần chính là logic sẽ có lợi nhất khi sử dụng linh kiện lập trình logic, nhưng một thiết kế với nhiều thành phần tương tự sẽ không thích hợp với những linh kiện đó Tóm lại, vi xử lý là một lĩnh vực rộng đòi hỏi những nghiên cứu chuyên sâu với nhiều đầu tư cả
về thời gian, sức lực và kinh phí.Với những người bắt đầu, lời khuyên là các bạn nên sử dụng họ MCS51 và bắt đầu làm việc với dẫn xuất Atmel 89C52 bằng ngôn ngữ lập trình Assembly Đây
là ngôn ngữ cơ sở, đủ mạnh cho những ứng dụng nhỏ, có bản dùng thử miễn phí trên mạng Với Assembly bạn dễ dàng hiểu nắm bắt được phần cứng và rõ về hoạt động của vi xử lý, tuy nhiên khi cần phát triển những ứng dụng lớn hơn bạn sẽ gặp những hạn chế của ngôn ngữ này là phải
tự làm lấy mọi thứ mà không có sự hỗ trợ nào từ phần mềm thông qua hệ thống thư viện, đặc biệt là không hỗ trợ giao tiếp vào ra với thiết bị chuẩn như LCD, RTC, … Sau khi bạn đã nắm tốt về vi xử lý cơ sở và lập trình Assembly, bạn nên chuyển sang làm việc bằng C cho những thiết kế lớn hơn Phần mềm nên sử dụng ban đầu là Read51, được tích hợp cả Assembly và C nên tôi nghĩ rằng đây là phần mềm tốt nhất cho các bạn mới bắt đầu
Một số tính năng cơ bản của họ vi điều khiển Intel 8051 kinh điển:
- CPU 8 bit được thiết kế tối ưu cho các ứng dụng điều khiển
- Có các khả năng xử lý bit lôgic
- Không gian bộ nhớ chương trình 64Kbyte
- Không gian bộ nhớ dữ liệu 64 Kbyte
- Tích hợp 4 Kbyte bộ nhớ chương trình trên chip
- Tích hợp 128 byte bộ nhớ RAM trên chip
- Có 32 đường vào/ra 2 chiều có thể định địa chỉ đến từng bit
- Tích hợp 02 timer 16bit
- Tích hợp UART song công
- Cấu trúc ngắt với 06 nguồn/05 vector ở 02 mức ưu tiên khác nhau
- Tích hợp mạch bộ dao động trên chip
Trang 4I Cấu trúc hệ vi điều khiển
Kiến trúc phần cứng căn bản của vi điều khiển 8051 được mô tả bằng sơ đồ khối sau:
U1
8051
2930
402031
1918
9
393837363534333212345678
21222324252627281011121314151617
PSENALE
VCCGNDEA
X1X2
RST
P0.0/AD0P0.1/AD1P0.2/AD2P0.3/AD3P0.4/AD4P0.5/AD5P0.6/AD6P0.7/AD7P1.0P1.1P1.2P1.3P1.4P1.5P1.6P1.7
P2.0/A8P2.1/A9P2.2/A10P2.3/A11P2.4/A12P2.5/A13P2.6/A14P2.7/A15P3.0/RXDP3.1/TXDP3.2/INT0P3.3/INT1P3.4/T0P3.5/T1P3.6/WRP3.7/RD
Tổ chức bộ nhớ:
Họ vi điều khiển 8051 có hai không gian địa chỉ dành cho bộ nhớ chương trình và bộ nhớ dữ liệu là riêng biệt Cấu trúc riêng rẽ như vậy giúp cho bộ nhớ trong có thể truy nhập nhanh hơn với 8 bit địa chỉ vì CPU 8 bit sẽ có thể lưu trữ cũng như xử lý giá trị 8 bit này nhanh hơn so với giá trị 16 bit Ngoài ra, để có thể đạt được không gian địa chỉ 64 Kbyte dành cho bộ nhớ dữ liệu, chip được thiết kế với thanh ghi 16 bit tên là DPTR chuyên dùng để phát ra các địa chỉ 16 bit
Bộ nhớ chương trình có thể có dung lượng tối đa là 64 Kbytes Thông thường thì bộ nhớ chương trình tích hợp trên chip có dung lượng chỉ chiếm 4 Kbyte hay 8 Kbyte trong không gian 64 Kbyte đó Bộ nhớ chương trình có thể là bộ nhớ ngoài và được truy cập bằng tín hiệu #PSEN (“# “ có nghĩa là tích cực thấp), tức là khi sử dụng bộ nhớ trong cần nối chân #EA/VPP lên nguồn +5 VDC thông qua trở hạn dòng khoảng 4K7
Bộ nhớ chương trình:
Sau khi reset CPU bắt đầu làm việc từ địa chỉ đầu người sử dụng khai báo, thường là địa chỉ 0000H
Trang 5Các vector ngắt được quy định cố định ở các địa chỉ đầu tiên Nếu các ngắt được sử dụng thì mã lệnh của chương trình phục vụ ngắt tương ứng phải được đặt tại các địa chỉ của các vector ngắt
Do các vector ngắt là sát nhau nên không thể đặt các chương trình phục vụ ngắt tại các địa chỉ này (vì chương trình phục vụ ngắt của ngắt này sẽ đè lên vector ngắt của ngắt khác) mà thông thường người ta đặt tại đó các lệnh nhảy đến các chương trình phục vụ ngắt đã được đặt ở nơi khác trong bộ nhớ chương trình Nếu các ngắt không được sử dụng thì các ô nhớ dành cho các vector ngắt hoàn toàn có thể dùng như các vùng nhớ khác trong bộ nhớ chương trình Địa chỉ của bộ nhớ chương trình luôn là địa chỉ 16 bit cho dù dung lượng bộ nhớ thực được sử dụng không chiếm đầy không gian 64Kbyte
Vùng địa chỉ thấp nhất của không gian bộ nhớ chương trình có thể là bộ nhớ tích hợp trên chip hoặc bộ nhớ ngoài chip Lựa chọn này được thực hiện bằng cách nối chân #EA với VCC hoặc GND Như vậy với #EA nối với VCC thì không gian bộ nhớ chương trình sẽ bao gồm phần không gian địa chỉ thấp dành cho bộ nhớ tích hợp trên chip cộng với khoảng không gian còn thừa cho bộ nhớ ngoài chip Với chân #EA nối với GND, toàn bộ không gian nhớ chương trình được mặc nhiên coi là dành cho bộ nhớ ngoài (bất kể chip có được tích hợp bộ nhớ hay không – nghĩa là bộ nhớ chương trình nếu có tích hợp trên chip thì cũng không được dùng đến) Để truy nhập bộ nhớ ngoài thì người ta sử dụng tín hiệu #PSEN cùng hai cổng vào/ra P0 và P2 Khi viết chương trình cho vi xử lý, nếu chương trình lớn hơn 4 KBytes (Hoặc 8 KBytes với AT89C52) thông thường ta nên viết chương trình tại bộ nhớ ngoài, bỏ qua bộ nhớ chương trình tích hợp sẵn trên chip (Bộ nhớ trong) để dễ dàng hơn cho quá trình quản lý, lúc đó #EA nối GND
Bộ nhớ dữ liệu:
Bộ nhớ dữ liệu có dung lượng tối đa 64 Kbytes dùng để chứa dữ liệu cho chương trình Do bộ nhớ này có dung lượng hạn chế nên trong các thiết kế đòi hỏi dữ liệu ngoài là rất lớn, chương trình chứa nhiều dữ liệu ngoài vượt quá bộ nhớ của CPU như quang báo, Fuzzy, … người ta buộc phải sử dụng đến bộ nhớ dữ liệu ngoài để chứa các thông tin cần gọi vào chương trình xử
lý Đó là các dòng tin tức được đưa ra hiển thị ngoài Quang báo, các tập mờ, …
Trang 6Thanh ghi:
Khi lập trình cho vi xử lý, điều cần đặc biệt chú ý là khả năng điều khiển các ngắt làm việc Với các dòng sản phẩm khác nhau của họ vi xử lý MCS51, các ngắt của một chức năng hoạt động như nhau và được thiết kế tại cùng một địa chỉ Với các vi xử lý thế hệ sau của các hãng khác như SAB80515/535 thì có đôi chút khác biệt về tên gọi các bit, khả năng xử lý tương tự, Vì vậy khi xem xét vào ứng dụng với chip cụ thể, ta cần tra cứu tài liệu của hãng cung cấp Ở đây ta chọn vi xử lý AT89C52 là chip đại diện cho dòng chip để nghiên cứu bởi nó hoàn toàn tương thích với Intel 8051, khả năng làm việc trên phần mềm tích hợp Assembly-C có bản chạy thử miễn phí, chip này dễ tìm, giá rẻ, khả năng tương đối mạnh cho các ứng dụng nhỏ
Trang 7AT89C52 là vi xử lý điển hình của họ MCS51, khá mạnh cho những ứng dụng nhỏ Tích hợp 8 KBytes Flash ROM bộ nhớ chương trình trên chip và 256 Bytes RAM bộ nhớ dữ liệu trên chip, khả năng mở rộng tới 64 KBytes ROM và 64 Kbytes RAM
Trang 8AT89C529
1819
202930
31
40
12345678
21222324252627281011121314151617
3938373635343332
RST
XTAL2XTAL1
GNDPSENALE/PROG
EA/VPP
VCC
P1.0/T2P1.1/T2-EXP1.2P1.3P1.4P1.5P1.6P1.7
P2.0/A8P2.1/A9P2.2/A10P2.3/A11P2.4/A12P2.5/A13P2.6/A14P2.7/A15P3.0/RXDP3.1/TXDP3.2/INT0P3.3/INT1P3.4/T0P3.5/T1P3.6/WRP3.7/RD
P0.0/AD0P0.1/AD1P0.2/AD2P0.3/AD3P0.4/AD4P0.5/AD5P0.6/AD6P0.7/AD7
Đặc điểm cấu trúc chân cổng vi xử lý MCS51:
Nhận thấy rằng các chân của Port0 không có điện trở treo (Internal pull-up), vì vậy khi thiết kế
sử dụng cổng này mạch cần chú ý điện trở treo ngoài
Trang 9
AT89C52 có các ngắt cơ bản hay sử dụng: 2 Ngắt ngoài, 3 ngắt Timer, 1 ngắt nối tiếp Chú ý rằng vi xử lý này không có ADC nên không có các bit và ngắt xử lý tín hiệu tương tự như SAB80535 Trong phần lập trình ta sẽ bàn kỹ các vấn đề xử lý, điều khiển các thanh ghi này
Trang 10 Ngắt ngoài: là các tín hiệu ngắt được kích hoạt từ bên ngoài thông qua 2 chân vi xử lý /INT0 (P3.2) và /INT1 (P3.3) Có thể ngắt theo 2 kiểu, phụ thuộc bit ITx trong thanh ghi TCON:
- Theo mức khi bit ITx=0
- Theo sườn khi bit ITx=1
Ngắt Timer: Các Timer bao gồm hai dạng: Đếm xung thời gian từ Clock (Timer) và đếm
sự kiện ngoài (Countetr), được điều khiển thông qua các thanh ghi TMOD và TCON Các bộ đếm luôn đếm tiến, ngoại trừ Timer2 có một chế độ có thể đếm lùi
Trang 11Chế độ 0:
Chế độ 0 là chế độ định thời 13 bit, sử dụng Byte cao của THx ghép với 5 bit thấp trong Byte thấp TLx Chế độ này cung cấp khả năng tương thích với bộ vi điều khiển thế hệ trước 8048 Chế độ này không được dùng cho các thiết kế mới
Chế độ 1: Chế độ định thời 13 bit
Chế độ 1 là chế độ định thời 16 bit, có cấu hình giống như chế độ định thời 13 bit Ở chế độ này xung Clock được đặt kết hợp cả vào thanh ghi định thời cao và thấp Khi có xung Clock đến, Timer sẽ điến tiến từ 0000H FFFFH rồi xảy ra hiện tượng tràn dữ liệu, nhảy về 0000H Mỗi lần tràn dữ liệu sẽ phát sinh ra một cờ ngắt, tức set bit TF1 = 1 Đây là bit điều khiển Timer nằm trong TCON, được đọc/ghi bằng phần mềm
Trang 12 Chế độ 2: Chế độ định thời 16 bit
Chế độ 2 là chế độ tự nạp lại 8 bit, đây là chế độ hay sử dụng nhất Byte thấp của bộ định thời (TLx) hoạt động lưu giá trị đếm trong khi Byte cao (THx) giữ giá trị nạp lại Khi số đếm tràn từ FFH 00H, cờ tràn TF được set len 1 và giá trị trong THx còn được nạp vào TLx, bộ đếm sẽ tiếp tục đếm từ giá trị này Ví dụ dùng Timer tạo thời gian trễ là 1 s:
- Cách 1: Timer hoạt động ở chế độ 1
Dùng Timer 16 bit đếm từ 0, tràn x lần thì tăng số đếm
3 15 536
65
x lần tràn Timer, với số nạp ban đầu là: 655356-50000=15536
Như vậy ta có thể nạp cho Timer giá trị đầu là 15535, cho Timer đếm tiến tới 65535 thì tràn, hoặc nạp số -50000 Sai số của phương pháp này chỉ do lấy xấp xỉ tần số thạch anh (thường sử dụng 11,0592 MHz thay vì 12 MHz), không tránh khỏi
Trang 13Timer1 không hoạt động ở chế độ 3, nhưng có thể được khởi động bằng cách chuyển Timer này vào một chế độ khác Khi Timer0 ở chế độ 3, Timer1 có thể hoạt động hoặc ngừng bằng cách chuyển Timer này vào hoặc ra khỏi chế độ 3 Timer1 có thể sử dụng bởi Port nối tiếp làm nhiệm
vụ tạo tốc độ baud rate cho clock, hoặc sử dụng theo một cách khác nhưnưg không yêu cầu ngắt
vì lúc này không còn nối TF1.
Cách xử lý như trên tương đối phức tạp, vì vậy với vi xử lý AT89C52 ngoài các ngắt Timer 0
và 1 như 8051 còn thiết kế thêm Timer 2, chủ yếu phục vụ chủ yếu cho các ứng dụng truyền thông Timer 2 được điều khiển thông qua thanh ghi T2CON và T2MOD
Timer2 có 3 chế độ hoạt động: Chế độ thu nhận, chế độ tự nạp lại và chế độ tạo tốc độ baud Các chế độ này được chọn bởi các chân theo bảng:
Chú ý rằng Timer2 có thể lập trình đếm lên hoặc xuống khi hoạt động trong chế độ 16 bit, và chỉ
có Timer này có khả năng đếm lùi, Timer0 và Timer1 chỉ đếm tiến Cách sử dụng các Timer này các bạn sẽ được tìm hiểu kỹ trong phần ghép nối ngoại vi
Trang 16Thanh ghi điều khiển ngắt IE
Trang 17Khi thiết lập trạng thái ban đầu (reset hệ thống) tất cả các ngắt đều bị vô hiệu hoá (cấm), sau đó chúng được cho phép (set) bằng phần mềm Khi xảy ra 2 hay nhiều tác động ngắt đồng thời, hoặc xảy ra một ngắt trong khi ngắt khác đang được phục vụ thì các ngắt được xử ý theo sơ đồ
ưu tiên được lập trình bởi người sử dụng Mỗi nguyên nhân gây ngắt được hoặc không cho phép riêng rẽ thông qua thanh ghi cho phép ngắt IE, còn mỗi nguyên nhân gây ngắt được lập trình riêng rẽ để có một trong hai mức ưu tiên thông qua thanh ghi chức năng đặc biệt điều khiển ưu tiên ngắt IP
Trạng thái của tất cả các nguyên nhân gây ra ngắt thể hiện qua các bit cờ tương ứng Khi hệ thống được thiết lập trạng thái ban đầu, thanh ghi IP mặc định tất cả các ngắt ở mức ưu tiên thấp Nếu có 2 ngắt với mức ưu tiên ngắt khác nhau xuất hiện đồng thời, ngắt có mức ưu tiên cao hơn
sẽ được phục vụ trước Khi một ngắt xuất hiện và được CPU chấp nhận, chương trình phục vụ ngắt được kích hoạt theo các bước sau:
- Hoàn tất việc thực thi lệnh hiện hành
- Cất bộ đếm chương trình PC vào Stack
- Lưu giữ trạng thái hiện tại của chương trình chính hoặc ngắt đang làm việc
- Các ngắt được chặn lại ở mức ngắt
- Bộ đếm chương trình PC được nạp địa chỉ của vector phục vụ ngắt mới
- Thực thi phục vụ ngắt mới đén khi gặp lệnh RETI (RETurn Interrupt) Lện này lấy lại giá trị cũ của bộ đếm chương trình PC từ Stack và phục hồi trngj thái cũ
- Tiếp tục chương trình ở trạng thái tạm ngưng trước đó
Khi một chương trình phục vụ ngắt được trỏ tới, cờ gây ra ngắt sẽ tự động bị xoá về 0 bởi phần cứng Chú ý rằng khác với Timer là cờ TF sẽ tự động set khi tràn Timer, các ngoại lệ khác bao gồm cờ RI, TI đối với các Port nối tiếp, TF2 và EXF2 đối với các ngắt Timer2 Các nguyên nhân gây ngắt thuộc hai ngoại lệ trên do có hai khả năng tạo ra ngắt nên trong thực tế CPU không xoá cờ ngắt
Trang 18PORT NỐI TIẾP
Đặc trưng của Port nối tiếp là hoạt động song công, nghĩa là có khả năng thu/phát tín hiệu đồng thời Ngoài ra việc đệm dữ liệu của Port nối tiếp cho phép cho phép một ký tự được nhận và lưu trữ trong bộ đệm thu trong khi ký tự tiếp theo được nhận vào, CPU đọc dữ liệu thứ nhất trước khi dữ liệu thứ hai được nhận vào đầy đủ, dữ liệu cũng không bị mất Bộ đệm dữ liệu thu và lưu
dữ liệu vào SBUF, việc ghi lên SBUFsex nạp dữ liệu để phát và việc đọc SBUF sẽ xuất dữ liệu
đã nhậ được Các thao tác này được điều khiển thông qua thanh ghi điều khiển Port nối tiếp SCON
Chế độ hoạt động của Port nối tiếp được thiết lập bằng cách ghi từ điều khiển lên thanh ghi chọn chế độ SCON của Port nối tiếp Trước khi sử dụng Port nối tiếp, thanh ghi SCON phải được khởi động đúng theo chế độ yêu cầu Port nối tiếp có 4 chế độ hoạt động, đựoc chọn bằng cách ghi 1 hoặc 0 cho các bit SM0 và SM1 trong thanh ghi SCON Có ba chế độ truyền thông không đồng bộ, trong đó mỗi ký tự được thu hoặc phát sẽ phát kèm cùng với một bit START và một bit STOP tạo thành một khung truyền tin (Form)
Chế độ 0: Thanh ghi dịch 8 bit
Chế độ 0 được chọn bằng cách ghi giá trị 0 và 1 vào các bit SM0 và SM1 trong thanh ghi SCON
Dữ liệu nối tiếp được thu và phát thông qua chân RxD, chân TxD xuất xung dịch bit Khi phát
và thu dữ liệu, bit có trọng số thấp nhất LSB được phát hoặc thu đầu tiên Tốc độ baud cố định bằng 1/12 tần số của mạch dao động trên chip Việc phát dữ liệu được khởi động bằng một lệnh ghi dữ liệu vào SBUF Dữ liệu được dịch ra ngoài qua chân RxD (P3.0) với các xung Clock dịch được gửi ra trên chân TxD (P3.1) Mỗi một bit hợp lệ được truyền đi trên đường RxD trong một chu kỳ máy (1 mc 1 s với thạch anh 11,0592 MHz) Trong mỗi chu kỳ máy, xung Clock dịch bit đổi thành mức thấp và lấy trở lại mức cao Việc thu dữ liệu được khởi động khi bit cho phép
Trang 19thu REN ở mức logic 1 và cờ ngắt thu RI ở mức logic 0 Quy luật tổng quát là ta phải set bit REN = 1 ở thời điểm bắt đầu chương trình để khởi tạo Port nối tiếp, sau đó xoá bit RI = 0 để bắt đầu công việc thu dữ liệu Khi bit RI được xoá các xung Clock dịch bit xuất ra trên chân TxD, bắt đầu chu kỳ máy tiếp theo và dữ liệu được dịch vào chân RxD bởi xung Clock dịch bit, hiển nhiên là các mạch ghép nối để cung cấp dữ liệu trên đường RxD được đồng bộ bởi xung Clock dịch bit trên đường TxD
Chế độ này được ứng dụng trong quang báo, mở rộng cổng cho vi điều khiển Một vi mạch thanh ghi dịch nối tiếp song song có thể được nối với các chân TxD và RxD để cung cấp thêm 8 đường xuất dữ liệu Các thanh ghi dịch bit khác có thể ghép cascade với thanh ghi dịch đầu tiên để mở rộng thêm nữa
Chế độ 1: UART 8 bit có tốc độ baud thay đổi
Trong chế độ 1, Port nối tiếp hoạt động như một bộ thu phát không đồng bộ UART 8 bit có tốc
độ baud thay đổi, biến đổi dữ liệu phát từ song song thành nối tiếp để truyền đi trên một đường truyền và biến đổi dữ liệu thu từ nối tiếp thành song song Ở chế độ này Form truyền là 10 bit,
10 bit nhận trên RxD và 10 bit phát trên TxD cho mỗi ký tự dữ liệu Bao gồm 1 bit START (luôn là 0), 8 bit data và một bit STOP (luôn là 1) Khi hoạt động thu, bit STOP đưa lên RB8 của SCON Với 8951 tốc độ baud thiết lập bởi tốc độ tràn của Timer1, còn với 8952 tốc độ baud được thiết lập bởi tốc đọ ràn của Timer1 hoặc Timer2 hoặc tổ hợp của cả hai (một cho phát và một cho thu)
Việc cấp xung Clock dịch bit và đồng bộ các thanh ghi dịch bit của Port nối tiếp ở chế độ 1, 2 và
3 được thiết lập bởi bộ đếm 16 bit, ngõ ra của bộ đếm là xung Clock tốc độ baud, ngõ vào được chọn bởi phần mềm Việc phát được khởi động bằng cách ghi vào SBUF được thực sự bắt đầu ở lần tràn kế tiếp của bộ đếm cung cấp tốc độ baud cho Port nối tiếp Dữ liệu được dịch bit để xuất
ra trên đường TxD sẽ bắt đầu bằng bit START, tiếp theo là 8 bit data rồi đến bit STOP Thời gian của mỗi một bit là giá trị nghịch đảo của tốc độ baud Cò ngắt phát TI được set bằng 1 ngay kgi bit STOP xuất hiện trên đường TxD Việc nhận được khởi động bởi một chuyển trạng thái từ
1 xuống 0 trên đường RxD (bắt đầu start) Bộ đếm ngay lập tức được xoá đi để gán các số đếm cho dòng bit đến chân RxD, bit kế tiếp đến khi bộ đếm tràn lần nữa
Bộ thu phát hiện bit START bằng cách yêu cầu 8 số đếm ở trạng thái 0 sau khi có sự chuyển trạng thái từ 1 xuống 0 lần đầu tiên Nếu điều này không xảy ra, bộ thu biết rằng đã nhận được nhiều bit thay vì một bit hợp lệ, bộ thu sẽ được thiết lập lại quay về trạng thái nghỉ và chờ sự chuyển trạng thái từ 1 xuống 0 kế tiếp Giả sử một bit START hợp lệ được phát hiện, việc nhận
ký tự sẽ tiếp tục, bit START được bỏ qua và 8 bit data được nhận tuần tự vào thanh ghi dịch của Port nối tiếp Khi cả 8 bit ddax được nhận, vi xử lý thực hiện các việc sau:
- Bit thứ 0 (STOP bit) được đưa đến bit RB8 trong thanh ghi SCON
- 8 bit dữ liệu (data bit) được nạp vào SBUF
- Cờ ngắt thu RI được set lên 1
MCS51
TxD (P3.1) RxD (P3.0)
Clock Data Shift registerr
8 extra outputs
Trang 20 Chế độ 2: UART 9 bit có tốc độ baud cố định
Khi SM0 = 0 và SM1 = 1 Port nối tiếp hoạt dộng ở chế độ 2, chế độ UART 9 bit có tốc độ baud
cố định Form truyền là 11 bit cho việc thu/phát một ký tự dữ liệu, bao gồm 1 bit START, 8 bit data, bit thứ 9 lập trình được và 1 bit STOP Khi phát bit thứ 9 là bit kiểm tra chẵn lẻ (Parity bit) được đặt vào bit TB8 trong thanh ghi SCON, khi thu bit thứ 9 nhận được sẽ được đặt vào bit RB8 Tốc độ baud ở chế độ 2 bằng 1/32 hoặc 1/64 tần số mạch dao động trên chip
Chế độ 3: UART 9 bit có tốc độ baud thay đổi
Chế độ này tương tự như chế độ 2 ngoại trừ việc tốc độ baud được lập trình bởi Timer Thật ra
về cơ chế hoạt động của chế độ 1, 2 và 3 là như nhau, các chế độ hoạt động này chỉ khác nhau ở
ở tốc độ baud (cố định ở chế độ 2, thay đổi ở chế độ 3) và ở số bit dữ liệu (8 bit ở chế độ 1, 9 bit
ở chế dộ 2 và 3)
Tốc độ baud của Port nối tiếp:
Tốc độ baud sẽ luôn là cố định trong các chế độ 0 và 2 Trong chế độ 0, tốc độ baud luôn bằng tần số của mạch dao động chia cho 12 Thông thường khi sử dụng chế độ này trong truyền thông,
ta sử dụng thạch anh dao động ngoài có tần số 12 MHz để thu được tốc độ baud chế độ 0 là 1 Mhz Với chế độ 2, sau khi reset hệ thống, tốc độ baud bằng tần số của mạch dao động chia cho
64 Bit số 7 của PCON là SMOD quy định việc chia tần số dao động, SMOD = 1 chia tần cho 32, SMOD = 0 chia tần cho 64
Các tốc độ baud của 8951 ở chế độ 1 và 3 được xác định bởi tốc độ tràn của Timer1 Vì các Timer hoạt động ở tần số tương đối cao nên ta cần chia tốc độ tràn Timer cho 32 (SMOD = 0) hoặc 16 (SMOD = 1) trước khi tạo thành Clock cấp cho Port nối tiếp Tốc độ baud của 8952 ở các chế độ 1 và 3 được xác định bởi tốc độ tràn Timer1 hoặc Timer2 hoặc cả hai Timer
12
on chip
Oscillator
baud rate clock (a) Mode 0
32
Timer1
overflow
baud rate clock (b) Mode 1 và 3
16
Trang 21Khi sử dụng Timer1 làm xung clock tạo tốc độ baud, kỹ thuật thường dùng là khởi động thanh ghi TMOD ở chế độ Autoreload 8 bit (chế độ định thời 2) và đặt giá trị nạp lại thích hợp vào thanh ghi TH1 Khởi tạo TMOD bằng lệnh mov TMOD,#0010xxxxB , với xxxx dành cho Timer0 Đây không phải là khả năng duy nhất, các tốc độ baud chậm có thể nhận được bằng cách sử dụng Timer chế độ 16 bit, chế độ định thời 2 với TMOD = 0001xxxxB , các thanh ghi TH1/TL1 phải được nạp lại sau mỗi lần tràn Timer Điều này cần thực hiện nạp lại trong chương trình phục vụ ngắt Một lựa chọn khác là cung cấp xung clock bên ngoài cho Timer1 bằng cách
sử dụng ngõ vào T1 (P3.5) Dù là lựa chọn nào tốc độ baud cũng bằng tốc độ tràn của Timer1 chia cho 32 do vậy công thức xác định tốc độ baud ở chế độ 1 và 3 là:
Baud rate = Timer1 overflow rate : 32
Thí dụ nếu cần tốc độ baud là 1200, tốc độ tràn của Timer1 phải là 38,4KHz (1200 x 32) Nếu tần số dao động của mạch dao động là 12 MHz, Timer phải tràn ở tốc độ 38,4 KHz, như vậy hiện tượng tràn cần xảy ra sau mỗi 26,04 xung (1000/38,4) và sđược làm tròn là 26 Do Timer chỉ đếm tiến, tràn khi có số đếm từ FFH chuyển thành 00H, như vậy ta cần nạp lại tự động (Auto reload) số - 26 (0E6H) thông qua lệnh mov TH1,#0E6H Do làm tròn số xung đếm nên sẽ tạo ra sai số trong kết quả tính tốc độ baud Nói chung một sai số 5% là chấp nhận được trong truyền
dữ liệu không đồng bộ Để cấp tốc độ baud chính xác, ta sử dụng thạch anh 11,0592 MHz với số nạp là –3 (FDH)
Trang 22II.3 PHẦN CỨNG TỐI THIỂU CỦA HỌ MCS51
Phần cứng tối thiểu là cấu hình đơn giản nhất của phần cứng để hệ thống có thể hoạt động được với những bài toán thông thường Với các ứng dụng đơn giản, thường ta nên chọn tần số thạch anh giao động ngoài là 12 MHz, còn với những ứng dụng liên quan tới truyền thông ta chọn thạch anh 11,0592MHz để dễ dàng tính toán tốc độ truyền tin
Dưới đây đưa ra sơ đồ nguồn +5 VDC và sơ đồ tối thiểu cho một cấu trúc tối thiểu AT89C52 sử dụng bộ nhớ trong, dao động sử dụng thạch anh ngoài 11,0592 MHz Cầu Diode trong phần nguồn các bạn có thể thay 4 Diode bằng cầu chế tạo sẵn Ngoài ra để chống nhiễu tốt nên lắp thêm cuộn dây và Diode vào phím như sơ đồ chi tiết bảng thí nghiệm
D15 1N4007
C410uR1 470
+C61000u/25V
#EA
C5104
D14 LED
VCC
VCC
C8104D13 1N4007
U3
AT89C52
91819
20
2930
31
40
123456781011121314151617
3938373635343332
2122232425262728
RSTXTAL2XTAL1
GND
PSENALE/PROG
EA/VPP
VCC
P1.0P1.1P1.2P1.3P1.4P1.5P1.6P1.7P3.0/RXDP3.1/TXDP3.2/INT0P3.3/INT1P3.4/T0P3.5/T1P3.6/WRP3.7/RD
P0.0/AD0P0.1/AD1P0.2/AD2P0.3/AD3P0.4/AD4P0.5/AD5P0.6/AD6P0.7/AD7
P2.0/A8P2.1/A9P2.2/A10P2.3/A11P2.4/A12P2.5/A13P2.6/A14P2.7/A15
RESET
Y1
11.0592MHz
VCCU4
LM7805C/TO
C233
R20 470
D16 1N4007J5
#EA
R210K
C333
R34K7
Trang 23CHƯƠNG IV: LẬP TRÌNH CHO HỆ VI ĐIỀU KHIỂN
I Một số phần mềm lập trình thông dụng
II Tổ chức chương trình phần mềm
Tổng quan:
Khi một bài toán thực tế được đưa ra, ta cần phải tìm hiểu cặn kẽ các yêu cầu do bài toán đặt ra
và thực hiện giải quyết theo các bước sau:
- Bước 1: Định hướng giải quyết
- Bước 2: Lựa chọn phương án thiết kế phần cứng
- Bước 3: Lập lưu đồ thuật toán cho thiết kế phần mềm
- Bước 4: Thể hiện lưu đồ thuật toán bằng các lệnh cụ thể
Các bước 1 và 2 đã được trình bày trong các tài liệu hướng dẫn thiết kế các mạch thí nghiệm, ở đây chỉ chú trọng vào giải quyết các bước 3 và 4 Trong giai đoạn thiết kế phần mềm, bước 3 không chỉ là bước tiên phong mà còn là bước có ý nghĩa quyết định đối với sự thành công và chất lượng của sản phẩm Bước 4 chỉ là bước hoàn thiện cuối cùng của việc giải quyết một bài toán
Trước hết nói về lưu đồ thuật toán, như đã đề cập đến trong phần các kiến thức căn bản trong Kỹ thuật Vi xử lý, lưu đồ thuật toán có vai trò đặc biệt quan trọng trong thiết kế phần mềm Về cơ bản, một lưu đồ thuật toán có thể được xây dựng bằng các biểu tượng sau đây:
Trang 24Đây là biểu tượng dùng để diễn đạt sự lựa chọn một trong hai phương án đúng hoặc sai đối với điều kiện hay tình huống được nêu ra trong đó Biểu tượng này chỉ có một đầu vào nhưng lại có hai đầu ra
Đây là biểu tượng dùng để diễn đạt tiến trình làm việc của chương trình
III Tập lệnh hệ vi điều khiển
Direct - là một biến 8 bit(hay chính là ô nhớ) bất kỳ trong RAM (trừ 32 thanh ghi Rn ở
đầu RAM, địa chỉ phần thấp)
#data - là một hằng số 8 bit bất kỳ
#data16 - là một hằng số 16 bit bất kỳ
<rel> - là địa chỉ nằm trong khoảng [PC-128 ; PC+127]
<addr11> - là địa chỉ nằm trong khoảng [PC-
<addr16> - là địa chỉ bất kỳ trong không gian 64K (áp dụng cho cả không gian nhớ chương
trình và không gian nhớ dữ liệu)
<bit> - bit bất kỳ có thể đánh địa chỉ được (không dùng cho các bit không đánh được địa
chỉ)
Trang 25CÁC LỆNH TÁC ĐỘNG TRONG THANH GHI TRẠNG THÁI
Trang 2622 MUL AB B:A = A*B 1 48
trong thanh ghi A
CÁC LỆNH TRAO ĐỔI DỮ LIỆU
Trang 2718 MOVC A,@A+PC Đọc giá trị bộ nhớ chương
trình tại địa chỉ = A + PC, cất kết quả vào A
19 MOVX A,@Ri Đọc vào A giá trị của bộ nhớ
ngoài tại địa chỉ = Ri
20 MOVX A,@dptr Đọc vào A giá trị của bộ nhớ
ngoài tại địa chỉ = DPTR
21 MOVX @Ri,A Ghi giá trị của A vào bộ nhớ
ngoài tại địa chỉ = Ri
22 MOVX @dptr,A Ghi giá trị của A vào bộ nhớ
ngoài tại địa chỉ = DPTR
23 PUSH Direct Cất nội dung của biến trong
RAM vào đỉnh ngăn xếp
24 POP Direct Lấy byte ở đỉnh ngăn xếp cho
vào biến trong RAM
28 XCHD A,@Ri Hoán đổi 4 bit thấp giữa A và
một ô nhớ trong Ram tại địa chỉ = Ri
13 JC <rel> nhảy đến nhãn <rel> nếu C = 1 2 24
14 JNC <rel> nhảy đến nhãn <rel> nếu C = 0 2 24
15 JB Bit, <rel> nhảy đến nhãn <rel> nếu bit= 1 3 24
Trang 2816 JNB Bit, <rel> nhảy đến nhãn <rel> nếu bit= 0 3 24
17 JBC Bit, <rel> nhảy đến nhãn <rel> nếu bit =
1 và sau đó xóa luôn bit về 0
11 CJNE A,direct,<rel> So sánh và nhảy đến nhãn nếu
14 CJNE @Ri,#data,<rel> So sánh và nhảy đến nhãn nếu
byte có địa chỉ = Ri có nội dung khác với data
15 DJNZ Rn,<rel> Giảm Rn đi 1 và nhảy đến
nhãn nếu chưa giảm về 0
16 DJNZ Direct,<rel> Giảm direct đi 1 và nhảy đến
nhãn nếu chưa giảm về 0
CÁC CẤU TRÚC LẬP TRÌNH CƠ BẢN
Tóm Tắt Các Lệnh Nhảy (JMP)
Trang 31SKIP2 : CJNE P1,#11111011b, SKIP3
Add
ORG 0H
MOV R5,#25H ; nap 25H vao R5
MOV R7,#34H ; nap 34H vao R7
MOV A,#0 ; nap 0 vao A
ADD A,R5 ; cong R5 voi A
MOV A,#29H ; A = 29H, packed BCD
MOV R2,A ; sao luu A vao R
ANL A,#0FH ; che nibble cao (A=09)
ORL A,#30H ; chuyen thanh ma ASCII, A=39H (`9')
MOV R6,A ; luu ket qua vao R6 (R6=39H ASCII char)
MOV A,R2 ; lay la.i gia tri A ban dau
ANL A,#0F0H ; che nibble thap (A=20)
RR A ; quay pha 4 lan
RR A ;
RR A ;
RR A ; -> A=02
ORL A,#30H ; chuyen thanh ma ASCII
MOV R2,A ; luu vao R2
SJMP $
Bin2BCD ; doi Binary (P1) -> BCD (R5 R6 R7)
MOV A,#0FFH
MOV P1,A ; P1: input port
MOV A,P1 ; doc P1
MOV B,#10 ; B=0A hex (10 dec)
DIV AB ; chia cho 10
MOV R7,B ; luu digit thap
MOV B,#10 ;
DIV AB ; chia cho 10
MOV R6,B ; luu digit tiep theo vao R6
MOV R5,A ; luu digit cuoi vao R6
SJMP $
Cong_16bit
Trang 32; cong so 16-bit: 3CE7h + 3B8Dh
; ket qua luu trong: R7 R6
MOV R0,#40H ; nap con tro
MOV R2,#5 ; nap bien dem
CLR A ; A=0
MOV R7,A ; xoa R7
AGAIN: ADD A,@R0 ; cong o nh tro boi R0
DA A ; hieu chinh BCD
JNC NEXT ; neu CY=0 -> khong tang R7
INC R7 ; CY=1 -> ta(ng R7
NEXT: INC R0 ; tang con tro
DJNZ R2,AGAIN ; lap den khi R2=0
SJMP $
Cong_Don
; cong don 5 byte
ORG 0
MOV R0,#40H ; nap dia chi cho con tro
MOV R2,#5 ; R2: bien dem
CLR A ; A = 0
MOV R7,A ; xoa R7
AGAIN: ADD A,@R0 ; cong o nho tro boi R0
JNC NEXT ; neu CY=0 thi khong tang R7
INC R7 ; neu CY=1 thi tang R7
NEXT: INC R0 ; dich con tro len 1 dia chi
DJNZ R2,AGAIN ; lap cho den khi R2 = 0
SJMP $
Copy_String
; copy mot chuoi tu bo nho chuong trinh vao RAM noi
ORG 0
MOV DPTR,#MYDATA ; con tro nguon
MOV R0,#40H ; con tro dich
BACK: CLR A ; A=0
MOVC A,@A+DPTR ; lay data tu bo nho CT
JZ HERE ; thoat neu data = 0 (NULL)
MOV @R0,A ; luu vao RAM
INC DPTR ; tang con tro nguon
INC R0 ; tang con tro dich
SJMP BACK ;
HERE: SJMP HERE
ORG 250H
MYDATA: DB 'HUTECH',0 ; chuoi du lieu
; ket thuc la 0 (NULL char)
END
Copyblock
; copy khoi du lieu 10 byte tu 35h den 60h
ORG 0
MOV R0,#35H ; con tro nguon
MOV R1,#60H ; con tro dich
MOV R3,#10 ; bien dem (10 bytes)
BACK: MOV A,@R0 ; doc 1 byte tu data nguon
MOV @R1,A ; copy vao dich
INC R0 ; tang con tro nguon
INC R1 ; tang con tro dich
DJNZ R3,BACK ;
SJMP $
Trang 33MOV A,#0AAH ; A = AAh
MOV P1,A ; P1 = AAh
POP 5 ; POP INTO R5
POP 4 ; POP INTO R4
; tra bang tinh x2
; xuat ket qua ra P2
ORG 0
MOV DPTR,#300H ; nap dia chi bang tra
MOV A,#0FFH ;
MOV P1,A ; P1: input
BACK: MOV A,P1 ; doc x
MOVC A,@A+DPTR ; tra bang tinh x^2
MOV P2,A ; xuat ra P
MOV A,#62H ; A=62H
SUBB A,#96H ; 62H-96H=CCH, CY=1
MOV R7,A ; luu ket qua
MOV A,#27H ; A=27H
MOV A,#4Ch ; A=4CH
SUBB A,#6EH ; A=A-6Eh
JNC NEXT ; neu CY=0 nhay den NEXT
CPL A ; neu CY=1 lay bu 2
Trang 34Để làm rõ hơn cách xây dựng một lưu đồ cụ thể, ta hãy xem xét một bài toán mẫu đơn giản trên
cơ sở phần mạch phần cứng thí nghiệm và lưu đồ mẫu để giải quyết bài toán đó
Bài toán: Nhấp nháy 8 LED đơn nối với cổng P1 theo chu kỳ 1 giây sáng và 1 giây tắt
Như vậy với yêu cầu do bài toán đặt ra, lưu đồ thuật toán phải được xây dựng như sau:
Hoặc nếu không quan tâm đến trạng thái bắt đầu của sự nhấp nháy (tức là không cần biết sáng trước hay tắt trước), ta có thể có được lưu đồ đơn giản hơn:
Trong hai chương trình trên có sử dụng chương trình con “delay1s” Có thể sử dụng Timer để tạo trễ, tuy nhiên với các ví dụ đơn giản ta nên sử dụng phương pháp lặp vòng chương trình Sử dụng các vòng lặp djnz (2mc) lồng nhau chạy tiêu tốn thời gian cần thiết, thạch anh 12 MHz
delay1s: ;day la chuong trinh con tao tre 1 giây
Trang 35delay1s: ;day la chuong trinh con tao tre 1 giây
;(1+1+1+1+1+1+1+1+2)mcx100x100x10=1000000mc=1000000us=1s mov r1,#10
Trang 36Lưu đồ thuật toán cho chương trình con “delay1s” như sau:
Trang 37Với lưu đồ thuật toán thứ nhất ta có thể thực hiện bước 4 như sau:
org 40h ;dat chuong trinh chinh bat dau tu dia chi này de
;tranh khong de len vung cac vector ngat main:
mov p1,#0 ;cho sáng 8 den LED noi voi P1
lcall delay1s ;tre 1 giây
mov p1,#0ffh ;tat 8 den LED noi voi P1
lcall delay1s ;tre 1 giây
sjmp main ;quay tro lai tiep tuc nhu the
delay1s: ;day la chuong trinh con tao tre 1 giây
mov a,p1 ;lay gia tri hien thoi cua cong P1
cpl a ;dao gia tri (lat trang thai, 0 thanh 1, 1 thanh 0)
mov p1,a ;dua ra tro lai P1 de thuc hien dao trang thai cac LED lcall delay1s
Trang 38CẤU TRÚC CHƯƠNG TRÌNH ASSEMBLY
Nếu chương trình đơn giản, ta viết tất cả tại chương trình chính
#include <sfr51.inc> ; thư viện chuẩn
Form của một chương trình đầy đủ bao gồm các ngắt, các chương trình con
#include <sfr51.inc> ; thư viện chuẩn
#include “mylib.inc” ; thư viện người lập trình
;khai báo biến nếu cần
; -
org 00h
ljmp main
org xxH ; Địa chỉ ngắt sử dụng ljmp Ngắt_i
org yyH ; Địa chỉ ngắt sử dụng ljmp Ngắt_j
; -
org 40h
main:
mov sp,#5Fh ;stack lcall Khởi tạo
lcall Tạo trễ
main_loop:
lcall Xử lý chương trình lcall Các xử lý khác
Trang 39Chương 5 THIẾT KẾ MỘT SỐ GHÉP PHỐI CƠ BẢN VỚI HỆ VI ĐIỀU KHIỂN
I Ghép nối LED đơn
Đây là ghép nối đơn giản nhất Các LED đơn có thể sáng rõ với một vài mA dòng điện cung cấp
Có 02 cách cung cấp dòng phân cực thuận cho LED đơn:
Cách thứ nhất: bơm dòng
I/O port
LED R
Cách thứ hai: Nuốt dòng
I/O port
LED R
Trong cách ghép nối thứ nhất, để LED phát sáng cần đưa ra giá trị logic 1 (ứng với điện áp +5V)
để phân cực thuận cho LED Dòng điện I sẽ chảy từ cổng vi xử lý qua điện trở hạn dòng, qua LED về đất
Trong cách ghép nối thứ hai, để LED phát sáng cần đưa ra giá trị logic 0 (ứng với điện áp đưa ra
là 0V) Dòng điện I lúc này sẽ chảy từ dương nguồn qua điện trở hạn dòng, qua LED vào chân
vi xử lý
Trong hai kiểu ghép nối trên, kiểu thứ 2 là kiểu được dùng nhiều hơn vì cổng vi xử lý do thiết kế chế tạo có đặc điểm: có thể sinh ra dòng điện tối đa vài trăm A nhưng có thể “nuốt” được dòng điện cỡ vài chục mA
Bài tập 1: Viết chương trình nháy LED dơn nối cổng p1.0, 1nhịp/ 1giây
Cách 1: Cấu trúc tuần tự, đưa tất cả vào chương trình chính
Trang 40Bài toán phát triển:
Coi dãy LED đơn là dãy đèn quảng cáo Viết chương trình nháy đèn theo một chu trình đặt trước (Tuỳ chọn theo yêu cầu khách hàng)