Mục lục
Lời nói đầu
Ngày này, việc ứng dụng máy tính vào các kỹ thuật đo lường và điều khiển không còn mới vì khi các thiết bị, hệ thống đo lường và điều khiển được ghép nối với máy tính sẽ có thời gian thu thập và xử lý dữ liệu ngắn trong khi mức độ chính xác vẫn được đảm bảo, nhưng điều đáng quan tâm hơn cả là khả năng tự động hoá trong việc thu thập và xử lý dữ liệu. Chính vì điều này làm cho máy tính được ứng dụng trong hầu hết vào các lĩnh vực trong cuộc sống hàng ngày đặc biệt là trong l
140 trang |
Chia sẻ: huyen82 | Lượt xem: 1456 | Lượt tải: 0
Tóm tắt tài liệu Sử dụng vi mạch điều khiển AT90S8535 của hãng Atmel để thiết kế một mạch đo nhiệt độ, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
ĩnh vực công nghiệp.
Một bước tiến quan trọng trong kỹ thuật vi xử lý là sự ra đời của các bộ vi xử lý kỹ thuật số. Đây là một vi mạch điện tử có mật độ tích hợp cao bao gồm rất nhiều các mạch số có khả năng nhận, xử lý và xuất dữ liệu. Đặc biệt là quá trình xử lý dữ liệu được thực hiện theo một chương trình là một tập hợp các lệnh từ bên ngoài mà người sử dụng có thể thay đổi dễ dàng tùy thuộc vào từng ứng dụng. Do đó một bộ vi xử lý có thể thực hiện được rất nhiều các yêu cầu điều khiển khác nhau tuỳ thuộc vào nhu cầu sử dụng.
Sự ra đời của kỹ thuật vi xử lý là sự kết hợp giữa kỹ thuật phần cứng và phần mềm đã làm cho hoạt động của các mạch điện tử trở nên mềm dẻo hơn với những phần mềm rất linh hoạt mà người sử dụng có thể sửa chữa, thay đổi hoặc bổ sung làm cho ứng dụng ngày càng trở nên hoàn thiện mà không cần phải thiết kế lại toàn bộ ứng dụng.
Trong đồ án này, em sử dụng vi mạch điều khiển AT90S8535 của hãng Atmel để thiết kế một mạch đo nhiệt độ đơn giản. Đây là một bộ vi xử lý 8 bit năng lượng thấp (theo kiểu chíp CMOS) trên cơ sở cấu trúc RICS của hãng Atmel, tốc độ xử lý dữ liệu của IC AT90S8535 rất cao (xấp xỉ 8 MISP tại tần số 8MHz) cho phép hệ thống có thể được thiết kế tối ưu làm tăng tốc độ xử lý. Do đó, nó cung cấp khả năng linh hoạt rất cao trong các ứng dụng nhúng. Vì vậy, việc tìm hiểu cấu trúc và đặc tính của vi mạch điều khiển AT90S8535 có thể giúp chúng ta sử dụng vi mạch điều khiển này cho các ứng dụng cần thiết.
Em xin chân thành cảm ơn thầy Bùi Quốc Anh đã tận tình hướng dẫn để em hoàn thành đồ án này. Em cũng xin chân thành cảm ơn các anh ở trung tâm NET.JSC đã giúp đỡ em trong suốt thời gian thực hiện đồ án. Tuy nhiên, do trình độ còn nhiều hạn chế nên đồ án không thể tránh khỏi những thiếu sót, vì vậy em rất mong được sự chỉ bảo của các thầy cô cũng như của những người đi trước trong lĩnh vực này để đồ án của em hoàn thiện hơn qua đó em có thể xây dựng được những ứng dụng trong thực tế.
Chương i
Nhiệm vụ và phương hướng thực hiện
1.1. Nhiệm vụ của đồ án.
Từ mục đích tổng quát của đề tài là thiết kế và xây dựng một hệ thống đo nhiệt độ đơn giản, có thể phân tách ra thành các nhiệm vụ chính cần thực hiện như sau:
Thiết kế và xây dựng hệ thống ghép nối vi điều khiển (mC) AT90S8535 với module LCD (4x20 character), keypad (16 keys), cảm biến nhiệt LM335. Ngoài ra hệ thống còn phải có khả năng giao tiếp với máy tính (PC) qua cổng RS 232.
Hình 1.1 : Sơ đồ tổng thể của hệ thống cần thiết kế
PC
mC +
I/O port
LCD display
KeyPad
16
RS 232
L335
Thiết kế và xây dựng phần mềm điều khiển mC để thu thập dữ liệu từ cảm biến nhiệt nhiệt LM335, từ keypad hoặc từ PC. Xử lý dữ liệu nhận được để hiển thị trên LCD hoặc truyền sang PC.
Xây dựng phần mềm trên PC để có thể giao tiếp được với mC qua cổng RS 232
1.2. Phân tích nhiệm vụ.
Để có thể thiết kế và xây dựng được hệ thống như trên cần phải thực hiện các bước sau :
Nghiên cứu và tìm hiểu bộ vi xử lý AT90S8535.
Tìm hiểu sự hoạt động của module LCD và cảm biến nhiệt LM 335.
Tìm hiểu sự hoạt động và phương pháp mã hoá keypad để có thể ghép nối với mC.
Tìm hiểu phương pháp truyền thông sử dụng chuẩn RS 232.
Thiết kế sơ đồ mạch nối ghép giữa mC với LCD, keypad, IC LM335 và giữa mC với máy tính thông qua cổng RS 232.
Lập trình phần mềm nạp cho mC để thực hiện các kết nối trên.
Viết phần mềm trên PC để giao tiếp với mC qua cổng RS 232.
Lắp giáp mạch đã thiết kế, chạy kiểm thử và đánh giá kết quả.
Viết báo cáo tốt nghiệp.
1.3. Phương hướng thực hiện.
1.3.1. Lựa chọn thiết bị.
Lựa chọn vi điều khiển :
Trong thực tế có rất nhiều các họ vi xử lý khác nhau có thể sử dụng được trong ứng dụng này như họ vi điều khiển 8051 của Intel, 68hC11 của Motorola hay họ vi điều khiển 8515 của ATMEL... Tuy nhiên, trong đồ án sử dụng bộ vi xử lý AT90S8535 của ATMEL, do đây là một sản phẩm mới của hãng ATMEL nên việc tìm hiểu nó sẽ đem lại rất nhiều lợi ích trong việc thiết kế các ứng dụng đo lường và điều khiển. Về mặt cấu tạo nó cũng tương tự như bộ vi xử lý AT90S8515 đã có từ khá lâu với 4 cổng I/O lập trình được. Nhưng về mặt công dụng thì bộ vi xử lý AT90S8535 được tích hợp nhiều chức năng hơn so với bộ vi xử lý AT90S8515, đặc biệt trên mC AT90S8535 được tích hợp một bộ ADC cho phép mỗi chân của port A được sử dụng là đầu vào cho bộ ADC, làm cho việc sử dụng mC AT90S8535 trong các ứng dụng linh hoạt hơn rất nhiều so với mC AT90S8515 đang được sử dụng rộng rãi tại Việt Nam.
Thiết bị hiển thị dữ liệu :
Đối với các loại dữ liệu được hiển thị dưới dạng số thì giải pháp tối ưu là sử dụng các LED 7 thanh do loại thiết bị hiển thị này có giá thành tương đối rẻ. Tuy nhiên, do ứng dụng không chỉ hiển thị chữ số (giá trị nhiệt độ) mà còn phải hiển thị cả các ký tự trong bảng chữ cái, do đó lựa chọn thiết bị hiển thị LCD vì loại thiết bị hiển thị này có khả năng hiển thị cả chữ cái và chữ số một cách rõ nét. Mặc dù so với các loại đèn LED thì LCD có giá thành cao hơn, nhưng bù lại thiết bị hiển thị LCD có nhiều đặc tính ưu việt hơn hẳn so với các loại đèn LED. Đặc biệt, thiết bị LCD cung cấp khả năng hiển thị dữ liệu vô cùng linh hoạt do ta có thể điều khiển xuất dữ liệu một cách trực tiếp thông qua tập lệnh điều khiển của vi mạch điều khiển và bộ mã ký tự sẵn có trong CGRAM của LCD. Một điều cần quan tâm khác là thiết bị LCD tiêu tốn rất ít năng lượng.
Trên thị trường hiện nay có khá nhiều module LCD của các hãng khác nhau như Samsung, Hitachi, Motorola... với nhiều loại kích thước. Trong đồ án sử dụng module LCD có kích thước 4x20 characters với 16 chân ghép nối. Không nhất thiết phải chọn hãng cung cấp vì các module LCD đều được xây dựng theo cùng một tiêu chuẩn, do đó cách thức điều khiển và ghép nối các module LCD thông dụng hiện nay cũng tương tự nhau.
Thiết bị vào dữ liệu và điều khiển (Keypad) :
Để người sử dụng có thể giao tiếp được với hệ thống, cần phải ghép nối mC với một module keypad. Do ứng dụng có thể làm việc với cả chữ cái và chữ số nên ta sử dụng keypad loại 16 keys, trong đó mỗi một phím được thiết kế như một công tắc để có thể nhập được dữ liệu có dạng như sau :
10 chữ số trong hệ thập phân từ 0..9.
26 chữ cái la tinh từ A..Z.
Các phím điều khiển bao gồm : Send, Bspace, , , /, Clear.
Do số ký tự có thể được sử dụng cùng với các phím chức năng lớn hơn rất nhiều so với tổng số phím sẵn có trên module keypad. Vì vậy, bắt buộc phải sử dụng phương pháp Multikey, tức là sử dụng phần mềm để mỗi một phím trên module keypad có thể mã hoá được không ít hơn hai ký tự khác nhau. Bằng cách này, với keypad có 16 phím ta có thể mã hoá được toàn bộ bảng chữ cái và chữ số đồng thời vẫn có thể thực hiện được các chức năng điều khiển như trình bầy ở trên.
Giao tiếp giữa mC và PC :
Mặc dù hệ thống được thiết kế dựa trên mC AT90S8535 đã có thể làm việc độc lập trong qua trình thu thập, xử lý và hiển thị dữ liệu tới người sử dụng mà không cần có sự trợ giúp của PC. Tuy nhiên, trong hầu hết các ứng dụng đều cần phải lưu trữ lại dữ liệu mà nếu thực hiện việc này dựa trên mC AT90S8535 đòi hỏi rất nhiều kỹ thuật và chi phí. Trong khi đó, thao tác lưu trữ dữ liệu trên PC lại rất đơn giản, vì vậy giải pháp tối ưu nhất là sử dụng PC để làm nhiệm vụ phức tạp này. Vấn đề còn lại chỉ là thao tác truyền dữ liệu cần lưu trữ từ mC sang PC, việc này được thực hiện khá đơn giản vì bản thân mC AT90S8535 đã được tích hợp một bộ UART để sử dụng trong hoạt động truyền tin với các thiết bị ở xa. Như vậy, dựa vào mạch UART của mC ta có thể thực hiện truyền nhận dữ liệu với PC theo chuẩn RS 232. Một vấn đề cần quan tâm khi ghép nối mC với PC theo chuẩn RS 232 là sự tương quan về mặt điện áp tín hiệu dạng TTL của mC và điện áp tín hiệu dạng RS 232 của PC. Để thực hiện việc chuyển đổi tín hiệu dạng TTL sang dạng tín hiệu RS 232 ta sử dụng IC Max232, IC này có nhiệm vụ tạo ra tín hiệu ±10V từ mức điện áp TTL để tạo sự tương thích về mức điện áp với chuẩn RS 232.
1.3.2. Phương hướng thiết kế.
Từ sơ đồ tổng thể của hệ thống như trên hình 1.1 và từ việc lựa chọn thiết bị như trình bầy ở trên, hệ thống cần thiết kế có thể được thể hiện như trong sơ đồ hình 1.2, trong đó :
Khối LCD display : Sử dụng module LCD sẵn có trên thị trường được ghép nối với mC để hiển thị các thông tin cần thiết cho người sử dụng.
Khối Keypad : Được nối ghép với mC để người sử dụng có thể nhập dữ liệu hoặc điều khiển sự hoạt động của hệ thống. Module này được thiết kế dưới dạng các công tắc và sử dụng trực tiếp các đặc tính của các cổng I/O lập trình được của mC để thực hiện mà không cần nguồn hỗ trợ bên ngoài.
Khối LM 335 : Là một IC cảm biến nhiệt làm nhiệm vụ biến đổi nhiệt độ môi trường sang dạng điện áp để làm đầu vào cho bộ ADC của mC làm việc.
Khối Max 232 : Sử dụng IC Max 232 ghép nối trược tiếp với mC làm nhiệm vụ trao đổi thông tin giữa mC và PC theo chuẩn RS 232.
Khối nguồn : Làm nhiệm vụ biến nguồn xoay chiều 220V sang nguồn một chiều ±5V ổn định để cấp nguồn cho các khối khác hoạt động.
Hình 1.2 : Sơ đồ khối thiết kế phần cứng
Max 232
Nguồn
mC +
I/O port
LM335
Keypad
LCD display
Chương 2
Lựa chọn linh kiện thiết kế
và một số lý thuyết về chuyển đổi A/D
2.1. Lựa chọn linh kiện thiết kế.
2.1.1. Giới thiệu vi mạch điều khiển AT90S8535.
AT90S8535 là một vi mạch điều khiển năng lượng thấp 8 bit (công nghệ chíp CMOS) trên cơ sở cấu trúc RICS của hãng ATMEL, nó thuộc họ vi điều khiển AT90S/LS8535. Bằng cách thực hiện mỗi lệnh trong một đơn chu kỳ, AT90S8535 có thể đạt tới 1 MIPS cho mỗi MHz cho phép hệ thống có thể được thiết kế một cách tối ưu nhất sự tiêu thụ năng lượng làm tăng tốc độ xử lý. Về mặt cấu tạo mC này cũng tương tự như mC AT90S8515 với 4 cổng I/O lập trình được, tuy nhiên về mặt chức năng thì mC AT90S8535 được tích hợp thêm nhiều tính năng mới mà mC AT90S8515 không có. Các đặc trưng chính của mC AT90S8535 được trình bầy dưới đây :
8KB bộ nhớ chương trình
512 byte EEPROM
512 byte SRAM
32 line (4 cổng) I/O lập trình được
32 thanh ghi đa năng 8 bit
8 kênh đầu vào ADC riêng biệt với 10 bit kết quả
2 bộ Timer/Counter 8 bit với bộ đếm độc lập và chế độ so sánh
1 bộ Timer/Counter 16 bit với bộ đếm độc lập và các chế độ PWM
1 bộ UART lập trình trao đổi thông tin nối tiếp
1 bộ Watchdog Time lập trình được với bộ tạo giao động trong
1 bộ so sánh analog
1 cổng phối ghép nối tiếp thiết bị ngoại vi SPI
3 chế độ làm việc là : Idle, Power-Save và Power-down
Nguồn cung cấp từ 4.0 - 6.0V, tần số làm việc 0 - 8MHz.
Vi mạch điều khiển AT90S8535 được chế tạo theo công nghệ chíp nhớ cố định với mật độ cao. Bộ nhớ Flash ISP trên chíp cho phép bộ nhớ chương trình có thể được lập trình lại thông qua một cổng SPI phối ghép nối tiếp với thiết bị ngoại vi. Ngoài ra, mC AT90SS8535 còn hỗ trợ cho việc lập trình thông qua các công cụ pháp triển hệ thống như C, assemblers...
Vi điều khiển AT90S8535 có 4 cấu hình chân khác nhau là : PDIP (Có 40 chân), PLCC, TQFP, MLF (Có 44 chân). Sơ đồ chân của mỗi loại như sau.
Hình 2.1 : Cấu hình chân của mC AT90S8535
PDIP
PLCC
TQFP
MLF
Chức năng các chân của mC AT90S8535 như sau :
VCC : Chân cấp nguồn 5V
GND : Chân nối đất
RESET : Là đầu vào reset. Tín hiệu reset ở bên ngoài sẽ tạo ra bởi mức thấp của trở kháng trên chân Reset. Xung reset dài quá 50ns sẽ tạo ra tín hiệu reset. Xung ngắn hơn sẽ không đảm bảo phát sinh tín hiệu reset.
XTAL1 : Là một đầu vào có tác dụng đảo chiều bộ khuếch đại tạo dao động và là đầu vào của mạch điều khiển đồng hồ bên trong.
XTAL2 : Là đầu ra của tín hiệu đảo từ bộ khuếch đại tạo dao động
AVCC : Là chân cung cấp điện áp cho cổng A và bộ chuyển đổi ADC, nếu ADC không được sử dụng thì chân này phải được nối với nguồn 5V (chân VCC), nếu ADC được sử dụng thì chân này phải được nối tới nguồn 5V qua bộ lọc thông thấp.
AREF : Là đầu vào chuẩn của tín hiệu tương tự cho bộ chuyển đổi ADC. Để cho ADC hoạt động được, nguồn sử dụng cho chân này phải có phạm vị từ 2V đến AVCC.
AGND : Chân nối đất của tín hiệu analog, nếu bo mạch có một mức nối đất riêng của tín hiệu analog, thì chân này phải được nối tới mức nối đất này. Nếu không có, chân này được nối tới chân GND.
Port A (PA7..PA0) : Là một cổng vào ra hai chiều 8 bit. Các chân của cổng có thể cung cấp các trở kháng trong cho phép chọn từng bit. Đệm ra của cổng A có khả năng kéo dòng lên tới 20mA và có thể điều khiển trực tiếp sự hiển thị LED. Khi các chân PA0 đến PA7 được sử dụng như các cổng vào và ở mức thấp, chúng sẽ là đầu vào hiện thời nếu các điện trở trong được kích hoạt. Cổng A cũng có thể được sử dụng như những đầu vào analog để đưa tín hiệu tới bộ bộ chuyển đổi ADC. Các chân của cổng A ở trạng thái không xác định khi reset, ngay cả khi đồng hồ không hoạt động.
Port B (PB7..BP0) : Là một cổng vào ra hai chiều 8 bit với các trở kháng trong. Đệm ra của cổng B có khả năng kéo dòng lên tới 20mA. Khi là đầu vào, các chân của cổng B trong trạng thái trở kháng thấp sẽ là đầu vào hiện thời nếu các điện trở trong được kích hoạt. Cổng B là cổng cung cấp các chức năng khác nhau với những đặc tính đặc biệt của mC AT90S8535. Các chân của cổng B ở trạng thái không xác định khi reset, ngay cả khi đồng không hoạt động.
Port C (PC0..PC7) : Là một cổng vào ra hai chiều 8 bit với các trở kháng trong. Đệm ra của cổng C có khả năng kéo dòng lên tới 20mA. Khi là đầu vào, các chân của cổng C trong trạng thái trở kháng thấp sẽ là đầu vào hiện thời nếu các điện trở được kích hoạt. Hai chân của cổng C có thể được lựa chọn để sử dụng giống như bộ tạo dao động cho bộ Timer/Counter2. Các chân của cổng C ở trạng thái không xác định khi reset, ngay cả khi đồng không hoạt động.
Port D (PD0..PD7) : Là một cổng vào ra hai chiều 8 bit với các trở kháng trong. Đệm ra của cổng C có khả năng kéo dòng lên tới 20mA. Khi là đầu vào, các chân của cổng D trong trạng thái trở kháng thấp sẽ là đầu vào hiện thời nếu các điện trở được kích hoạt. Cổng D cũng cung cấp những chức năng có đặc tính đặc biệt của mC AT90S8535. Các chân của cổng D ở trạng thái không xác định khi reset, ngay cả khi đồng không hoạt động.
Hình 2.2 : Sơ đồ khối vi mạch điều khiển AT90S8535
2.1.1.1. Cấu trúc của vi mạch AT90S8535.
Vi mạch điều khiển AT90S8535 có những phương thức truy cập nhanh tới tâp thanh ghi đa năng bao gồm 32 thanh ghi 8 bit với thời gian truy cập trong một đơn chu kỳ đồng hồ. Điều này có nghĩa trong một đơn chu kỳ, một thao tác của bộ ALU được thực hiện sẽ lấy hai toán hạng từ hai thanh ghi trong tập thanh ghi, sau khi thao tác được thực hiện và kết qua trả sẽ được lưu trở lại tập thanh ghi trong một chu kỳ đồng hồ.
Sáu trong số 32 thanh ghi đa năng này có thể được sử dụng như 3 thanh ghi địa chỉ gián tiếp 16 bit trỏ đến không gian địa chỉ dữ liệu, làm cho phép tính địa chỉ đạt được hiệu quả cao. Một trong 3 con trỏ địa chỉ này cũng được sử dụng giống như con trỏ địa chỉ tới vùng nhớ dữ liệu cố định. Các thanh ghi địa chỉ này là các thanh ghi 16 bit X, Y, Z.
Hình 2.3 : Sơ đồ khối kiến trúc của mC AT90S8535
Bộ ALU cung cấp các chức năng tính toán số học và logic giữa các thanh ghi hoặc giữa một hằng số và một thanh ghi. Những thao tác của một thanh ghi đơn cũng được thực hiện trong bộ ALU. Sự hoạt động của ALU được phân chia làm 3 loại chính là số học, logic và các chức năng bit.
Ngoài các chức năng của thanh ghi, các chế độ đánh địa chỉ bộ nhớ thông thường cũng có thể được sử dụng trên các tập các thanh ghi. Điều này được thực hiện qua việc tập thanh ghi được gán 32 địa chỉ thấp nhất của không gian địa chỉ dữ liệu ($00..$1F), Cho phép chúng có thể được truy nhập như là là các địa chỉ nhớ bình thường.
Không gian vùng nhớ I/O bao gồm 64 địa chỉ ($20..$5F) dành cho các chức năng điều khiển thiết bị ngoại vi của mC như : Các thanh ghi điều khiển, bộ Timer/Couter, bộ chuyển đổi ADC và các chức năng I/O khác. Vùng nhớ I/O có thể được truy nhập trực tiếp hoặc gián tiếp thông qua tập các thanh ghi.
mC AT90S8535 sử dụng kiến trúc Harvard - với bộ nhớ và bus độc lập cho chương trình và dữ liệu. Bộ nhớ chương trình được thực hiện với một “pipeline” hai trạng thái. Trong khi một lệnh đang được thực hiện, lệnh tiếp theo được nạp trước từ bộ nhớ chương trình. Cách thức này cho phép các lệnh liên tiếp được thực hiện trong từng đơn chu kỳ đồng hồ. Bộ nhớ chương trình là bộ nhớ Flash cho phép nạp dữ liệu trong hệ thống.
Với những lệnh nhẩy và lệnh gọi, toàn bộ không gian địa chỉ 4K được truy nhập trực tiếp. Hầu hết các lệnh của AVR đều có độ dài 16 bit. Mỗi địa chỉ bộ nhớ chương trình bao gồm một lệnh 16 bit hoặc 32 bit.
Mỗi một module ngắt có những thanh ghi điều khiển trong không gian I/O với một bit cho phép ngắt chung được đặt trong thanh ghi trạng thái. Mỗi ngắt khác nhau có một vector ngắt độc lập trong bảng vector ngắt ở tại vị trí bắt đầu của bộ nhớ chương trình. Mỗi ngắt khác nhau đều có mức độ ưu tiên tuân theo vị trí vector ngắt của chúng. Địa chỉ của vector ngắt càng thấp, mức độ ưu tiên càng cao. Khi xẩy ra ngắt, một chương trình con phụ vụ ngắt được gọi, địa chỉ trở về PC được đẩy vào ngăn xếp. Vùng nhớ ngăn xếp được cấp phát trong vùng nhớ dữ liệu của SRAM và do đó, dung lượng của ngăn xếp bị giới hạn bởi tổng dung lượng của SRAM và cách sử dụng thông thường của SRAM. Tất cả các chương trình của người sử dụng phải được khởi đầu bằng con trỏ ngăn xếp (SP) trong thủ tục reset (trước khi các chương trình con hoặc các ngắt được thực thi). Con trỏ stack sử dụng 10 bit để truy nhập ghi/đọc trong không gian I/O. 512 byte dữ liệu SRAM có thể được truy cập dễ dàng bởi 5 chế độ địa chỉ khác nhau được cung cấp bởi mC AT90S8535.
Hình 2.4 : Bản đồ bộ nhớ của mC AT90S8535
2.1.1.2. Tập thanh ghi đa năng của mC AT90S8535.
Tất cả các thanh ghi trong tập thanh ghi của mC AT90S8535 khi thực một hiện lệnh trong tập lệnh đều có thể được truy cập trực tiếp trong một đơn chu kỳ đồng hồ. Ngoại trừ 5 lệnh trực tiếp SBCI, SUBI, CPI, ANDI, ORI giữa một hằng số và một thanh ghi và lệnh LDI sử dụng để nạp tức thì hằng dữ liệu, những lệnh này phải sử dụng các thanh ghi của nửa thứ hai trong tập thanh ghi (từ R16..R31). Các lệnh còn lại đều có thể sử dụng bất kỳ thanh ghi nào trong tập thanh ghi.
Hình 2.5 : Địa chỉ 32 thanh ghi đa năng của mC
Qua hình 2.5 có thể thấy, mỗi thanh ghi đều được gán một địa chỉ trong không gian địa chỉ dữ liệu, chúng được đặt trong 32 vị trí đầu tiên của không gian dữ liệu sử dụng. Mặc dù không được thực hiện một cách vật lý như trong SRAM, việc tổ chức bộ nhớ này cung cấp sự linh hoạt lớn trong việc truy nhập tới các thanh ghi, như các thanh ghi X, Y, Z có thể được thiết lập để trỏ tới bất kỳ thanh ghi nào trong tập thanh ghi.
Các thanh ghi từ R26..R31 được thêm vào một số chức năng nhằm mở rộng khả năng sử dụng của tập thanh ghi. Những thanh ghi này là những con trỏ địa chỉ được sử dụng trong chế độ địa chỉ gián tiếp của không gian dữ liệu. Ba thanh ghi địa chỉ gián tiếp là X, Y, Z được mô tả như trong hình 2.6 :
Hình 2.6 : Mô tả các thanh ghi địa chỉ gián tiếp X, Y, Z
Trong các chế độ địa chỉ khác nhau, các thanh ghi này có chức năng điều chỉnh linh hoạt đối với từng trường hợp, tự động tăng, giảm hoặc không đổi.
2.1.1.3. Bộ số học và Logic - ALU.
Bộ ALU của mC AT90S8535 được nối trực tiếp với 32 thanh ghi đa năng. Trong một đơn chu kỳ đồng hồ, các thao tác của ALU giữa các thanh ghi trong tập thanh ghi được thực hiện và giữa một thanh ghi với một hằng số hoặc trên một đơn thanh ghi. Các hoạt động của ALU được chia làm 3 loại chính là : số học, logic và các phép toán trên bit.
2.1.1.4. Đặc điểm các bộ nhớ trong của mC AT90S8535.
Bộ nhớ chương trình (Flash program memory) : Trong mC AT90S8535 chứa đựng 8KB bộ nhớ Flash lập trình được dùng để lưu trữ chương trình. Nó được tổ chức như một bộ nhớ 4Kx16 bit để phù hợp với sự làm việc của các lệnh có độ dài 16 hoặc 32 bit. Bộ nhớ Flash này có thể chịu được ít nhất 1000 chu kỳ ghi/xoá. Vì bộ đếm chương trình (PC) của mC AT90S8535 có độ dài 12 bit, do đó nó có thể mã hoá 4096 địa chỉ trong bộ nhớ chương trình.
Bộ nhớ SRAM : 608 vị trí địa chỉ thấp nhất trong vùng nhớ dữ liệu được dùng để địa chỉ hoá cho tập thanh ghi, bộ nhớ I/O và SRAM. 96 vị trí địa chỉ đầu tiên là của tập thanh ghi và bộ nhớ I/O, 512 vị trí địa chỉ tiếp theo là của bộ nhớ SRAM. Một địa chỉ bất kỳ trong trong không gian địa chỉ dữ liệu SRAM đều có thể được xác định thông qua 5 chế độ địa chỉ khác nhau là : trực tiếp, tương đối, gián tiếp, gián tiếp với sự giảm trước và gián tiếp với sự tăng sau. Trong tập thanh ghi, các thanh ghi từ R26 tới R31 được sử dụng như các thanh ghi con trỏ địa chỉ gián tiếp.
ở chế độ địa chỉ trực tiếp có cho phép truy cập tới toàn bộ không gian dữ liệu. Chế độ địa chỉ tương đối cho phép xác định 63 vị trí địa chỉ từ địa chỉ cơ sở cho bởi các thanh ghi Y hoặc Z. Khi sử dụng các chế độ thanh ghi gián tiếp với sự tự động giảm trước hoặc tăng sau, nội dung của các thanh ghi địa chỉ X, Y và Z đều tự động tăng hoặc giảm sau khi thực hiện. 32 thanh ghi đa năng, 64 thanh ghi I/O và 512 byte của bộ nhớ trong SRAM trong AT90S8535, tất cả đều có thể được truy nhập thông qua các chế độ địa chỉ này.
Hình 2.7 : Tổ chức bộ nhớ SRAM của mC
Bộ nhớ EEPROM : mC AT90S8535 có 512 byte bộ nhớ EEPROM, được tổ chức như một không gian dữ liệu riêng biệt cho phép mỗi byte có thể được ghi/đọc. Bộ nhớ EEPROM có thể thực hiện ít nhất 100.000 chu kỳ ghi/xoá. Sự truy nhập giữa EEPROM và mC được thực hiện thông qua các thanh ghi địa chỉ, thanh ghi dữ liệu và thanh ghi điều khiển của EEPROM, các thanh ghi này có thể được truy cập trong không gian I/O. Thời gian truy cập ghi EEPROM trong phạm vi từ 2.5 đến 4 ms, tuỳ thuộc vào điện áp trên chân VCC. EEPROM có một chức năng tự động tính thời gian cho phép phần mềm của người sử dụng kiểm tra khi byte tiếp theo có thể được ghi/đọc. Một ngắt đặc biệt kiểm tra sự sẵn sàng của EEPROM có thể được thiết lập để kích hoạt khi EEPROM sẵn sàng tiếp nhận dữ liệu mới. Để ngăn cản việc ghi EEPROM ngoài ý muốn, một quy trình ghi cụ thể phải được tuân theo. Khi đọc EEPROM, mC bị tạm dừng trong 4 chu kỳ đồng hồ trước khi lệnh tiếp theo được thực hiện. Khi ghi EEPROM, mC tạm dừng trong 2 chu kỳ đồng hồ trước khi thực hiện lệnh tiếp theo.
Thanh ghi địa chỉ EEPROM : EEARH và EEARL
Các thanh ghi địa chỉ của EEPROM (EEARH và EEARL) chỉ định địa chỉ của một byte trong không gian 512 byte EEPROM. Các byte dữ liệu của EEPROM được địa chỉ hóa từ 0 đến 511.
Thanh ghi dữ liệu EEPROM : EEDR
Trong thao tác ghi của EEPROM, thanh ghi EEDR chứa dữ liệu được ghi tới EEPROM theo địa chỉ được xác định bởi thanh ghi EEAR. Trong thao tác đọc EEPROM, thanh ghi EEDR chứa dữ liệu đọc ra từ EEPROM tại địa chỉ cho trong thanh ghi EEAR.
Thanh ghi điều khiển EEPROM : EECR
Bit 3 - EERIE : Bit cho phép sẵn sàng ngắt của EEPROM
Khi bit I trong thanh ghi SREG và bit EERIE được thiết lập, ngắt trạng thái sẵn sàng của EPROM được cho phép. Khi bị xoá ngắt bị vô hiệu hoá. Ngắt trạng thái sẵn sàng EEPROM tạo ra một ngắt cứng khi bit EEWE bị xoá.
Bit 2 - EEMWE : Bit cho phép thao tác ghi EEPROM
Bit EEMWE xác định có hay không sự thiết lập bit EEWE để gây ra thao tác ghi EEPROM. Khi bit EEMWE được thiết lập, thì sự thiết lập của bit EEWE sẽ ghi dữ liệu vào EEPROM tại địa chỉ đã lựa chọn. Nếu bit EEMWE là 0, thì sự thiết lập của bit EEWE sẽ không có kết quả. Khi bit EEMWE đã được thiết lập bởi phần mềm, phần cứng xoá bit này về 0 sau 4 chu kỳ đồng hồ.
Bit 1 - EEWE : Bit cho phép ghi EEPROM
Tín hiệu cho phép ghi EEPROM (EEWE) là một xung chọn ghi tới EEPROM. Khi địa chỉ và dữ liệu đã được thiết lập phù hợp, bit EEWE phải được thiết lập để ghi giá trị vào trong EEPROM. Bit EEEMWE phải được thiết lập khi giá trị logic 1 được ghi vào bit EEWE, nếu không thì không xẩy ra thao tác ghi EEPROM. Quy trình dưới đây phải được tuân theo khi ghi EEPROM (thứ tự của bước 2 và 3 không cần quan tâm).
1. Đợi cho đến khi bit EEWE trở về 0
2. Ghi địa chỉ mới của EEPROM tới thanh ghi địa chỉ EEPROM (tuỳ chọn)
3. Ghi dữ liệu mới vào thanh ghi EEDR (tuỳ chọn)
4. Ghi giá trị logic 1 vào bit EEMWE trong thanh ghi EECR (Để có thể ghi giá trị logic 1 vào bit EEMWE, thì bit EEWE phải được ghi là 0 trong cùng một chu kỳ đồng hồ)
5. Trong vòng 4 chu kỳ đồng hồ sau khi thiết lập bit EEMWE, ghi giá trị logic 1 tới bit EEWE.
Chú ý : Một ngắt giữa bước 4 và 5 sẽ làm lỗi chu kỳ ghi, vì bit EEMWE sẽ hết thời gian. Nếu một thủ tục ngắt truy xuất tới EEPROM trong khi một ngắt khác cũng đang truy xuất EEPROM, thì nội dung của các thanh ghi EEAR và EEDR sẽ bị thay đổi, gây lỗi ngắt truy xuất EEPROM. Để tránh những vấn đề này cần xoá các cờ ngắt chung trong thời gian thực hiện 4 bước cuối cùng. Khi thời gian truy cập ghi kết thúc (2.5ms và VCC = 5V hoặc 4ms và VCC = 2.7V), bit EEWE được xoá bởi phần cứng, Sử dụng phần mềm có thể thăm dò bít này và đợi nó trở về không trước khi thực hiện ghi byte tiếp theo. Khi bit EEWE đã được thiết lập, mC tạm dừng trong 2 chu kỳ đồng hồ trước khi lệnh tiếp theo được thực hiện.
Bit 0 - EERE : Bit cho phép đọc EEPROM
Tín hiệu cho phép đọc EEPROM là xung chọn đọc đến EEPROM. Khi địa chỉ phù hợp được thiết lập trong thanh ghi EEAR, bit EERE phải được thiết lập. Khi bit EERE bị xoá bởi phần cứng, dữ liệu yêu cầu được tìm thấy trong thanh ghi EEDR. Sự truy xuất đọc EEPROM cần một lệnh và không cần thăm dò bit EERE. Khi bit EERE đã được thiết lập, mC tạm dừng trong 4 chu kỳ đồng hồ trước khi lệnh tiếp theo được thực hiện.
Người sử dụng cần phải thăm dò bit EEWE trước khi bắt đầu thao tác đọc. Nếu dữ liệu hoặc địa chỉ mới được ghi vào các thanh ghi vào/ra của EEPROM khi một thao tác ghi đang diễn ra, thì thao tác ghi sẽ bị ngắt và kết quả không được xác định.
2.1.1.5. Các chế độ địa chỉ của mC AT90S8535.
Vi mạch điều khiển AT90S8535 hỗ trợ các chế độ địa chỉ rất mạnh và hiệu quả cao cho việc truy nhập tới bộ nhớ chương trình (bộ nhớ Flash) và bộ nhớ dữ liệu (SRAM, tập thanh ghi và bộ nhớ I/O). Dưới đây là các chế độ địa chỉ của mC AT90S8535 :
Địa chỉ trực tiếp một thanh ghi
Toán hạng được chứa trong thanh ghi d (Rd)
Địa chỉ trực tiếp hai thanh ghi
Các toán hạng được chứa trong thanh ghi r (Rr) và d (Rd).
Kết quả được lưu trong thanh ghi d (Rd)
Địa chỉ I/O trực tiếp
Toán hạng địa chỉ chứa trong 6 bit LSB của từ lệnh,
n là địa chỉ của thanh ghi nguồn hoặc đích
Địa chỉ dữ liệu trực tiếp
16 bit địa chỉ dữ liệu được chứa trong 16 bit LSB của hai từ lệnh.
Rd/Rr chỉ rõ thanh ghi nguồn hoặc thanh ghi đích.
Địa chỉ dữ liệu tương đối
Toán hạng địa chỉ là kết quả của nội dung thanh ghi Y hoặc Z
được cộng với địa chỉ chứa trong 6 bit LSB của từ lệnh (a)
Địa chỉ dữ liệu gián tiếp
Toán hạng địa chỉ là nội dung của thanh ghi X, Y hoặc Z
Địa chỉ dữ liệu gián tiếp giảm trước
Nội dung các thanh ghi X, Y, Z giảm 1 trước khi thực hiện
Toán hạng địa chỉ là nội dung đã giảm của thanh ghi X, Y, Z
Địa chỉ dữ liệu gián tiếp tăng sau
Thanh ghi X, Y hoặc Z được cộng 1 sau khi thực hiện.
Địa chỉ toán hạng là nội dung của thanh ghi X, Y hoặc Z trước khi cộng
Địa chỉ cố định khi thực hiện lệnh LPM
Địa chỉ byte cố định được xác định bởi nội dung của thanh ghi Z.
15 bit MSB lựa chọn địa chỉ từ (0 – 4K), bit LSB cho phép
chọn byte thấp nếu LSB = 0 hoặc byte cao nếu đặt LSB = 1.
Địa chỉ gián tiếp trong bộ nhớ chương trình với lệnh IJMP và ICALL
Chương trình được tiếp tục thực hiện tại địa chỉ được chứa bởi thanh ghi Z
(Bộ đếm chương trình (PC) được nạp với nội dung của thanh ghi Z)
Địa chỉ tương đối của bộ nhớ chương trình với lệnh RJMP và RCALL
Chương trình được tiếp tục thực hiện tại địa chỉ PC + k + 1
Địa chỉ tương đối k bắt đầu từ - 2048 tới 2047
2.1.1.6. Thời gian truy cập bộ nhớ và thời gian thực hiện lệnh.
mC AT90S8535 được điều khiển bởi đồng hồ hệ thống 0, được tạo trực tiếp từ đồng hồ bên ngoài của chip và không sử dụng bộ chia thời gian trong.
Hình 2.8 mô tả quá trình tìm và thực hiện lệnh song song theo cấu trúc Harvard và khái niệm tập thanh ghi truy nhập nhanh.
Hình 2.8: Quá trình tìm và thực hiện lênh song song
Hình 2.9 mô tả khái niệm thời gian thao tác trong của tập thanh ghi. Trong một đơn chu kỳ đồng hồ, một thao tác sử dụng hai toán hạng trong hai thanh ghi của ALU được thực hiện và kết quả được lưu trở lại thanh ghi đích.
Hình 2.9: Hoạt động của ALU trong đơn chu kỳ đồng hồ
Sự truy nhập vào bộ nhớ SRAM được thực hiện trong hai chu kỳ đồng hồ và được mô tả như hình dưới.
Hình 2.10 : Các chu kỳ truy cập bộ nhớ SRAM
2.1.1.7. Không gian bộ nhớ I/O.
Bảng 2.1 : Không gian I/O của mC AT90S8535
Địa chỉ I/O
(Địa chỉ SRAM)
Tên thanh
ghi/cổng
Chức năng
$3F ($5F)
SREG
Thanh ghi trạng thái
$3E ($5E)
SPH
địa chỉ byte cao của con trỏ Stack
$3D ($5D)
SPL
Địa chỉ byte thấp của con trỏ Stack
$3B ($5B)
GIMSK
Thanh ghi mặt nạ ngắt chung
$3A ($5A)
GIFR
Thanh ghi cờ ngắt chung
$39 ($59)
TIMSK
Thanh ghi mặt nạ ngắt của bộ Timer/Counter
$38 ($58)
TIFR
Thanh ghi cờ ngắt của bộ Timer/Counter
$35 ($55)
MCUCR
Thanh ghi điều khiển chung của MCU
$34 ($45)
MCUSR
Thanh ghi trạng thái chung của MCU
$33 ($53)
TCCR0
Thanh ghi điều khiển bộ Timer/Counter 0
$32 ($52)
TCNT0
8 bit dữ liệu của bộ Timer/Counter 0
$2F ($4F)
TCCR1A
Thanh ghi điều khiển A của bộ Timer/Counter 1
$2E ($4E)
TCCR1B
Thanh ghi điều khiển B của bộ Timer/Counter 1
$2D ($4D)
TCNT1H
Byte cao của bộ Timer/Counter 1
$2C ($4C)
TCNT1L
Byte thấp của bộ Timer/Counter 1
$2B ($4B)
OCR1AH
Byte cao của thanh ghi A so với đầu ra của Timer/Counter1
$2A ($4A)
OCR1AL
Byte thấp của thanh ghi A so với đầu ra của Timer/Counter1
$29 ($49)
OCR1BH
Byte cao của thanh ghi B so với đầu ra của Timer/Counter1
$28 ($48)
OCR1BL
Byte thấp của thanh ghi B so với đầu ra của Timer/Counter1
$27 ($47)
ICR1H
Thanh ghi lưu trữ Byte cao của đầu vào Timer/Counter1
$26 ($46)
ICR1L
Thanh ghi lưu trữ Byte cao đầu vào của Timer/Counter1
$25 ($45)
TCCR2
Thanh ghi điều khiển bộ Timer/Counter 2
$24 ($44)
TCNT2
8 bit dữ liệu của bộ Timer/Counter 2
$23 ($43)
OCR2
Thanh ghi so với đầu ra của bộ Timer/Counter 2
$22 ($42)
ASSR
Thanh ghi trạng thái chế độ không đồng bộ
$21 ($41)
WDTCR
Thanh ghi điều khiển mạch kiểm tra tuần tự bộ địn._.h thời gian
$1F ($3E)
EEARH
Thanh ghi địa chỉ Byte cao của EEPROM
$1E ($3E)
EEARL
Thanh ghi địa chỉ Byte thấp của EEPROM
$1D ($3D)
EEDR
Thanh ghi dữ liệu EEPROM
$1C ($3C)
EECR
Thanh ghi điều khiển EEPROM
$1B ($3B)
PORTA
Thanh ghi dữ liệu, cổng A
$1A ($3A)
DDRA
Thanh ghi điều hướng dữ liệu, cổng A
$19 ($39)
PINA
Các chân vào của cổng A
$18 ($38)
PORTB
Thanh ghi dữ liệu cổng B
$17 ($37)
DDRB
Thanh ghi điều hướng dữ liệu, cổng B
$16 ($36)
PINB
Các chân vào của cổng B
$15 ($35)
PORTC
Thanh ghi dữ liệu cổng C
$14 ($34)
DDRC
Thanh ghi điều hướng dữ liệu, cổng C
$13 ($33)
PINC
Các chân vào của cổng C
$12 ($32)
PORTD
Thanh ghi dữ liệu của cổng D
$11 ($31)
DDRD
Thanh ghi điều hưởng dữ liệu, cổng D
$10 ($30)
PIND
Các chân vào của cổng D
$0F ($2F)
SPDR
Thanh ghi dữ liệu cổng vào/ra của thiết bị ngoại vi
$0E ($2E)
SPSR
Thanh ghi trạng thái của SPI
$0D ($2D)
SPCR
Thanh ghi điều khiển SPI
$0C ($2C)
UDR
Thanh ghi dữ liệu vào/ra của bộ UART
$0B ($2B)
USR
Thanh ghi trạng thái UART
$0A ($2A)
UCR
Thanh ghi điều khiển UART
$09 ($29)
UBRR
Thanh ghi tốc độ baud của UART
$08 ($28)
ACSR
Thanh ghi điều khiển và trạng thái của mạch so sánh Analog
$07 ($27)
ADMUX
Thanh ghi lựa chọn của bộ dồn kênh ADC
$06 ($26)
ADCSR
Thanh ghi điều khiển và trạng thái của bộ ADC
$05 ($25)
ADCH
Thanh ghi dữ liệu byte cao của bộ ADC
$04 ($24)
ADCL
Thanh ghi dữ liệu byte thấp của bộ ADC
Tất cả các cổng I/O của mC AT90S8535 và các thiết bị ngoại vi đều được đặt trong gian cổng I/O. Các vị trí cổng I/O được truy nhập bởi lệnh IN và OUT truyền dữ liệu giữa 32 thanh ghi đa năng và không gian I/O. Các thanh ghi I/O có địa chỉ trong phạm vi từ $00 đến $1F có thể được truy nhập trực tiếp tới các bit bằng cách sử dụng các lệnh SBI và CBI. Trong các thanh ghi này, giá trị các bit đơn có thể được kiểm tra bằng cách sử dụng các lệnh SBIS và SBIC. Khi sử dụng các lệnh I/O cụ thể IN và OUT, các địa chỉ I/O từ $00 đến $3F phải được sử dụng. Khi xác định địa chỉ các thanh ghi I/O như địa chỉ của SRAM, phải thêm $20 vào các địa chỉ này.
Bảng 2.2 : Vị trí các bit trong các thanh ghi I/O
Address
Name
Bit 7
Bit 6
Bit 5
Bit 4
Bit 3
Bit 2
Bit 1
Bit 0
$3F ($5F)
SREG
I
T
H
S
V
N
Z
C
$3E ($5E)
SPH
-
-
-
-
-
-
SP9
SP8
$3D ($5D)
SPL
SP7
SP6
SP5
SP4
SP3
SP2
SP1
SP0
$3C ($5C)
Res
$3B ($5B)
GIMSK
INT1
INT0
-
-
-
-
-
-
$3A ($5A)
GIFR
INTF1
INTF0
$39 ($59)
TIMSK
OCIE2
TOIE2
TICIE1
OCIE1A
OCIE1B
TOIE1
-
TOIE0
$38 ($58)
TIFR
OCF2
TOV2
ICF1
OCF1A
OCF1B
TOV1
-
TOV0
$37 ($57)
Res
$36 ($56)
Res
$35 ($55)
MCUCR
-
SE
SM1
SM0
ISC11
ISC10
ISC01
ISC00
$34 ($54)
MCUSR
-
-
-
-
-
-
EXTRF
PORF
$33 ($53)
TCCR0
-
-
-
-
-
CS02
CS01
CS00
$32 ($52)
TCNT0
Timer/Counter0 (8 Bits)
$31 ($51)
Res
$30 ($50)
Res
$2F ($4F)
TCCR1A
COM1A1
COM1A0
COM1B1
COM1B0
-
-
PWM11
PWM10
$2E ($4E)
TCCR1B
ICNC1
ICES1
-
-
CTC1
CS12
CS11
CS10
$2D ($4D)
TCNT1H
Timer/Counter1 – Counter Register High Byte
$2C ($4C)
TCNT1L
Timer/Counter1 – Counter Register Low Byte
$2B ($4B)
OCR1AH
Timer/Counter1 – Output Compare Register A High Byte
$2A ($4A)
OCR1AL
Timer/Counter1 – Output Compare Register A Low Byte
$29 ($49)
OCR1BH
Timer/Counter1 – Output Compare Register B High Byte
$28 ($48)
OCR1BL
Timer/Counter1 – Output Compare Register B Low Byte
$27 ($47)
ICR1H
Timer/Counter1 – Input Capture Register High Byte
$26 ($46)
ICR1L
Timer/Counter1 – Input Capture Register Low Byte
$25 ($45)
TCCR2
-
PWM2
COM21
COM20
CTC2
CS22
CS21
CS20
$24 ($44)
TCNT2
Timer/Counter2 (8 Bits)
$23 ($43)
OCR2
Timer/Counter2 Output Compare Register
$22 ($42)
ASSR
-
-
-
-
AS2
TCN2UB
OCR2UB
TCR2UB
$21 ($41)
WDTCR
-
-
-
WDTOE
WDE
WDP2
WDP1
WDP0
$20 ($40)
Res
$1F ($3F)
EEARH
EEAR8
$1E ($3E)
EEARL
EEAR7
EEAR6
EEAR5
EEAR4
EEAR3
EEAR2
EEAR1
EEAR0
$1D ($3D)
EEDR
EEPROM Data Register
$1C ($3C)
EECR
-
-
-
-
EERIE
EEMWE
EEWE
EERE
$1B ($3B)
PORTA
PORTA7
PORTA6
PORTA5
PORTA4
PORTA3
PORTA2
PORTA1
PORTA0
$1A ($3A)
DDRA
DDA7
DDA6
DDA5
DDA4
DDA3
DDA2
DDA1
DDA0
$19 ($39)
PINA
PINA7
PINA6
PINA5
PINA4
PINA3
PINA2
PINA1
PINA0
$18 ($38)
PORTB
PORTB7
PORTB6
PORTB5
PORTB4
PORTB3
PORTB2
PORTB1
PORTB0
$17 ($37)
DDRB
DDB7
DDB6
DDB5
DDB4
DDB3
DDB2
DDB1
DDB0
$16 ($36)
PINB
PINB7
PINB6
PINB5
PINB4
PINB3
PINB2
PINB1
PINB0
$15 ($35)
PORTC
PORTC7
PORTC6
PORTC5
PORTC4
PORTC3
PORTC2
PORTC1
PORTC0
$14 ($34)
DDRC
DDC7
DDC6
DDC5
DDC4
DDC3
DDC2
DDC1
DDC0
$13 ($33)
PINC
PINC7
PINC6
PINC5
PINC4
PINC3
PINC2
PINC1
PINC0
$12 ($32)
PORTD
PORTD7
PORTD6
PORTD5
PORTD4
PORTD3
PORTD2
PORTD1
PORTD0
$11 ($31)
DDRD
DDD7
DDD6
DDD5
DDD4
DDD3
DDD2
DDD1
DDD0
$10 ($30)
PIND
PIND7
PIND6
PIND5
PIND4
PIND3
PIND2
PIND1
PIND0
$0F ($2F)
SPDR
SPI Data Register
$0E ($2E)
SPSR
SPIF
WCOL
-
-
-
-
-
-
$0D ($2D)
SPCR
SPIE
SPE
DORD
MSTR
CPOL
CPHA
SPR1
SPR0
$0C ($2C)
UDR
UART I/O Data Register
$0B ($2B)
USR
RXC
TXC
UDRE
FE
OR
-
-
-
$0A ($2A)
UCR
RXCIE
TXCIE
UDRIE
RXEN
TXEN
CHR9
RXB8
TXB8
$09 ($29)
UBRR
UART Baud Rate Register
$08 ($28)
ACSR
ACD
-
ACO
ACI
ACIE
ACIC
ACIS1
ACIS0
$07 ($27)
ADMUX
-
-
-
-
-
MUX2
MUX1
MUX0
$06 ($26)
ADCSR
ADEN
ADSC
ADFR
ADIF
ADIE
ADPS2
ADPS1
ADPS0
$05 ($25)
ADCH
-
-
-
-
-
-
ADC9
ADC8
$04 ($24)
ADCL
ADC7
ADC6
ADC5
ADC4
ADC3
ADC2
ADC1
ADC0
$03 ($20)
Res
$02 ($22)
Res
$01 ($21)
Res
$00 ($20)
Res
Res : Reserved
Một vài bit cờ trạng thái có thể được xoá bằng cách ghi trị 1 vào vị trí của nó. Chú ý đối với các lệnh CBI và SBI sẽ có tác dụng trên tất cả các bit trong thanh ghi I/O và thao tác ghi lại 1 vào bất kỳ cờ nào đã được thiết lập đồng nghĩa với việc xoá cờ đó. Tuy nhiên, các lệnh CBI và SBI chỉ làm việc với các thanh ghi có địa chỉ từ $00 đến $1F. Chức năng của mỗi bit trong các thanh ghi sẽ được giới thiệu trong từng phần có liên quan, dưới đây là hai thanh ghi chính của vi mạch điều khiển AT90S8535.
Thanh ghi trạng thái mC : SREG
Thanh ghi trạng thái (Status register) của mC AT90S8535 có địa chỉ tại vị trí $3F ($5F) trong không gian I/O được định nghĩa như sau :
Bit 7 - I : Bit cho phép ngắt chung (Global Interrupt Enable)
Bit cho phép ngắt chung phải được thiết lập để cho phép các ngắt. Sau đó, mỗi sự điều khiển ngắt cho phép riêng được thực hiện trong các thanh ghi điều khiển độc lập. Nếu bit cho phép ngắt chung bị xoá, thì không có ngắt nào được cho phép. Bit I được xoá bởi phần cứng sau khi một ngắt xảy ra và được thiết đặt bởi lệnh RETI để cho phép các ngắt tiếp theo.
Bit 6 - T : Bit lưu trữ sao chép (Bit Copy Storage)
Các lệnh sao chép bit BLD (BitLoaD) và BST (BitSTore) sử dụng bit T như là nguồn hoặc đích cho thao tác bit. Một bit của một thanh ghi trong tập thanh ghi có thể sao chép vào trong bit T bằng lệnh BST và một bit trong T có thể được sao chép vào một bit trong thanh ghi của tập thanh ghi bởi lệnh BLD.
Bit 5 - H : Bit cờ nhớ phụ (Half-carry Flag)
Cờ nhớ phụ H xác định số nhớ trong một số thao tác số học.
Bit 4 - S : Bit dấu (Sign Bit, S = N Å V)
Bit dấu S luôn là một phép logic NAND giữa cờ phủ định N và cờ tràn số bù hai V.
Bit 3 - V : Bit cờ tràn bù hai (Two’s Complement Oveflow Flag)
Cờ tràn số bù hai V hỗ trợ cho phép tính số bù hai.
Bit 2 - N : Bit cờ phủ định (Negative Flag)
Cờ phủ định N cho biết một kết quả âm từ một phép tính số học hoặc logic.
Bit 1 - Z : Bit cờ Zero (Zero Flag)
Cờ Zero Z cho biết một kết quả bằng không từ một phép tính số hoặc logic.
Bit 0 - C : Bit cờ nhớ (Carry Flag)
Cờ carry C xác định số nhớ trong một phép tính số hoặc logic.
Chú ý : Thanh ghi trạng thái không tự động được lưu và khôi phục khi tham gia vào một thủ tục ngắt hoặc khi trở về từ một thủ tục ngắt. Do đó, nó phải được thực hiện bởi phần mềm.
Thanh ghi con trỏ ngăn xếp : SP
Con trỏ ngăn xếp của mC AT90S8535 được thực hiện như hai thanh ghi 8 bit ở địa chỉ $3E($5E) và $3D($5D) trong không gian I/O. Do bộ nhớ SRAM của AT90S8535 có $25F địa chỉ, do đó con trỏ SP cần sử dụng 10 bit để xác định các vị trí địa chỉ cần thiết.
Con trỏ ngăn xếp SP trỏ tới vùng dữ liệu ngăn xếp trong SRAM nơi mà một chương trình con phuc vụ ngắt và ngắt được định vị. Không gian ngăn xếp trong vùng dữ liệu SRAM phải được khai báo trong chương trình trước bất kỳ lời gọi chương trình con nào được thực hiện hoặc bất kỳ ngắt nào được cho phép. Con trỏ ngăn xếp phải được thiết đặt ở những địa chỉ lớn hơn $60. SP giảm đi 1 byte khi dữ liệu được đẩy vào Stack bởi lệnh PUSH và nó giảm đi 2 byte khi một địa chỉ được đẩy vào Stack trong lời gọi chương trình con hoặc ngắt. SP được tăng lên 1 byte khi dữ liệu được lấy ra khỏi Stack với lệnh POP và nó được tăng 2 byte khi một địa chỉ được lấy ra từ Stack với lệnh trở về từ chương trình con RET hoặc lệnh trở về từ một ngắt RETI.
2.1.1.8. Ngắt và xử lý ngắt trong mC AT90S8535.
mC AT90S8535 cung cấp 16 nguồn gây ngắt khác nhau và một ngắt Reset. Các ngắt này và ngắt Reset có một vector chương trình độc lập trong không gian bộ nhớ chương trình. Tất cả các ngắt được gán với các bit cho phép ngắt riêng và phải được thiết lập cùng với bit I trong thanh ghi SREG để cho phép ngắt xảy ra.
Vị trí địa chỉ thấp nhất trong không gian bộ nhớ chương trình được tự động định nghĩa là địa chỉ của vector Reset, tiếp theo đó là địa chỉ của các vector ngắt khác. Danh sách đầy đủ của các vector ngắt được thể hiện trong bảng 2.3, bảng này cũng cho biết các cấp độ ưu tiên của các ngắt tuỳ theo vị trí địa chỉ của vector ngắt của nó theo nguyên tắc, địa chỉ càng thấp thì mức độ ưu tiên càng cao. RESET có mức ưu tiên cao nhất, tiếp theo là INT0 v.v...
Bảng 2.3 : Địa chỉ của các vector ngắt trong mC AT90S8535
TT
Địa chỉ
vector ngắt
Nguồn gây ngắt
Định nghĩa ngắt
1
$000
RESET
Reset và khởi động lại mạch Watchdog
2
$001
INT0
Yêu cầu ngắt từ bên ngoài cấp 0
3
$002
INT1
Yêu cầu ngắt từ bên ngoài cấp 1
4
$003
TIMER2 COMP
Ngắt thích ứng so sánh của T/C 2
5
$004
TIMER2 OVF
Ngắt tràn của T/C 2
6
$005
TIMER1 CAPT
Ngắt lưu giữ sự kiện của T/C 1
7
$006
TIMER1 COMPA
Ngắt thích ứng so sánh A của T/C 1
8
$007
TIMER1 COMPB
Ngắt thích ứng so sánh B của T/C 1
9
$008
TIMER1 OVF
Ngắt tràn của T/C 1
10
$009
TIMER0 OVF
Ngắt tràn của T/C 0
11
$00A
SPI, STC
Ngắt kết thúc truyền nối tiếp qua SPI
12
$00B
UART, RX
Ngắt kết thúc nhận dữ liệu của UART
13
$00C
UART, UDRE
Ngắt báo thanh ghi dữ liệu của UART rỗng
14
$00D
UART, TX
Ngắt hoàn thành truyền dữ liệu qua UART
15
$00E
ADC
Ngắt hoàn thành chuyển đổi ADC
16
$00F
EE_RDY
Ngắt báo EEPROM đã sẵn sàng R/W
17
$010
ANA_COMP
Ngắt so sánh độ dài tín hiệu Analog
Một chương trình bình thường có thể thiết lập cho các địa chỉ của vector Reset và các vector ngắt khác như sau :
Địa chỉ
Lệnh
Nhãn/toán hạng
Giải thích
$000
rjmp
RESET
;Điều khiển Reset
$001
rjmp
EXT_INT0
;Điều khiển IRQ0
$002
rjmp
EXT_INT1
;Điều khiển IRQ1
$003
rjmp
TIM2_COMP
;Điều khiển so sánh Timer2
$004
rjmp
TIM2_OVF
;Điều khiển tràn Timer2
$005
rjmp
TIM1_CAPT
;Điều khiển bắt sự kiện Timer1
$006
rjmp
TIM1_COMPA
;Điều khiển so sánh A của Timer1
$007
rjmp
TIM1_COMPB
;Điều khiển so sánh B của Timer1
$008
rjmp
TIM1_OVF
;Điều khiển tràn Timer1
$009
rjmp
TIM0_OVF
;Điều khiển tràn Timer0
$00a
rjmp
SPI_STC
;Điều khiển kết thúc truyền dữ liệu qua SPI
$00b
rjmp
UART_RXC
;Điều khiển kết thúc UART RX
$00c
rjmp
UART_DRE
;Điều khiển thông báo hết dữ liệu trong UDR
$00d
rjmp
UART_TXC
;Điều khiển kết thúc UART TX
$00e
rjmp
ADC
;Ngắt thông báo kết thúc chuyển đổi ADC
$00f
rjmp
EE_RDY
;EEPROM sẵn sàng
$010
rjmp
ANA_COMP
;Điều khiển bộ so sánh tín hiệu tương tự
$011 MAIN:
ldi
r16, high(RAMEND)
;Bắt đầu chương trình chính
$012
out
SPH,r16
$013
ldi
r16, low(RAMEND)
$014
out
SPL,r16
$015
xxx
...
....
....
Các nguồn Reset của mC AT90S8535.
mC AT90S8535 có 3 nguồn Reset khác nhau là : Power-on Reset (Reset khi nguồn bật), Reset ngoài và Watchdog Reset.
Power-on Reset : MCU được thiết lập lại khi điện áp cung cấp thấp hơn ngưỡng điện áp Power-on Reset (VPOT).
Reset ngoài : MCU được thiết lập lại khi một mức điện áp thấp xuất hiện trên chân RESET trong khoảng thời gian lớn hơn 50ns.
Watchdog Reset : MCU được thiết lập lại khi chu kỳ của mạch Wachdog timer kết thúc và mạch Wachdog được cho phép.
Trong thời gian Reset, tất cả các thanh ghi I/O được thiết lập lại với giá trị khởi tạo và sự thực hiện chương trình được bắt đầu từ địa chỉ $000. Lệnh đặt trong địa chỉ $000 phải là lệnh RJMP (lệnh nhảy quan hệ) để thi hành thủ tục Reset. Nếu một chương trình không cho phép bất một ngắt nào, thì các vector ngắt sẽ không được sử dụng và đoạn mã của chương trình có thể được đặt tại các vị trí này.
Thông tin về bất cứ nguồn Reset nào gây ra sự thiết lập lại MCU được thể hiện đầy đủ trong các bit của thanh ghi trạng thái MCU - MCUSR.
Thanh ghi trạng thái MCU : MCUSR
Bit 7... 2 : Ressered bits
Bit 1 - EXTRF : Bit cờ Reset từ bên ngoài (EXTernal Reset Flag)
Sau một tín hiệu Reset Power-on, bit này không được xác định (X). Nó chỉ có thể được thiết lập bởi một tín hiệu reset từ bên ngoài. Một tín hiệu Reset Watchdog sẽ không thay đổi giá trị của bit này. Bit này được xoá bằng cách ghi giá trị logic 0 vào bit.
Bit 0 - PORF : Bit cờ Reset Power-on (Power-On Reset Flag)
Bit này chỉ được thiết lập bởi một tín hiệu Reset Power-on. Một tín hiệu Reset Watchdog hoặc tín hiệu Reset từ bên ngoài sẽ không làm thay đổi giá trị của bit này. Bit được xoá bằng cách ghi giá trị 0 vào bit.
Bảng 2. 4 : Giá trị của các bit EXTRF và PORF sau Reset
Nguồn Reset
EXTRF
PORF
Power-on Reset
Không thay đổi
1
External Reset
1
Không thay đổi
Watchdog Reset
Không thay đổi
Không thay đổi
Có thể sử dụng các giá trị của các bít này để xác định một điều kiện gây ra Reset. Đối với phần mềm cần phải xoá cả hai bit PORF và EXTRF càng sớm càng tốt trong chương trình. Kiểm tra giá trị của các bit PORF và EXTR trước khi các bit được xoá. Nếu bit được xoá trước khi xuất hiện một tín hiệu Reset từ bên ngoài hoặc của Watchdog, thì nguồn gốc của ngắt có thể được tìm thấy bằng cách sử dụng bảng 2.5.
Bảng 2.5 : Xác định nguồn Reset
EXTRF
PORF
Nguồn Reset
0
0
Watchdog Reset
0
1
Power-on Reset
1
0
External Reset
1
1
Power-on Reset
Xử lý ngắt của mC AT90S8535
Vi mạch điều khiển AT90S8535 có hai thanh ghi điều khiển mặt nạ ngắt 8 bit là : Thanh ghi mặt nạ ngắt chung - GIMSK (General Interrupt Mask register) và thanh ghi mặt nạ ngắt của các mạch Timer/Counter – TISMK (Timer/Counter Interrupt Mask register).
Khi xẩy ra một ngắt, bit cho phép ngắt chung I bị xoá và tất cả các ngắt bị cấm. Sử dụng phần mềm có thể thiết lập cho bit I để cho phép các ngắt đang bị che. Bit I được lập sau khi thực hiện lệnh trở về từ ngắt - RETI.
Khi bộ đếm chương trình PC trỏ tới một vector ngắt hiện tại để thực hiện chương trình con phục vu ngắt, phần cứng sẽ xoá cờ ngắt tương ứng với ngắt pháp sinh. Một vài cờ ngắt cũng có thể được xoá bằng cách ghi giá trị logic 1 vào vị trí bit cờ đó. Nếu một điều khiện ngắt xẩy ra khi bit cho phép ngắt tương ứng bị xoá, thì cờ ngắt sẽ được thiết lập và được nhớ cho đến khi ngắt đó được cho phép hoặc cờ được xoá bởi phần mềm.
Nếu một hoặc nhiều điều kiện ngắt xẩy ra khi bit cho phép ngắt chung bị xoá, các cờ ngắt tương ứng sẽ được thiết lập và được nhớ cho đến khi bit cho phép ngắt chung được thiết lập và các ngắt sẽ được thực hiện tuỳ theo cấp ưu tiên của mỗi ngắt.
Chú ý : Mức ngắt ngoài không có cờ và sẽ chỉ được nhớ lâu bằng điều kiện ngắt tích cực. Ngoài ra, thanh ghi trạng thái SREG sẽ không tự động lưu lại khi tham gia một ngắt và khôi phụ lại khi trở về từ chương trình con phục vụ ngắt, do đó nó phải được điều khiển bằng phần mềm.
Các thanh ghi điều khiển ngắt của mC AT90S8535
Thanh ghi mặt nạ ngắt chung : GIMSK (General Interrupt Mask)
Bit 7 - INT1 : Bit cho phép ngắt ngoài mức 1 (External Interrupt Request 1 Enable)
Khi bit INT1 được thiết lập và bit I trong thanh ghi trạng thái SREG được thiết lập, thì chân yêu cầu ngắt mức 1 từ bên ngoài được cho phép. Các bit ISC11 và ISC10 trong thanh ghi điều khiển chung MCUCR sẽ xác định ngắt từ bên ngoài được kích hoạt theo sườn lên hay sườn xuống hoặc theo mức nhận biết của tín hiệu trên chân INT1. Sự kích hoạt trên chân này sẽ gây ra một yêu cầu ngắt cho dù chân INT1 được cấu hình như một đầu ra. Ngắt tương ứng của một yêu cầu ngắt ngoài mức 1 được thực hiện từ địa chỉ $002 trong bộ nhớ chương trình.
Bit 6 - INT0 : Bit cho phép ngắt ngoài mức 0 (External Interrupt Request 0 Enable)
Khi bit INT0 và bit I trong thanh ghi trạng thái SREG được thiết lập, thì chân yêu cầu ngắt mức 0 từ bên ngoài được cho phép. Các bit ISC01 và ISC00 trong thanh ghi điều khiển chung MCUCR sẽ xác định ngắt từ bên ngoài được kích hoạt theo sườn lên hay sườn xuống hoặc theo mức nhận biết của tín hiệu trên chân INT0. Sự kích hoạt trên chân này sẽ gây ra một yêu cầu ngắt cho dù chân INT0 được cấu hình như một đầu ra. Ngắt tương ứng của một yêu cầu ngắt ngoài mức 0 được thực hiện từ địa chỉ $001 trong bộ nhớ chương trình.
Bit 5 .. 0 : Reserved bits.
Thanh ghi cờ ngắt chung : GIFR (General Interrupt Flag Register)
Bit 7- INTF1 : Bit cờ ngắt ngoài mức 1 (External Interrupt Flag 1)
Khi một tín hiệu theo sườn hoặc một sự thay đổi mức logic trên chân INT1 sẽ gây ra một yêu cầu ngắt, bit INTF1 được thiếp lập. Cờ này luôn được xoá khi chân này được thiết lập cho các ngắt có mức yêu tiên thấp, do đó trạng thái của một ngắt có mức ưu tiên thấp có thể được xác định bằng cách đọc bit này.
Nếu bit I trong thanh ghi trạng thái SREG và bit INT1 trong thanh ghi mặt nạ ngắt chung GIMSK được thiết lập, MCU sẽ nhẩy tới địa chỉ ngắt $002. Do ngắt được tác động bởi tín hiệu sườn và sự thay đổi mức logic, cờ này được xoá khi thủ tục ngắt được thực hiện, nó cũng có thể được xoá bởi việc ghi giá trị logic 1 vào vị trí của cờ.
Bit 6 - INTF0 : Bit cờ ngắt ngoài mức 0 (External Interrupt Flag 0)
Khi một tín hiệu sườn hoặc một sự thay đổi logic trên chân INT0 gây ra một yêu cầu ngắt, bit INTF0 được thiếp lập. Cờ này luôn được xoá (0) khi chân này được đặt cấu hình cho các ngắt có mức ưu tiên thấp, như vậy trạng thái của một ngắt có mức ưu tiên thấp có thể được xác định bằng cách đọc bit này.
Nếu bit I trong thanh ghi trạng thái SREG và bit INT1 trong thanh ghi mặt nạ ngắt chung GIMSK được thiết lập, MCU sẽ nhẩy tới địa chỉ ngắt $001. Do ngắt được tác động bởi tín hiệu sườn và sự thay đổi mức logic, cờ này được xoá khi thủ tục ngắt được thực hiện, nó cũng có thể được xoá bởi việc ghi giá trị logic 1 vào vị trí của cờ.
Thanh ghi mặt nạ ngắt của các bộ Timer/Counter : TIMSK
Bit 7 - OCIE2 : Bit cho phép ngắt so sánh bằng T/C2 (Timer/Counter2 Output Compare Match Interrupt Enable)
Khi bit OCIE2 được thiết lập và bit I trong thanh ghi trạng thái (SREG) được thiết lập, ngắt so sánh bằng T/C2 được cho phép. Ngắt tương ứng tại địa chỉ $003 được thực hiện nếu xuất hiện một tín hiệu so sánh bằng trong T/C2 (tức là, khi bit OFC2 được thiết lập trong thanh ghi cờ ngắt T/C [TIFR]).
Bit 6 - TOIE2 : Bit cho phép ngắt tràn T/C2 (Timer/Counter2 Overflow Interrupt Enable)
Khi bit TOIE2 được thiết lập và bit I trong thanh ghi trạng thái (SREG) được thiết lập, ngắt tràn T/C2 được cho phép. Ngắt tương ứng tại địa chỉ $004 được thực hiện nếu xuất hiện một tín hiệu tràn trong T/C2 (tức là, khi bit TOV2 được thiết lập trong thanh ghi cờ ngắt T/C [TIFR]).
Bit 5 - TICIE1 : Bit cho phép ngắt bắt sự kiện vào của T/C1 (Timer/Counter1 Input Capture Interrup Enable)
Khi bit TICIE1 được thiết lập và bit I trong thanh ghi trạng thái (SREG) được thiết lập, ngắt bắt sự kiện vào của T/C1 được cho phép. Ngắt tương ứng tại đại chỉ $005 được thực hiện nếu xuất hiện một sự kiện gây ra sự bắt tín hiệu trên chân 20, PD6 (ICP) (tức là, khi bit ICF1 được thiết lập trong thanh ghi cờ ngắt T/C [TIFR]).
Bit 4 - OCIE1A : Bit cho phép ngắt so sánh bằng A của T/C1 (Timer/Counter1 Output CompareA Match Interrupt Enable)
Khi bit OCIE1A được thiết lập và bit I trong thanh ghi trạng thái được thiết lập, ngắt so sánh bằng A của T/C1 được cho phép. Ngắt tương ứng tại đại chỉ $006 được thực hiện nếu xuất hiện một tín hiệu so sánh bằng A trong T/C1. (tức là, khi bit OCF1A được thiết lập trong thanh ghi cờ ngắt T/C [TIFR]).
Bit 3 - OCIE1A : Bit cho phép ngắt so sánh bằng B của T/C1 (Timer/Counter1 Output CompareB Match Interrupt Enable)
Khi bit OCIE1B được thiết lập và bit I trong thanh ghi trạng thái được thiết lập, ngắt so sánh bằng B của T/C1 được cho phép. Ngắt tương ứng tại địa chỉ $007 được thực hiện nếu xuất hiện một tín hiệu so sánh bằnh B trong T/C1. (tức là, khi bit OCF1B được thiết lập trong thanh ghi cờ ngắt T/C [TIFR]).
Bit 2 - TOIE1 : Bit cho phép ngắt tràn của T/C1 (Timer/Counter1 Overflow Interrupt Enable)
Khi bit TOIE1 được thiết lập và bit I trong thanh ghi trạng thái (SREG) được thiết lập, ngắt tràn T/C1 được cho phép. Ngắt tương ứng tại đại chỉ $008 được thực hiện nếu xuất hiện một tín hiệu tràn trong T/C1 (tức là, khi bit TOV1 được thiết lập trong thanh ghi cờ ngắt T/C [TIFR]).
Bit 1: Không sử dụng
Bit 0 - TOIE0 : Bit cho phép ngắt tràn của T/C0 (Timer/Counter0 Overflow Interrupt Enable)
Khi bit TOIE0 được thiết lập và bit I trong thanh ghi trạng thái (SREG) được thiết lập, ngắt tràn T/C0 được cho phép. Ngắt tương ứng tại đại chỉ $009 được thực hiện nếu xuất hiện một tín hiệu tràn trong T/C0 (tức là, khi bit TOV0 được thiết lập trong thanh ghi cờ ngắt T/C [TIFR]).
Thanh ghi cờ ngắt của các bộ Timer/Counter : TIFR (Timer/Counter Interrupt Flag)
Bit 7 - OFC2 : Bit cờ so sánh đầu ra của T/C2 (Output compare Flag2)
Bit OCF2 được thiết lập khi xuất hiện tín hiệu so sánh bằng giữa bộ T/C2 và dữ liệu trong OCR2 (Thanh ghi so sánh đầu ra của T/C 2). OCF2 được xoá bằng phần cứng khi thực hiện chương trình điều khiển vector ngắt tương ứng. Bit OCF2 có thể được xoá bằng cách ghi giá trị logic 1 vào cờ này. Khi bit I trong thanh ghi trạng thái SREG và bit OCIE (T/C2 compare Match Interupt Enable) và bit OCF2 được thiết lập, ngắt thích ứng so sánh của T/C2 được thực hiện.
Bit 6 - TOV2 : Bit cờ tràn của T/C2 (Timer/Counter2 Overflow Flag)
Bit TOV2 được thiết lập khi xuất hiện một tín hiệu tràn trong T/C2. Bit TOV2 được xoá bởi phần cứng khi thực hiện chương trình điều khiển vector ngắt tương ứng. Một cách khác, bit TOV2 có thể được xoá bằng cách ghi giá trị 1 vào bit cờ này. Khi bit I trong thanh ghi trạng thái SREG và bit TOIE2 (T/C2 Overflow Interupt Enable) và bit TOV2 được thiết lập, ngắt tràn của T/C2 được thực hiện. Trong chế độ PWM, bit này được thiết lập khi bộ T/C1 bắt đầu đếm từ giá trị $0000
Bit 5 - ICF1 : Cờ bắt tín hiệu vào T/C1 (Input Capture Flag1)
Bit ICF1 được thiết lập để dựng cờ cho phép lưu giữ một sự kiện đầu vào, và cho biết giá trị của T/C1 đã được chuyển đến thanh ghi bắt tín hiệu vào (ICR1). Bit ICF1 được xoá bởi phần cứng khi thực hiện chương trình điều khiển vector ngắt tương ứng. Một cách khác, bit ICF1 có thể được xoá bằng cách ghi giá trị 1 vào bit cờ này. Khi bit I trong thanh ghi trạng thái SREG, bit TICIE1 (Timer/Counter1 Input Capture Interrupt Enable) và bit ICF1 được thiết lập, ngắt bắt lưu giữ đầu vào T/C1 được thực hiện.
Bit 4 - OCF1A : Bit cờ so sánh A đầu ra của T/C1 (Output Compare Flag 1A)
Bit OCF1A được thiết lập khi xuất hiện tín hiệu so sánh bằng giữa T/C1 và dữ liệu trong OCR1A (Output Compare Register 1A). Bit OCF1A được xoá bởi phần cứng khi thực hiện chương trình điều khiển vector ngắt tương ứng. Cũng có thể xoá bit OCF1A bằng cách ghi giá trị 1 vào vị trí cờ này. Khi bit I trong thanh ghi trạng thái SREG, bit OCIE1A (Timer/Counter1 Compare Match InterruptA Enable) và bit OCF1A được thiết lập, ngắt so sánh bằng A của T/C1 được thực hiện.
Bit 3 - OCF1B : Bit cờ so sánh B đầu ra của T/C1 (Output Compare Flag 1B)
Bit OCF1B được thiết lập khi xuất hiện tín hiệu so sánh bằng giữa T/C1 và dữ liệu trong OCR1B (Output Compare Register 1B). Bit OCF1B được xoá bởi phần cứng khi thực hiện chương trình điều khiển vector ngắt tương ứng. Cũng có thể xoá bit OCF1B bằng cách ghi giá trị 1 vào vị trí cờ này. Khi bit I trong thanh ghi trạng thái SREG, bit OCIE1B (Timer/Counter1 Compare Match InterruptB Enable) và bit OCF1B được thiết lập, ngắt thích ứng so sánh B của T/C1 được thực hiện.
Bit 2 - TOV1 : Bit cờ tràn của T/C1 (Timer/Counter1 Overflow Flag)
Bit TOV1 được thiết lập khi xuất hiện một tín hiệu tràn trong T/C1. Bit TOV1 được xoá bởi phần cứng khi thực hiện chương trình điều khiển vector ngắt tương ứng. Một cách khác, bit TOV1 có thể được xoá bằng cách ghi giá trị 1 vào bit cờ này. Khi bit I trong thanh ghi trạng thái SREG, bit TOIE1 (Timer/Counter1 Overflow Interrupt Enable) và bit TOV1 được thiết lập, ngắt tràn của T/C1 được thực hiện. Trong chế độ PWM, bit này được thiết lập khi bộ T/C1 bắt đầu đếm từ giá trị $0000.
Bit 1 : Không sử dụng
Bit 0 - TOV0 : Bit cờ tràn T/C0 (Timer/Counter0 Overflow Flag)
Bit TOV0 được thiết lập khi xuất hiện một tín hiệu tràn trong T/C0. Bit TOV0 được xoá bởi phần cứng khi thực hiện chương trình điều khiển vector ngắt tương ứng. Một cách khác, bit TOV0 có thể được xoá bằng cách ghi giá trị 1 vào bit cờ này. Khi bit I trong thanh ghi trạng thái SREG, bit TOIE0 (Timer/Counter0 Overflow Interrupt Enable) và bit TOV0 được thiết lập, ngắt tràn của T/C0 được thực hiện. Trong chế độ PWM, bit này được thiết lập khi bộ T/C1 bắt đầu đếm từ giá trị $0000.
Các ngắt ngoài của mC AT90S8535
Các ngắt ngoài của mC AT90S8535 được gây ra bởi sự thay đổi tín hiệu trên các chân INT1 và INT0. Có thể thấy rằng, nếu được cho phép các ngắt ngoài sẽ xảy ra cho dù các chân INT1/INT0 được thiết lập như là các đầu ra. Đặc điểm này cung cấp một cách tạo ra ngắt bằng phần mền. Các ngắt ngoài có thể được tạo ra khi xuất hiện sườn xuống hoặc sườn lên hay mức thấp của tín hiệu. Khi ngắt ngoài được cho phép và được thiết lập điều kiện kích hoạt theo mức, ngắt sẽ xảy ra trong khoảng thời gian chân được giữ ở mức thấp. Các ngắt ngoài được thiết lập như mô tả trong thanh ghi điều khiển MCU (MCUCR).
Thanh ghi điều khiển MCU : MCUCR (MCU Control Register)
Thanh ghi MCUCR chứa các bit điều khiển dành cho các chức năng chung của MCU.
Bit 7 : Không sử dụng.
Bit 6 - SE : Bit cho phép nghỉ (Sleep Enable)
Bit SE phải được thiết lập để đưa MCU vào chế độ nghỉ khi lệnh SLEEP được thực hiện. Để tránh đưa MCU vào chế độ nghỉ ngoài ý muốn, chỉ nên thiết lập bit SE trước khi thực hiện lệnh SLEEP.
Bit 4,5 - SM1/SM0 : Các bit chọn chế độ nghỉ (Sleep Mode Select Bits 0 and 1)
Các bit này cho phép chọn người lập trình chọn một trong 3 chế độ nghỉ có sẵn của mC AT90S8535 như trong bảng 2.6.
Bảng 2.6 : Lựa chọn các chế độ nghỉ của mCAT90S8535
SM1
SM0
Sleep Mode
0
0
Idle
0
1
Không sử dụng
1
0
Power - down
1
1
Power - Save
Bit 3,2 - ISC11,ISC10 : Các bit điều khiển nhận biết ngắt mức 1 (Interrupt Sense Control 1 Bits 1 and 0)
Ngắt ngoài mức 1 được kích hoạt bởi chân yêu cầu ngắt ngoài INT1 nếu bit I trong thanh ghi trạng thái SREG và mặt nạ ngắt tương ứng trong thanh ghi mặt nạ ngắt GIMSK được thiết lập. Các sườn và mức kích hoạt ngắt trên chân yêu cầu ngắt ngoài INT1 được định nghĩa trong bảng 2.7.
Bảng 2.7 : Điều khiển nhận biết ngắt ngoài mức 1
ISC11
ISC10
Mô tả
0
0
Mức thấp trên chân INT1 phát sinh một yêu cầu ngắt
0
1
Dự trữ (Reserved)
1
0
Yêu cầu phát sinh ngắt trên chân INT1 theo sườn xuống
1
1
Yêu cầu ngắt phát sinh trên chân INT1 theo sườn lên
Giá trị trên chân INT được lấy mẫu trước khi kiểm tra các sườn. Nếu yêu cầu ngắt tác động theo sườn được lựa chọn, thì những xung cuối cùng kéo dài hơn một chu kỳ đồng hồ CPU sẽ phát sinh một ngắt. Xung ngắn sẽ không đảm bảo phát sinh ngắt. Nếu yêu cầu ngắt tác dộng theo mức thấp được lựa chọn, thì mức thấp phải được giữ cho đến khi hoàn thành lệnh đang thực hiện mới gây ra yêu cầu ngắt. Nếu được cho phép, một ngắt tác động theo mức sẽ phát sinh một yêu cầu ngắt trong khoảng thời gian chân INT1 được giữ ở mức thấp.
Bit 1,0 - ISCO1,ISCO0 : Các bit điều khiển nhận biết ngắt mức 0 (Interrupt Sense Control 1 Bits 1 and 0)
Ngắt ngoài mức 0 được kích hoạt bởi chân yêu cầu ngắt ngoài INT0 nếu bit I trong thanh ghi trạng thái SREG và mặt nạ ngắt tương ứng trong thanh ghi mặt nạ ngắt GIMSK được thiết lập. Các sườn và mức kích hoạt ngắt trên chân yêu cầu ngắt ngoài INT0 được định nghĩa trong bảng 2.8.
Bảng 2.8 : Điều khiển nhận biết ngắt ngoài mức 0
ISC01
ISC00
Mô tả
0
0
Mức thấp của chân INT0 phát sinh một yêu cầu ngắt
0
1
Dự trữ (Reserved)
1
0
Yêu cầu phát sinh ngắt của chân INT0 theo sườn xuống
1
1
Yêu cầu ngắt của chân INT0 phát sinh ngắt theo sườn lên
Giá trị trên chân INT được lấy mẫu trước khi kiểm tra các sườn. Nếu yêu cầu ngắt tác động theo sườn được lựa chọn, thì những xung cuối cùng kéo dài hơn một chu kỳ đồng hồ CPU sẽ phát sinh một ngắt. Xung ngắn sẽ không đảm bảo phát sinh ngắt. Nếu yêu cầu ngắt tác động theo mức thấp được lựa chọn, thì mức thấp phải được giữ cho đến khi hoàn thành lệnh đang thực hiện mới gây ra yêu cầu ngắt. Nếu được cho phép, một ngắt tác động theo mức sẽ phát sinh một yêu cầu ngắt trong khoảng thời gian chân INT0 được giữ ở mức thấp.
Thời gian hồi đáp ngắt (Interrup response time)
Thời gian hồi đáp thực hiện ngắt của tất cả các ngắt được cho phép của mC AT90S8535 tối thiểu là 4 chu kỳ đồng hồ. Bốn chu kỳ đồng hồ sau khi cờ ngắt được thiết lập, chương trình con xử lý ngắt hiện thời mới được thực hiện, trong khoảng thời gian 4 chu kỳ đồng hồ này, bộ đếm chương trình PC (2 bytes) được đẩy vào đỉnh ngăn xếp và con trỏ stack SP giảm 2. Một lệnh nhảy quan hệ nhảy tới chương trình con phục vụ ngắt và lệnh n._.iệu được lưu trữ
5.3. Nhận xét và đánh giá.
Nhìn chung, phần mềm trên máy tính và chương trình điều khiển mC chạy thử nghiệp cho kết quả tốt. Hai chương trình này hoạt động một cách đồng bộ trong việc truyền nhận dữ liệu, do đó kết nối thành một hệ thống hoàn chỉnh. Phần mềm trên PC không chỉ biểu diễn được các giá trị nhiệt độ dạng đồ thị theo thời gian mà còn có thể lưu trữ các thông tin cần thiết trong quá trình thu thập dữ liệu và các thông tin lưu trữ này có thể được xem lại khi cần thiết. Kết quả ADC được truyền sang máy tính để máy tính thực hiện các thao tác phức tạp như dựng đồ thị và lưu trữ, điều này giúp cho công việc lập trình trở nên đơn giản và đỡ tốn thời gian cũng như chi phí so với việc thực hiện công việc này trên mC.
Về cơ bản mạch phần cứng đã được lắp rắp hoàn chỉnh và chạy thử cho kết quả tốt đáp ứng được yêu cầu đề ra của đồ án. Song do điều kiện về thời gian nên không kịp thiết kế mạch in theo kỹ thuật có nên cũng phần nào ảnh hưởng đến chất lượng kỹ thuật cũng như chất lượng về mặt cảm quan của sản phẩm. Ngoài ra, do kinh nghiệm trong việc thiết kế phần cứng còn nhiều hạn chế nên việc ghép nối giữa mC với các modul khác qua các cổng I/O của mC AT90S8535 chưa thực sự tối ưu.
Hoạt động trao đổi dữ liệu dữ máy tính và RTU được thực hiện dựa trên phương pháp truyền thông nối tiếp theo chuẩn RS232, do đó tốc độ truyền dữ liệu bị hạn chế. Mặt khác, do dữ liệu được truyền trực tiếp từ mC tới máy tính mà không qua Modem nên khoảng cách giữa máy tính vào RTU cũng bị giới hạn.
Mặc dù hệ thống cần thiết kế đã hoàn thành, tuy nhiên có thể thấy nó có một số hạn chế trong đó hạn chế lớn nhất là khả ứng dụng trong thực tế của sản phẩm không cao. Nên mặc dù việc thay đổi đại lượng biến đổi ở đầu vào của bộ chuyển đổi A/D trong hệ thống để phù hợp với các ứng dụng thực tế không đòi hỏi nhiều chi phí và thời gian thiết kế lại mạch, nhưng chương trình điều khiển mC và chương trình trên PC cần có những thay đổi thích hợp.
Kết luận
Trong bản báo có đồ án tốt nghiệp này, em đã nêu ra một số lý thuyết sử dụng để thiết kế và quy trình công việc phải thực hiện trong thực tế. Nói chung công việc đã hoàn thành theo đúng tiến độ đề ra, tuy nhiên do năng lực cũng như kinh nghiệm về lĩnh vực công nghệ phần cứng còn nhiều yếu kém nên đồ án không thể tránh được những thiếu sót. Tuy nhiên, trong thời gian thực hiện đồ án, em cũng đã rút ra được một số kinh nghiệm quý báu, điều này rất cần thiết cho em khi ra làm việc thực tế.
Nói chung, hệ thống cần thiết kế đã hoàn thành và chạy thử nghiệp cho kết quả tốt. Do mục đích của đồ án là tìm hiểu nguyên lý hoạt động và thực hiện điều khiển một bộ vi xử lý AT90S8535, đây là một mC còn rất mới của hãng ATMEL nên sản phẩm được thiết kế hầu như không được ứng dụng trong thực tế mà chỉ mang tính thử nghiệm. Tuy nhiên, thông qua quá trình tìm hiệu và sử mC AT90S8535 để thiết kế, có thể giúp em hiểu phần nào về công nghệ phần cứng ứng dụng trong các lĩnh vực khác nhau trong cuộc sống. Sau khi hoàn thành đồ án, em sẽ tìm hiểu thêm các kiến thức về kỹ thuật phối ghép để có thể thực hiện thiết kế những mạch điện tử có khả năng ứng dụng cao trong thực tế.
Một lần nữa em xin chân thành cảm ơn thầy giáo hướng dẫn Bùi Quốc Anh đã tận tình hướng dẫn và giúp đỡ em rất nhiều trong suốt thời gian thực hiện đồ án này. Em cũng xin chân thành sự giúp đỡ của các anh làm việc ở trung tâm NET.JSC đã giúp đỡ em hoàn thành bản đồ án này.
Phụ lục
Chương trình điều khiển mC AT90S8535
.nolist
.include "\AVR\AvrAssembler\Appnotes\8535def.inc"
.list
;Defined register
.def Save = r1
.def HPtrTx = r2
.def LPtrTx = r3
.def HPtrRxL = r4
.def HPtrRxH = r5
.def ShowRxL = r6
.def ShowRxH = r7
.def ResultADCL = r8
.def ResultADCH = r9
.def Implement = r10
.def StatementReg = r13
.def TimeOut = r16
.def Temp = r17
.def Instr = r18
.def Data = r19
.def AddrShow = r20
.def KeyPress = r21
.def CtrlReg = r22
.def OldKey = r23
.def Position = r24
.def PositionH = r25
;Defined control constant
.equ RS = 6 ;RS signal
.equ RW = 5 ;RW signal
.equ E = 4 ;Enable signal
;Control KeyPad
.equ Row1 = 7
.equ Row2 = 6
.equ Row3 = 5
.equ Row4 = 4
.equ Col1 = 0
.equ Col2 = 1
.equ Col3 = 2
.equ Col4 = 3
.equ INTRATE = 4 ;INT rate keypress
.equ EnImpKey = 1
.equ ImpKey = 0
.equ EnSelectTxRx = 4
.equ SelectTxRx = 2
.equ EnShowRxBuff = 8
.equ ShowRxBuff = 3
.equ EnInstroduc = 2
.equ Instroduc = 1
.equ EnOnKeyPress = $80
.equ OnKeyPress = 7
.equ PressOne = 0
.equ PressTwo = $10
.equ PressThree = $20
.equ PressFour = $30
.equ CR = $0D
.equ Statement = $23 ;Ascii '#'
.equ EnShow_CK = $01 ;Show cencius
.equ Show_CK = 0
.equ EnShowSymbolTempr = $02 ;Show symbol Tempr
.equ ShowSymbolTempr = 1
.equ EnCencius = $01 ;Display temprature for cencius
;Macro get address of last char in string
.macro Get_Addr_Char
ldi Position,@0 ;Last position show @0
ldi Instr,@1 ;Display on line @1
ldi Temp,@2 ;Total char of string @2
ldi ZL,LOW(@3<<1) ;Name of string @3
ldi ZH,HIGH(@3<<1)
adiw ZL,@2-1 ;Get address of last char in string
.endmacro
;Macro get address of string
.macro Get_Addr_String
ldi Instr,@0 ;Position show @0
ldi @1,LOW(@3<<1) ;Low pointer @1, name's string @3
ldi @2,HIGH(@3<<1) ;High pointer @2
ldi Temp,@4 ;Total char @4
.endmacro
;Macro set first ascii code for keypress
.macro Set_First_Ascii
ldi Data,@0 ;Ascii of number @0
ldi Position,@1 ;Ascii of prechar @1
.endmacro
;Macro get position to display for char
.macro Get_Position
cpi @0,@1 ;Position to show @0,
breq GetPos ;Position last @1
inc @0
GetPos: mov Instr,@0
.endmacro
;Create buffer for RxD and TxD
.dseg
.org $0060
TxBuff : .byte 128 ;Buffer send
RxBuff : .byte 128 ;Buffer receive
;Defined constant of buffer
.equ EndTxBuff = LOW(TxBuff)+127
.equ StartTxBuff = LOW(TxBuff)-1
.equ EndRxBuffL = $62
.equ EndRxBuffH = $01
.equ StartRxBuff = LOW(RxBuff)
.cseg
.org $000
rjmp RESET
rjmp SCAN_CODE
.org $006
rjmp ENABLE_ADC ;Enable ADC
.org $008
rjmp KEY_RATE ;INT KEYRATE
.org $00B
rjmp Rx_COMPELET
.org $00E
rjmp END_CONVERT ;End convert ADC
.org $011
PrefA1 : .db "TRUONG DHBK HA NOI"
PrefA2 : .db "KHOA CNTT"
PrefA3 : .db "DO AN TOT NGHIEP"
PrefA4 : .db "NG.CUU IC AT90S8535"
PrefB1 : .db "SINH VIEN THUC HIEN"
PrefB2 : .db "VU TAN MANH"
PrefB3 : .db "GIAO VIEN HUONG DAN"
PrefB4 : .db "BUI QUOC ANH"
Tile : .db " MEASURE TEMPERATURE"
Info : .db "CURRTEMP ="
Symbol : .db "Tx:"
ADCon : .db "Waiting"
OverTx : .db "OverB! you send?"
SendTo : .db "Sending... "
RESET:
ldi Temp,LOW(RAMEND) ;Init Stack
out SPL,Temp
ldi Temp,HIGH(RAMEND)
out SPH,Temp
cli
;Init register Control
clr CtrlReg
clr StatementReg
clr Implement
;Init port I/O of LCD
ldi Temp,$0F ;Data lines
out DDRC,Temp
ldi Temp,$70 ;Control Lines (bits 4,5,6)
out DDRD,Temp ;Init INT0 and LCD busy
ldi Temp,$02
out PORTD,Temp ;set pullup on pin 2
rcall LCD_INIT
rcall SHOW_PREFACEA
rcall SHOW_PREFACEB
rcall DISPLAY_INTERFACE
Get_Addr_String $8B,ZL,ZH,ADCon,7
rcall SHOW_STRING ;Show string wait
rcall SHOW_SELECT_TxRx
;Create port for KeyPad and int register
ldi Temp,$F0 ;lower nibble input
out DDRB,Temp
ldi Temp,$0F ;Set pullup on lower nibble
out PORTB,Temp
ldi OldKey,-1
ldi AddrShow,$97 ;Preaddress to show
clr KeyPress
;Init address pointer to buffer Tx
clr XH
ldi Temp,StartTxBuff
mov LPtrTx,Temp
ldi Temp,LOW(TxBuff)
mov HPtrTx,Temp
;Init pointer to buffer Rx
clr YH
ldi YL,StartRxBuff
mov HPtrRxH,YH
mov HPtrRxL,YL
;Init INT of KeyPad
ldi Temp,$40
out GIMSK,Temp
ldi Temp,$00 ;Soure trigger INT0 at lower
out MCUCR,Temp
;Init UART
ldi Temp,$98 ;Enable INT Rx compelet
out UCR,Temp ;8 bit data 1 stop, 1 start
ldi Temp,$33 ;baud = 9600bps
out UBRR,Temp
clr Implement ;Init register statement
;Init Interrup comperaA match of TC1
ldi Temp,$10
out TIMSK,Temp
ldi Temp,$0C ;Set value $0000 to counter
out TCCR1B,Temp ;CK/256 = 31.250Hz
ldi Temp,$01 ;Value for comperaA match 312
out OCR1AH,Temp ;312*(256*0,125)us = 10ms
ldi Temp,$38
out OCR1AL,Temp
;Init ADC
ldi Temp,$00 ;Input ADC is PA0
out ADMUX,Temp
ldi Temp,$8F ;Enable single mode
out ADCSR,Temp
ldi Temp,-1
mov ResultADCH,Temp ;Condition show symbol Tempr
clr ResultADCL
sei
MAIN:
sbrs KeyPress,OnKeyPress ;Have a key press
rjmp NoKeyPress
cbr KeyPress,EnOnKeyPress ;Get real KeyPress
sbrs CtrlReg,ImpKey
rjmp NormalKey
rcall CONTROL_KEY
rjmp EndKeyPress
NormalKey:rcall DISPLAY_KEY
in Temp,TIFR ;Clear flag TC1
andi Temp,INTRATE
out TIFR,Temp
in Temp,TIMSK ;Enabl Int KeyRate
sbr Temp,TOIE1
out TIMSK,Temp
ldi Temp,$E7 ;Init counter for int overflow TC1
out TCNT1H,Temp ;65.536 - 6.250 = $E796
ldi Temp,$96 ;6.250*(256*0.125) = 200mS
out TCNT1L,Temp
EndKeyPress:in Temp,GIFR ;Clear flag INT SCAN_CODE
out GIFR,Temp
ldi Temp,$40 ;Enable INT SCAN_CODE
out GIMSK,Temp
NoKeyPress:ldi Temp,-1
cp ResultADCH,Temp
brne SetShowSymbol
mov Temp,StatementReg
sbr Temp,EnShowSymbolTempr
mov StatementReg,Temp
SetShowSymbol:sbrc StatementReg,ShowSymbolTempr
rcall SHOW_SYMBOL_CK
tst Implement
brmi SkipToBack
rcall EXCUTER_FROM_PC
SkipToBack:rjmp MAIN
;Program control LCD
;(RS = 0,RW = 1)
LCD_BUSY:
sbi PORTD,RW ;Select DR
Busy: sbi PORTD,E ;Read 4 MSBs bit
nop
cbi PORTD,E
sbis PIND,7 ;LCD Busy
rjmp NoBusy
sbi PORTD,E ;Ignore 4 LSBs bit
nop
cbi PORTD,E
rjmp Busy
NoBusy: sbi PORTD,E
cbi PORTD,RW
cbi PORTD,E
ret
;Instroduction in register Intr
;(RS = 0, RW = 0)
LCD_INSTR:
swap Instr ;Send 4 MSB bits
out PORTC,Instr
nop
sbi PORTD,E
nop
cbi PORTD,E
swap Instr ;Send 4 LSB bits
out PORTC,Instr
nop
sbi PORTD,E
nop
cbi PORTD,E
ret
;Data in register Data
;(RS = 1, RW = 0)
LCD_DATA:
sbi PORTD,RS
swap Data ;Send 4 MSB bits
out PORTC,Data
nop
sbi PORTD,E
nop
cbi PORTD,E
swap Data ;Send 4 LSB bits
out PORTC,Data
nop
sbi PORTD,E
nop
cbi PORTD,E
cbi PORTD,RS
ret
;Init LCD
LCD_INIT:
ldi TimeOut,$96 ;Wait 15ms after LCD on
rcall DELAY
ldi Instr,$3F ;Function set
rcall LCD_INSTR
ldi TimeOut,$29 ;Wait 4.1ms
rcall DELAY
rcall LCD_INSTR
ldi TimeOut,$01 ;Wait 100us
rcall DELAY
rcall LCD_INSTR
ldi Instr,$28 ;Set 4 bits interface
rcall LCD_BUSY ;on 2 line, font 5x7 dots
rcall LCD_INSTR
ldi Instr,$08 ;LCD off
rcall LCD_BUSY
rcall LCD_INSTR
ldi Instr,$01 ;Reset DDRAM
rcall LCD_BUSY
rcall LCD_INSTR
ldi Instr,$0C ;LCD on
rcall LCD_BUSY
rcall LCD_INSTR
ldi Instr,$06 ;Set address of
rcall LCD_BUSY ;DDRAM increment
rcall LCD_INSTR
ret
;Run char to fixed Position, char in Data
;first address in Instr
RUN_TO_POS:
cpi Data,$20
breq NoRun
push Temp
push Instr
RunChar: rcall LCD_BUSY
rcall LCD_INSTR
rcall LCD_BUSY
rcall LCD_DATA ;Show char
cp Instr,Position ;Right position show
breq HaltRun
ldi Temp,$0A ;Wait 250ms
rcall TIMEWAIT
push Data ;Clear char
ldi Data,$20
rcall LCD_INSTR ;Get position to clear
rcall LCD_BUSY
rcall LCD_DATA
pop Data
inc Instr ;Next position show
rjmp RunChar
HaltRun: pop Instr
pop Temp
NoRun: ret
;Run char of string, Z pointer to last char of string
;coordine in Position, line address in Instr, total char in Temp
RUN_STRING:
lpm ;Load char to Data
mov Data,r0
rcall RUN_TO_POS
sbiw ZL,1 ;Next char in string
dec Position ;Next position show
dec Temp ;Remain char count
brne RUN_STRING
ret
;Clear char of display string to end of line, char in Data
;end of line in Position, address of char to clear in Instr
CLEAR_TO_POS:
cpi Data,$20
breq NoClear
push Instr
push Temp
CLRChar: push Data ;Clear char
ldi Data,$20
rcall LCD_INSTR
rcall LCD_BUSY
rcall LCD_DATA
pop Data
cp Instr,Position ;End of line?
breq HaltCLR
inc Instr ;Next position show
rcall LCD_BUSY
rcall LCD_INSTR
rcall LCD_BUSY
rcall LCD_DATA ;Reshow char at new position
ldi TimeOut,10 ;Wait 250ms
rcall TIMEWAIT
rjmp CLRChar
HaltCLR: pop Temp
pop Instr
NoClear: ret
;Clear display string, Z pointer to last char of string, End of line
;in Position, address of char to clear in Instr, Totla char in Temp
CLEAR_STRING:
lpm ;Load char to Data
mov Data,r0
rcall CLEAR_TO_POS
sbiw ZL,1 ;Next char to clear
dec Instr ;Next address of char to clear
dec Temp ;Remain char count
brne CLEAR_STRING
ret
;Display notify PrefaceA
SHOW_PREFACEA:
Get_Addr_Char $92,$80,18,PrefA1
rcall RUN_STRING ;Display on line 1
Get_Addr_Char $CD,$C0,9,PrefA2
rcall RUN_STRING ;Display on line 2
Get_Addr_Char $A5,$94,16,PrefA3
rcall RUN_STRING ;Display on line 3
Get_Addr_Char $E7,$D4,19,PrefA4
rcall RUN_STRING ;Display on line 4
ret
;Display notify PrefaceB
SHOW_PREFACEB:
Get_Addr_Char $93,$92,18,PrefA1
rcall CLEAR_STRING ;Clear string on line 1
Get_Addr_Char $93,$80,19,PrefB1
rcall RUN_STRING ;Display new string on line 1
Get_Addr_Char $D3,$CD,9,PrefA2
rcall CLEAR_STRING
Get_Addr_Char $CE,$C0,11,PrefB2
rcall RUN_STRING
Get_Addr_Char $A7,$A5,16,PrefA3
rcall CLEAR_STRING
Get_Addr_Char $A7,$94,19,PrefB3
rcall RUN_STRING
Get_Addr_Char $E7,$E7,19,PrefA4
rcall CLEAR_STRING
Get_Addr_Char $E3,$D4,12,PrefB4
rcall RUN_STRING
ret
;Display string, position in Instr, Z pointer
;to first char of string, total char in Temp
SHOW_STRING:
rcall LCD_INSTR
ShowNext: lpm
mov Data,r0
rcall LCD_BUSY
rcall LCD_DATA
adiw ZL,1
dec Temp
brne ShowNext
ret
;Show symbol RxTx
SHOW_RxTx:
cpi Position,9
breq TwoChar
cpi Position,10
breq ThrChar
ldi Temp,1
rjmp ShowSym
TwoChar: ldi Temp,2
rjmp ShowSym
ThrChar: ldi Temp,3
ShowSym: ldi Instr,$94
push Temp
rcall SHOW_STRING
pop Temp
ldi Instr,$D4
mov ZL,XL
mov ZH,XH
push Temp
rcall LCD_BUSY
rcall SHOW_STRING
pop Temp
cpi Temp,3
brlo EndRxTx
ldi Data,$52 ;ASCII code of R
rcall LCD_BUSY
rcall LCD_INSTR
rcall LCD_BUSY
rcall LCD_DATA
EndRxTx: ret
;Show interface to LCD, total char in Temp
DISPLAY_INTERFACE:
ldi Instr,$01 ;Clear screen
rcall LCD_INSTR
ldi TimeOut,49 ;Wait 4.1ms
rcall DELAY
ldi ZL,LOW(Tile<<1) ;String on line 1
ldi ZH,HIGH(Tile<<1)
adiw ZL,19
ldi YL,LOW(Info<<1) ;String on line 2
ldi YH,HIGH(Info<<1)
adiw YL,9
ldi XL,LOW(Symbol<<1) ;String on line 3,4
ldi XH,HIGH(Symbol<<1)
adiw XL,2
ldi Instr,$80
ldi Temp,1 ;Total char show on line 1
ldi Position,1 ;Total char show on line 2
ReShow: push Instr
push ZL
push ZH
push Temp
rcall SHOW_STRING ;Show line 1
pop Temp
cpi Temp,11 ;Show line 2
brlo ShowOne
ldi Instr,$C0
push Temp
mov Temp,Position
mov ZL,YL
mov ZH,YH
rcall SHOW_STRING ;Show line 2
sbiw YL,1 ;Part of string shown on line 2
cpi Position,8
brlo ShowTwo
mov ZL,XL
mov ZH,XH
rcall SHOW_RxTx ;Show all screen
sbiw XL,1
ShowTwo: pop Temp
inc Position
ShowOne: pop ZH
pop ZL
pop Instr
sbiw ZL,1 ;Part of string will show
ldi TimeOut,4 ;Wait 100ms
rcall TIMEWAIT
inc Temp
cpi Temp,21
brlo ReShow
ret
;Get ascii code of keypress
GET_ASCII_CODE:
cpi Temp,0
breq EndGetAscii
add Position,Temp
mov Data,Position
EndGetAscii:ret
;Find ascii code of keypress,
;ascii code contain Data
FIND_ASCII_CODE:
cp KeyPress,OldKey ;First time key press
brne FirstPress
subi CtrlReg,-$10 ;increment total time keypress
cbr CtrlReg,$40 ;Get real time keypress
dec AddrShow ;reshow new char
dec LPtrTx ;restore new char
rjmp GetTimeKey
FirstPress: mov OldKey,KeyPress
cbr CtrlReg,$F0 ;Reset time keypress
GetTimeKey:mov Temp,CtrlReg ;Get time keypress
swap Temp
andi Temp,$0F
cpi KeyPress,5 ;Scan code < 5
brge Key5To9
cpi KeyPress,3
brge Key3Or4
cpi KeyPress,1
brne Key0Or2
Set_First_Ascii $31,$43 ;Ascii of 1 and D
rcall GET_ASCII_CODE
rjmp EndFindAscii
Key0Or2: cpi KeyPress,2
breq Key2
Set_First_Ascii $30,$40
rcall GET_ASCII_CODE
rjmp EndFindAscii
Key2: Set_First_Ascii $32,$46
rcall GET_ASCII_CODE
rjmp EndFindAscii
Key3Or4: cpi KeyPress,3
breq Key3
Set_First_Ascii $34,$4C
rcall GET_ASCII_CODE
rjmp EndFindAscii
Key3: Set_First_Ascii $33,$49
rcall GET_ASCII_CODE
rjmp EndFindAscii
Key5To9: cpi KeyPress,7
brge Key7To9
cpi KeyPress,6
brne Key5
Set_First_Ascii $36,$52
rcall GET_ASCII_CODE
rjmp EndFindAscii
Key5: Set_First_Ascii $35,$4F
rcall GET_ASCII_CODE
rjmp EndFindAscii
Key7To9: cpi KeyPress,8
brne Key7Or9
Set_First_Ascii $38,$58
cpi Temp,3
brne SkipFour
cbr CtrlReg,$F0 ;Loopback times keypress
ldi Temp,0 ;to skip keypress four
SkipFour: rcall GET_ASCII_CODE
rjmp EndFindAscii
Key7Or9: cpi KeyPress,9
brne Key7
Set_First_Ascii $39,$19
cpi Temp,2
brne SkipThree
cbr CtrlReg,$F0
ldi Temp,0
SkipThree: rcall GET_ASCII_CODE
rjmp EndFindAscii
Key7: Set_First_Ascii $37,$55
rcall GET_ASCII_CODE
EndFindAscii:ret
;Display char in Tx buffer, use pointer Z
;total char to show in Temp, position show in Instr
DISPLAY_CHAR_IN_TxBUFF:
rcall LCD_INSTR
NextShow: ld Data,Z+
rcall LCD_BUSY
rcall LCD_DATA
dec Temp
brne NextShow
ret
;Get pointer to first char show in Tx buff on LCD
GET_POINTER:
push Temp
mov Temp,AddrShow
subi Temp,$97 ;Total current char display
mov Position,LPtrTx
sub Position,HPtrTx
cp Position,Temp
breq NoGetPoint
mov Position,LPtrTx
sub Position,Temp
mov HPtrTx,Position ;Set pointer
pop Temp
NoGetPoint:ret
;Display char in TxBuff to LCD
;Total char to show in Temp
SHOW_CHAR_IN_TxBuff:
rcall GET_POINTER
cpi AddrShow,$A7
brne NoReShow
cpi Temp,15 ;Number char Need to show?
brne Show16Char
inc HPtrTx ;Show 15 last char
Show16Char:ldi Instr,$98 ;Show 16 last char
clr ZL
mov ZL,HPtrTx ;Get pointer to char
push Data
rcall DISPLAY_CHAR_IN_TxBUFF
pop Data
NoReShow:ret
;Show char corresponding keypress, and store char
;into TxBuff to send to PC
DISPLAY_KEY:
rcall FIND_ASCII_CODE
inc LPtrTx ;Increment pointer buffer
ldi Temp,EndTxBuff+1
cp LPtrTx,Temp ;Over TxBuff
breq OverBuff
ldi Temp,15
rcall SHOW_CHAR_IN_TxBuff ;Reshow 15 lastchar in buff
Get_Position AddrShow,$A7
rcall LCD_INSTR ;Show char to LCD
rcall LCD_BUSY
rcall LCD_DATA
mov XL,LPtrTx
st X,Data ;Store char
rjmp EndDisplay
OverBuff: Get_Addr_String $98,ZL,ZH,OverTx,16
rcall SHOW_STRING
dec LPtrTx ;Get back LPtrTx
EndDisplay:ret
;Show symbol select on Tx or Rx
SHOW_SELECT_TxRx:
ldi Temp,1
sbrs CtrlReg,SelectTxRx
rjmp SelectTx
ldi Instr,$97
rcall CLEAR_LINE
ldi Instr,$D7
rjmp ShowSymbol
SelectTx: ldi Instr,$D7
rcall CLEAR_LINE
ldi Instr,$97
ShowSymbol:rcall LCD_BUSY
rcall LCD_INSTR
ldi Data,$7E ;Symbol select
rcall LCD_BUSY
rcall LCD_DATA
ret
;Perform function select display on Tx or Rx
SELECT_TxRx:
sbrs CtrlReg,SelectTxRx
rjmp EnableRx
cbr CtrlReg,EnSelectTxRx ;Select Tx
rjmp ShowSelect
EnableRx: sbr CtrlReg,EnSelectTxRx ;Select Rx
ShowSelect:rcall SHOW_SELECT_TxRx
ret
;Clear char at Addrshow
CLEAR_CHAR_IN_LCD:
ldi Temp,16
rcall SHOW_CHAR_IN_TxBuff
mov Instr,AddrShow
rcall LCD_INSTR
ldi Data,$20
rcall LCD_BUSY
rcall LCD_DATA
dec AddrShow
cpi AddrShow,$97
brne EndClear
ldi Temp,LOW(TxBuff)
cp HPtrTx,Temp
breq EndClear
inc AddrShow ;Yet char
mov Instr,AddrShow
rcall LCD_BUSY
rcall LCD_INSTR
dec HPtrTx
mov XL,HPtrTx
ld Data,X ;Get next char to show
rcall LCD_BUSY
rcall LCD_DATA
EndClear:ret
;Perform function backspace
BACK_SPACE:
sbrc CtrlReg,SelectTxRx ;Selecting Rx
rjmp NoPerform
cpi AddrShow,$97
breq NoPerform ;No char
dec LPtrTx
rcall CLEAR_CHAR_IN_LCD
NoPerform:ret
;Clear char in line, address start in Instr
;Total char to clear in Temp
CLEAR_LINE:
rcall LCD_INSTR
ldi Data,$20
NextClear: rcall LCD_BUSY
rcall LCD_DATA
dec Temp
brne NextClear
ret
;Perform function clear TxRx
CLEAR_Tx_OR_Rx:
sbrc CtrlReg,SelectTxRx
rjmp SelectRx
ldi Instr,$98
ldi Temp,16 ;Total char to clear
rcall CLEAR_LINE
ldi Temp,LOW(TxBuff)
mov HPtrTx,Temp
ldi Temp,StartTxBuff
mov LPtrTx,Temp
ldi AddrShow,$97
rjmp HalfClear
SelectRx: ldi Instr,$D8 ;Clear display line
ldi Temp,16
rcall CLEAR_LINE
clr YH ;Reset pointer to RxBuff
ldi YL,StartRxBuff
mov HPtrRxH,YH
mov HPtrRxL,YL
HalfClear: ret
;Display char in Rx buffer, use pointer Z
;total char to show in Temp, position show in Instr
DISPLAY_CHAR_IN_RxBUFF:
rcall LCD_INSTR
NextDisplay:ld Data,Z+
rcall LCD_BUSY
rcall LCD_DATA
cpi ZL,EndRxBuffL+1
brne NoResetPoint
clr ZH
ldi ZL,StartRxBuff
NoResetPoint:dec Temp
brne NextDisplay
ret
;Perform function shift right
SHIFT_RIGHT:
sbrc CtrlReg,SelectTxRx
rjmp ShiftR_Rx
cpi AddrShow,$97
breq NoShiftR ;No char
mov Position,AddrShow
subi Position,$98 ;Number of current char
mov Temp,LPtrTx
sub Temp,HPtrTx
cp Temp,Position
breq NoShiftR
inc HPtrTx
clr ZH
mov ZL,HPtrTx
mov Temp,LPtrTx
sub Temp,HPtrTx
inc Temp
cpi Temp,16 ;Number char to show
brge ShowAllChar
push Temp
ldi Temp,$A7 ;Clear part last in LCD
sub Temp,AddrShow
mov Instr,AddrShow
inc Instr
rcall CLEAR_LINE
pop Temp
rjmp SetAddr
ShowAllChar:ldi Temp,16
SetAddr: ldi Instr,$98
rcall DISPLAY_CHAR_IN_TxBUFF
rjmp NoShiftR
ShiftR_Rx: cp HPtrRxL,YL
breq NoShiftR ;No char in RxBuff
mov Position,ShowRxL
mov PositionH,ShowRxH
adiw Position,15
cpi Position,EndRxBuffL+1
brlo CheckLastPoint
clr PositionH
subi Position,$62
ldi Temp,StartRxBuff-1
add Position,Temp
CheckLastPoint:cp Position,YL
breq NoShiftR
mov Position,ShowRxL
mov PositionH,ShowRxH
adiw Position,1
cpi Position,EndRxBuffL+1
brne GetNewPoint ;Reset pointer
clr PositionH
ldi Position,StartRxBuff
GetNewPoint:mov ShowRxL,Position ;Get new pointor
mov ShowRxH,PositionH
mov ZL,ShowRxL
mov ZH,ShowRxH
ldi Instr,$D8
ldi Temp,16
rcall DISPLAY_CHAR_IN_RxBUFF
NoShiftR: ret
;Perform function shift left
SHIFT_LEFT:
sbrc CtrlReg,SelectTxRx
rjmp ShiftL_Rx
ldi Temp,LOW(TxBuff)
cp HPtrTx,Temp
breq NoShiftL ;No shift
dec HPtrTx
mov Temp,LPtrTx
sub Temp,HPtrTx
inc Temp ;Total char to show
cpi Temp,17
brlo ShiftTxL
ldi Temp,16
ShiftTxL: ldi Instr,$98 ;Position to show
clr ZH
mov ZL,HPtrTx
rcall DISPLAY_CHAR_IN_TxBUFF
rjmp NoShiftL
ShiftL_Rx: cp ShowRxL,HPtrRxL
breq NoShiftL
mov Position,ShowRxL
mov PositionH,ShowRxH
sbiw Position,1
cpi Position,StartRxBuff-1
brne NoGetNewPoint
ldi Position,EndRxBuffL
ldi PositionH,EndRxBuffH
NoGetNewPoint:mov ShowRxL,Position ;Get new pointor
mov ShowRxH,PositionH
ldi Temp,16
ldi Instr,$D8
mov ZL,ShowRxL
mov ZH,ShowRxH
rcall DISPLAY_CHAR_IN_RxBUFF
NoShiftL: ret
;Perform function Send
SEND_TxBUFF_TO_PC:
sbrc CtrlReg,SelectTxRx ;Selecting Rx
rjmp NoSend
cpi AddrShow,$97 ;No char in buff
breq NoSend
Get_Addr_String $98,ZL,ZH,SendTo,16
rcall SHOW_STRING
ldi XL,LOW(TxBuff)
SendChar: ld Data,X
WaitReady:sbis USR,UDRE
rjmp WaitReady
out UDR,Data
cp XL,LPtrTx
breq ClearToSend
inc XL
rjmp SendChar
ClearToSend:rcall CLEAR_Tx_OR_Rx
NoSend: ret
;Perform control key
CONTROL_KEY:
cbr CtrlReg,EnImpKey ;Clear confirm controlkey
cpi KeyPress,13
brge Key13To15
cpi KeyPress,11
brne Key10Or12
rcall BACK_SPACE
rjmp EndControlKey
Key10Or12:cpi KeyPress,10
breq Key10
rcall SHIFT_LEFT
rjmp EndControlKey
Key10: rcall SEND_TxBUFF_TO_PC
rjmp EndControlKey
Key13To15:cpi KeyPress,14
breq Key14
cpi KeyPress,15
breq Key15
rcall SHIFT_RIGHT
rjmp EndControlKey
Key15: rcall CLEAR_Tx_OR_Rx
rjmp EndControlKey
Key14: rcall SELECT_TxRx
EndControlKey:ldi OldKey,-1 ;Reset OldKey
ret
;Service INT0
SCAN_CODE:
in Save,SREG
ldi KeyPress,$00
out GIMSK,KeyPress
ldi TimeOut,2 ;Wait 0.2ms for settle
rcall DELAY
;Find col
sbis PINB,Col1
ldi KeyPress,0
sbis PINB,Col2
ldi KeyPress,4
sbis PINB,Col3
ldi KeyPress,8
sbis PINB,Col4
ldi KeyPress,12
;invert port to find col
push Temp
ldi Temp,$F0 ;Lower ninble is output
out DDRB,Temp
ldi Temp,$0F ;Set pullup on upper
out PORTB,Temp
ldi TimeOut,2 ;Wait 0.2ms for settle
rcall DELAY
;Find Row
sbis PINB,Row1
subi KeyPress,0
sbis PINB,Row2
subi KeyPress,-1
sbis PINB,Row3
subi KeyPress,-2
sbis PINB,Row4
subi KeyPress,-3
;Get sort KeyPress
cpi KeyPress,10
brlo Normal
sbr CtrlReg,EnImpKey ;Confirm Control key
Normal: sbr KeyPress,EnOnKeyPress ;Confirm a key press
in Temp,TIMSK ;Disable int KEY_RATE overflow
sbrs Temp,TOIE1 ;Enable?
rjmp HalfScanCode
cbr Temp,INTRATE
out TIMSK,Temp
HalfScanCode:pop Temp
out SREG,Save
reti
;Service INT delay for reloop of keypress
KEY_RATE:
in Save,SREG
ldi OldKey,-1 ;Reset register for compera
push Temp
in Temp,TIMSK
cbr Temp,INTRATE
out TIMSK,Temp ;Disable INT KEY_RATE
pop Temp
out SREG,Save
reti
;Service INT Receive compelet
Rx_COMPELET:
in Save,SREG
push Data
in Data,UDR ;Get data
sbrs CtrlReg,Instroduc
rjmp Get_Code ;Get symbol of Statement
mov Implement,Data
cbr CtrlReg,EnInstroduc
rjmp HalfRx
Get_Code: cpi Data,Statement ;Receive symbol Statement
brne RxData
sbr CtrlReg,EnInstroduc
rjmp HalfRx
RxData: cpi Data,CR ;End of receive
brne SetStore
sbr CtrlReg,EnShowRxBuff ;Reques show data in Rx buff
ldi Data,$7C ;Symbol "|" end of char
SetStore: cpi YL,EndRxBuffL+1
brne StoreRx
clr YH ;Back to head RxBuff
ldi YL,StartRxBuff
inc HPtrRxL ;Increment head pointer
StoreRx: st Y+,Data ;Store data to RxBuff
push Temp
ldi Temp,StartRxBuff
cp HPtrRxL,Temp
breq HalfRx
cpi YL,EndRxBuffL+1
brne GetHPtrRx
clr HPtrRxH ;Reset pointer head RxBuff
mov HPtrRxL,Temp
rjmp ResetHPtrRx
GetHPtrRx: mov HPtrRxL,YL ;Get pointer head RxBuff
mov HPtrRxH,YH
ResetHPtrRx:pop Temp
HalfRx: pop Data
out SREG,Save
reti
;Service INT enable adc
ENABLE_ADC:
in Save,SREG
sbi ADCSR,ADSC ;Enable convert
out SREG,Save
reti
;Mull result convert with content Data to divide
;Mulled in Data
MULL_RESULT_CONVER:
clc
clr r11
mov r12,ResultADCL
Mull_Data: dec Data
breq HalfMull
add ResultADCL,r12
adc ResultADCH,r11
rjmp Mull_Data
HalfMull: ret
;Divide result convert to get temperature
;result in ResultADCH, remainde in ResultADCL
;Divider in Data
DIVIDE_TO_GET_TEMPR:
clr r11
sub r12,r12
LoopDivide:cp ResultADCH,r11
brne Divide
cp ResultADCL,Data
brlo EndDivide
Divide: sub ResultADCL,Data
sbc ResultADCH,r11
clc
inc r12
rjmp LoopDivide
EndDivide: mov ResultADCH,r12
ret
;Service INT end convert adc
;Result in ResultADCH, remainde in ResultADCL
END_CONVERT:
in Save,SREG
in ResultADCL,ADCL
in ResultADCH,ADCH
lsr ResultADCH ;Get 8 bit result
ror ResultADCL
lsr ResultADCH
ror ResultADCL
push Data
ldi Data,Statement
SendConfirm:sbis USR,UDRE
rjmp SendConfirm
out UDR,Data
ldi Data,$64 ;Mull result with 100
rcall MULL_RESULT_CONVER
ldi Data,$FF ;Divide with 255 to get tempr
rcall DIVIDE_TO_GET_TEMPR
SendResult: sbis USR,UDRE
rjmp SendResult
out UDR,ResultADCH ;Get result
push ResultADCH
clr ResultADCH ;Clear upper byte
ldi Data,$0A
rcall MULL_RESULT_CONVER
ldi Data,$FF
rcall DIVIDE_TO_GET_TEMPR
ldi Data,$80
cp ResultADCL,Data
brlo Get_Remainder
inc ResultADCH
Get_Remainder:mov ResultADCL,ResultADCH
pop ResultADCH
SendRemainde:sbis USR,UDRE
rjmp SendRemainde
out UDR,ResultADCL ;Get remainder
;thay bng dung co bao
rcall DISPLAY_TEMPR_TO_LCD
pop Data
out SREG,Save
reti
;Show temperature to LCD
DISPLAY_TEMPR_TO_LCD:
push Instr
ldi Instr,$CB
rcall LCD_INSTR
push ResultADCL
mov ResultADCL,ResultADCH
clr ResultADCH
sbrs StatementReg,Show_CK
rjmp ShowTemprC
clr Instr
ldi Data,$C8 ;Get Kelvin
add ResultADCL,Data
adc ResultADCH,Instr
ldi Data,$49
add ResultADCL,Data
adc ResultADCH,Instr
ShowTemprC:ldi Data,$64
rcall DIVIDE_TO_GET_TEMPR ;Get number hundres
ldi Data,0
cp ResultADCH,Data
breq No100
mov Data,ResultADCH
subi Data,-$30
rjmp Show100
No100: ldi Data,$20
Show100: rcall LCD_BUSY
rcall LCD_DATA
ldi Data,$0A
clr ResultADCH
rcall DIVIDE_TO_GET_TEMPR
ldi Data,0
cp ResultADCH,Data
breq No10
mov Data,ResultADCH
rjmp Show10
No10: ldi Data,$30
Show10: rcall LCD_BUSY
rcall LCD_DATA
mov Data,ResultADCL
subi Data,-$30
rcall LCD_BUSY
rcall LCD_DATA
ldi Data,$2E
rcall LCD_BUSY
rcall LCD_DATA
pop ResultADCL
mov Data,ResultADCL
subi Data,-$30
rcall LCD_BUSY
rcall LCD_DATA
pop Instr
ret
;Show symbol temperature
SHOW_SYMBOL_CK:
mov Temp,StatementReg
cbr Temp,EnShowSymbolTempr
mov StatementReg,Temp
ldi Instr,$D0
rcall LCD_INSTR
ldi Data,$DF
rcall LCD_BUSY
rcall LCD_DATA
sbrs StatementReg,Show_CK
rjmp ShowSymbolC
ldi Data,$4B ;Ascii of K
rjmp DisplaySymbol
ShowSymbolC: ldi Data,$43 ;Ascii of C
DisplaySymbol: rcall LCD_BUSY
rcall LCD_DATA
ret
;Excuter statement from PC
EXCUTER_FROM_PC:
ldi Temp,EnCencius
cp Implement,Temp
brne EnKenvin
mov Temp,StatementReg
cbr Temp,EnShow_CK
rjmp Excuted
EnKenvin: mov Temp,StatementReg
sbr Temp,EnShow_CK
Excuted: sbr Temp,EnShowSymbolTempr
mov StatementReg,Temp
ldi Temp,-1
mov Implement,Temp
ret
;Program time out delay
;TimeOut delay = (0.1*TimeOut)ms
DELAY:
push Data
push Temp
Reloop: ldi Data,$03
Back: ldi Temp,$56
Loop: dec Temp
brne Loop
dec Data
brne Back
dec TimeOut
brne ReLoop
pop Temp
pop Data
ret
;TimeWait = (25*Temp)ms
TIMEWAIT:
ldi TimeOut,$FA
rcall DELAY
dec Temp
brne TIMEWAIT
ret
._.
Các file đính kèm theo tài liệu này:
- DAN021.doc