Bộ nhớ chương trình Program memory: Là bộ nhớ Flash lập trình ñược, trong các chip AVR cũ như AT90S1200 hay AT2313… bộ nhớ chương trình chỉ gồm 1 phần là Application Flash Section nhưng
Trang 1CÙNG HỌC AVR AVR2 – CẤU TRÚC AVR
Thoả thuận: tài liệu này thuộc quyền sở hữu của tác giả, bạn có thể tự do tham khảo tài liệu nhưng không ñược phép sử dụng ñể in thành sách báo, ñăng lên các diễn ñàn hay website, nhưng bạn có thể dùng ñường link http://www.dieukhientudong.net ñể hướng tới tài liệu Liên hệ tác giả qua email: thanhtam.h@gmail.com
I Bạn sẽ ñi ñến ñâu
Bài này tiếp tục bài ñầu tiên trong loạt bài giới thiệu về AVR, nếu sau bài 1 bạn ñã phần nào biết cách lập trình cho AVR bằng AVRStudio thì trong bài này, chúng ta sẽ tìm hiểu kỹ hơn về cấu trúc của AVR Sau bài này, bạn sẽ:
- Hiểu ñược cấu trúc AVR, cấu trúc bộ nhớ và cách thức hoạt ñộng của chip
- Hiểu về Stack và cách hoạt ñộng
- Biết ñược một số instruction cơ bản truy xuất bộ nhớ
- Học các instruction rẽ nhánh và vòng lặp
- Chương trình con (Subroutine) và Macro
- Cải tiến ví dụ trong bài 1
- Viết 1 ví dụ minh họa cách sử dụng bộ nhớ và vòng lặp
II Tồ chức của AVR
AVR có cấu trúc Harvard, trong ñó ñường truyền cho bộ nhớ dữ liệu (data memory bus) và ñường truyền cho bộ nhớ chương trình (program memory bus) ñược tách riêng Data memory bus chỉ có 8 bit và ñược kết nối với hầu hết các thiết bị ngoại vi, với register file Trong khi ñó program memory bus có ñộ rộng 16 bits và chỉ phục vụ cho instruction registers Hình 1 mô tả cấu trúc bộ nhớ của AVR
Bộ nhớ chương trình (Program memory): Là bộ nhớ Flash lập trình ñược, trong các chip
AVR cũ (như AT90S1200 hay AT()2313…) bộ nhớ chương trình chỉ gồm 1 phần là Application Flash Section nhưng trong các chip AVR mới chúng ta có thêm phần Boot Flash setion Boot section sẽ ñược khảo sát trong các phần sau, trong bài này khi nói về bộ nhớ chương trình, chúng
ta tự hiểu là Application section Thực chất, application section bao gồm 2 phần: phần chứa các instruction (mã lệnh cho hoạt ñộng của chip) và phần chứa các vector ngắt (interrupt vectors) Các vector ngắt nằm ở phần ñầu của application section (từ ñịa chỉ 0x0000) và dài ñến bao nhiêu tùy thuộc vào loại chip Phần chứa instruction nằm liền sau ñó, chương trình viết cho chip phải ñược load vào phần này Xem lại phần ñầu của ví dụ trong bài 1:
.ORG 0x000
RJMP BATDAU ORG 0x020
BATDAU:
Trong ví dụ này, ngay sau khi set vị trí 0x000 bằng chỉ thị (DIRECTIVE) ORG 0x000 chúng ta dùng instruction RJMP ñể nhảy ñến vị trí 0x020, như thế phần bộ nhớ chương trình từ 0x00 ñến 0x01F không ñược sử dụng (vì trong ví dụ này chúng ta không sử dụng các vector
Trang 2ngắt) Chương trình chính ñược bắt ñầu từ ñịa chỉ 0x020, con số 0x020 là do người lập trình chọn, thật ra các vector ngắt của chip ATMEGA8 chỉ kéo dài ñến ñịa chỉ 0x012, vì vậy chương trình chính có thể ñược bắt ñầu từ bất cứ vị trí nào sau ñó Để biết ñộ dài các vector ngắt của từng chip bạn hãy tham khảo datasheet của chip ñó
Vì chức năng chính của bộ nhớ chương trình là chứa instruction, chúng ta không có nhiều cơ hội tác ñộng lên bộ nhớ này khi lập trình cho chip, vì thế ñối với người lập trình AVR, bộ nhớ này
“không quá quan trọng” Tất cả các thanh ghi quan trọng cần khảo sát nằm trong bộ nhớ dữ liệu của chip
Hình 1 Cấu trúc bộ nhớ của AVR
Bộ nhớ dữ liệu (data memory): Đây là phần chứa các thanh ghi quan trọng nhất của chip,
việc lập trình cho chip phần lớn là truy cập bộ nhớ này Bộ nhớ dữ liệu trên các chip AVR có ñộ lớn khác nhau tùy theo mỗi chip, tuy nhiên về cơ bản phần bộ nhớ này ñược chia thành 5 phần:
Phần 1: là phần ñầu tiên trong bộ nhớ dữ liệu, như mô tả tronh hình 2, phần này bao gồm 32 thanh ghi có tên gọi là register file (RF), hay General Purpose Rgegister – GPR, hoặc ñơn giản là
các Thanh ghi Tất cả các thanh ghi này ñều là các thanh ghi 8 bits như trong hình 2
Hình 2 Thanh ghi 8 bits
Tất cả các chip trong họ AVR ñều bao gồm 32 thanh ghi Register File có ñịa chỉ tuyệt ñối từ 0x0000 ñến 0x001F Mỗi thanh ghi có thể chứa giá trị dương từ 0 ñến 255 hoặc các giá trị có dấu
từ -128 ñến 127 hoặc mã ASCII của một ký tự nào ñó…Các thanh ghi này ñược ñặt tên theo thứ
Trang 3tự là R0 ñến R31 Chúng ñược chia thành 2 phần, phần 1 bao gồm các thanh ghi từ R0 ñến R15 và phần 2 là các thanh ghi R16 ñến R31 Các thanh ghi này có các ñặc ñiểm sau:
- Được truy cập trực tiếp trong các instruction
- Các toán tử, phép toán thực hiện trên các thanh ghi này chỉ cần 1 chu kỳ xung clock
- Register File ñược kết nối trực tiếp với bộ xử lí trung tâm – CPU của chip
- Chúng là nguồn chứa các số hạng trong các phép toán và cũng là ñích chứa kết quả trả lại của phép toán
Để minh họa, hãy xét ví dụ thực hiện phép cộng 2 thanh ghi bằng instruction ADD như sau:
Tất cả các instruction sử dụng RF làm toán hạng ñều có thể truy nhập tất cả các RF một cách
trực tiếp trong 1 chu kỳ xung clock, ngoại trừ SBCI, SUBI, CPI, ANDI và LDI, các instruction này chỉ có thể truy nhập các thanh ghi từ R16 ñến R31
Thanh ghi R0 là thanh ghi duy nhất ñược sử dụng trong instruction LPM (Load Program Memory) Các thanh ghi R26, R27, R28, R29, R30 và R31 ngoài chức năng thông thường còn ñược sử dụng như các con trỏ (Pointer register) trong một số instruction truy xuất gián tiếp Chúng ta sẽ khảo sát vấn ñề con trỏ sau này Hình 3 mô tả các chức năng phụ của các thanh ghi
Hình 3 Register file
Tóm lại 32 RF của AVR ñược xem là 1 phần của CPU, vì thế chúng ñược CPU sử dụng trực tiếp và nhanh chóng, ñể gọi các thanh ghi này, chúng ta không cần gọi ñịa chỉ mà chỉ cần gọi trực tiếp tên của chúng RF thường ñược sử dụng như các toán hạng (operand) của các phép toán trong lúc lập trình
Trang 4Phần 2: là phần nằm ngay sau register file, phần này bao gồm 64 thanh ghi ñược gọi là 64 thanh ghi nhập/xuất (64 I/O register) hay còn gọi là vùng nhớ I/O (I/O Memory) Vùng nhớ I/O
là cửa ngõ giao tiếp giữa CPU và thiết bị ngoại vi Tất cả các thanh ghi ñiều khiển, trạng thái…của thiết bị ngoại vi ñều nằm ở ñây Xem lại ví dụ trong bài 1, trong ñó tôi có ñề cập về việc ñiều khiển các PORT của AVR, mỗi PORT liên quan ñến 3 thanh ghi DDRx, PORTx và PINx, tất
cả 3 thanh ghi này ñều nằm trong vùng nhớ I/O Xa hơn, nếu muốn truy xuất các thiết bị ngoại vi khác như Timer, chuyển ñổi Analog/Digital, giao tiếp USART…ñều thực hiện thông qua việc ñiều khiển các thanh ghi trong vùng nhớ này
Vùng nhớ I/O có thể ñược truy cập như SRAM hay như các thanh ghi I/O Nếu sử dụng instruction truy xuất SRAM ñể truy xuất vùng nhớ này thì ñịa chỉ của chúng ñược tính từ 0x0020 ñến 0x005F Nhưng nếu truy xuất như các thanh ghi I/O thì ñịa chỉ của chúng ñựơc tính từ 0x0000 ñến 0x003F
Xét ví dụ instruction OUT dùng xuất giá trị ra các thanh ghi I/O, lệnh này sử dụng ñịa chỉ
kiểu thanh ghi, cấu trúc của lệnh như sau: OUT A, Rr, trong ñó A là ñịa chỉ của thanh ghi trong
vùng nhớ I/O, Rr là thanh ghi RF, lệnh OUT xuất giá trị từ thanh ghi Rr ra thanh ghi I/O có ñịa chỉ là A Giả sử chúng ta muốn xuất giá trị chứa trong R6 ra thanh ghi ñiều khiển hướng của PORTD, tức thanh ghi DDRD, ñịa chỉ tính theo vùng I/O của thanh ghi DDRD là 0x0011, như thế câu lệnh của chúng ta sẽ có dạng: OUT 0x0011, R6 Tuy nhiên trong 1 trường hợp khác, nếu
muốn truy xuất DDRD theo dạng SRAM, ví dụ lệnh STS hay LDS, thì phải dùng ñịa chỉ tuyệt ñối của thanh ghi này, tức giá trị 0x0031, khi ñó lệnh OUT ở trên ñược viết lại là STS 0x0031, R6
Để thống nhất cách sử dụng từ ngữ, từ bây giờ chúng ta dùng khái niệm “ñịa chỉ I/O” cho
các thanh ghi trong vùng nhớ I/O ñể nói ñến ñịa chỉ không tính phần Register File, khái niệm
“ñịa chỉ bộ nhớ” của thanh ghi là chỉ ñịa chỉ tuyệt ñối của chúng trong SRAM Ví dụ thanh ghi
DDRD có “ñịa chỉ I/O” là 0x0011 và “ñịa chỉ bộ nhớ” của nó là 0x0031, “ñịa chỉ bộ nhớ” =
“ñịa chỉ thanh ghi” + 0x0020
Vì các thanh ghi trong vùng I/O không ñược hiểu theo tên gọi như các Register file, khi lập trình cho các thanh ghi này, người lập trình cần nhớ ñịa chỉ của từng thanh ghi, ñây là việc tương ñối khó khăn Tuy nhiên, trong hầu hết các phần mềm lập trình cho AVR, ñịa chỉ của tất cả các thanh ghi trong vùng I/O ñều ñược ñịnh nghĩa trước trong 1 file Definition, bạn chỉ cần ñính kèm file này vào chương trình của bạn là có thể truy xuất các thanh ghi với tên gọi của chúng Giả sử trong ví dụ ở bài 1, ñể lập trình cho chip Atmega8 bằng AVRStudio, dòng thứ 2 chúng ta sử dụng INCLUDE "M8DEF.INC" ñể load file ñịnh nghĩa cho chip ATMega8, file M8DEF.INC Vì vậy, trong sau này khi muốn sử dụng thanh ghi DDRD bạn chỉ cần gọi tên của chúng, như:
OUT DDRD,R6
Phần 4: RAM ngoại (external SRAM), các chip AVR cho phép người sử dụng gắn thêm các
bộ nhớ ngoài ñể chứa biến, vùng này thực chất chỉ tồn tại khi nào người sử dụng gắn thêm bộ nhớ ngoài vào chip
Phần 5: EEPROM (Electrically Ereasable Programmable ROM) là một phần quan trọng của
các chip AVR mới, vì là ROM nên bộ nhớ này không bị xóa ngay cả khi không cung cấp nguồn nuôi cho chip, rất thích hợp cho các ứng dụng lưu trữ dữ liệu Như trong hình 1, phần bộ nhớ EEPROM ñược tách riêng và có ñịa chỉ tính từ 0x0000
Trang 5AVR hoạt ñộng như thế nào?
Hình 4 biểu diễn cấu trong bên trong của 1 AVR Bạn thấy rằng 32 thanh ghi trong Register File ñược kết nối trực tiếp với Arithmetic Logic Unit -ALU (ALU cũng ñược xem là CPU của AVR) bằng 2 line, vì thế ALU có thể truy xuất trực tiếp cùng lúc 2 thanh ghi RF chỉ trong 1 chu
kỳ xung clock (vùng ñược khoanh tròn màu ñỏ trong hình 4)
Hình 4 Cấu trúc bên trong AVR
Các instruction ñược chứa trong bộ nhớ chương trình Flash memory dưới dạng các thanh ghi
16 bit Bộ nhớ chương trình ñược truy cập trong mỗi chu kỳ xung clock và 1 instruction chứa trong program memory sẽ ñược load vào trong instruction register, instruction register tác ñộng và lựa chọn register file cũng như RAM cho ALU thực thi Trong lúc thực thi chương trình, ñịa chỉ của dòng lệnh ñang thực thi ñược quyết ñịnh bởi một bộ ñếm chương trình – PC (Program counter) Đó chính là cách thức hoạt ñộng của AVR
AVR có ưu ñiểm là hầu hết các instruction ñều ñược thực thi trong 1 chu kỳ xung clock, vì vậy có thể nguồn clock lớn nhất cho AVR có thể nhỏ hơn 1 số vi ñiều khiển khác như PIC nhưng thời gian thực thi vẫn nhanh hơn
Trang 6III Stack
Stack ñược hiểu như là 1 “tháp” dữ liệu, dữ liệu ñược chứa vào stack ở ñỉnh “tháp” và dữ liệu cũng ñược lấy ra từ ñỉnh Kiểu truy cập dữ liệu của stack gọi là LIFO (Last In First Out – vào sau ra trước) Hình 5 thể hiện cách truy cập dữ liệu của stack
ví dụ ở bài 1, phần khởi tạo các ñiều kiện ñầu
; KHOI TAO CÁC DIEU KIEN DAU
LDI R16, HIGH(RAMEND) LDI R17, LOW(RAMEND) OUT SPH, R16
OUT SPL, R17 Bốn dòng khai báo trên mục ñích là gán giá trị của RAMEND cho con trỏ SP, RAMEND (tức End of Ram) là biến chứa ñịa chỉ lớn nhất của RAM nội trong AVR, biến này ñược ñịnh nghĩa trong file M8DEF.INC Như thế sau 4 dòng trên, con trỏ SP chứa giá trị cuối cùng của SRAM hay nói cách khác vùng stack bắt ñầu từ vị trí cuối cùng của bộ nhớ SRAM Nhưng tại sao
là vị trí cuối cùng mà không là 1 giá trị khác Có thể giải thích như sau: stack trong AVR hoạt ñộng từ trên xuống, sau khi dữ liệu ñược ñẩy vào stack, SP sẽ giảm giá trị vì thế khởi ñộng SP ở
vị trí cuối cùng của SRAM sẽ tránh ñược việc mất dữ liệu do ghi ñè Bạn có thể khởi ñộng stack với 1 ñịa chỉ khác, tuy nhiên vì lý do an toàn, nên khởi ñộng stack ở RAMEND
Hai instruction dùng cho truy cập stack là PUSH và POP, trong ñó PUSH dùng ñẩy dữ liệu vào stack và POP dùng lấy dữ liệu ra khỏi stack Dữ liệu ñược ñẩy vào và lấy ra khỏi stack tại vị trí mà con trỏ SP trỏ ñến Ví dụ cho chip ATMega8, RAMEND=0x045F, sau khi khởi ñộng, con trỏ SP trỏ ñến vị trí 0x045F trong SRAM, nếu ta viết các câu lệnh sau:
Trang 7PUSH R1
Khi ñó nội dung của stack sẽ như trong hình 6
Hình 6 Nội dung stack trong ví dụ
Sau mỗi lần PUSH dữ liệu, SP sẽ giảm 1 ñơn vị và trỏ vào vị trí tiếp theo
Bây giờ nếu ta dùng POP ñể lấy dữ liệu từ stack, POP R2, thì R2 sẽ mang giá trị của ngăn
nhớ 0x045D, tức R2=8 Trước khi instruction POP ñược thực hiện, con trỏ SP ñược tăng lên 1 ñơn vị, sau ñó dữ liệu sẽ ñược lấy ra từ vị trí mà SP trỏ ñến trong stack
Stack trong AVR không phải là “vô ñáy”, nghĩa là chúng ta chỉ có thể PUSH dữ liệu vào stack ở 1 ñộ sâu nhất ñịnh nào ñấy (phụ thuộc vào chip) Sử dụng stack không ñúng cách ñôi khi
sẽ làm chương trình thực thi sai hoặc tốn thời gian thực thi vô ích Vì thế không nên sử dụng stack chỉ ñể lưu các biến thông thường Ứng dụng phổ biến nhất của stack là sử dụng trong các chương trình con (Subroutine), khi chúng ta cần “nhảy” từ một vị trí trong chương trình chính ñến 1 chương trình con, sau khi thực hiện chương trình con lại muốn quay về vị trí ban ñầu trong chương trình chính thì Stack là phương cách tối ưu dùng ñể chứa bộ ñếm chương trình trong trường hợp này Xem lại ví dụ trong bài 1, trong chương trình chính chúng ta dùng lệnh RCALL DELAY ñể nhảy ñến ñoạn chương trình con DELAY, RCALL là lệnh nhảy ñến 1 vị trí trong bộ nhớ chương trình, trước khi nhảy, PC ñược cộng thêm 1 và PUSH một cách tự ñộng vào stack Cuối chương trình con DELAY, chúng ta dùng instruction RET, instruction này POP dữ liệu từ stack ra PC một cách tự ñộng, bằng cách này chúng ta có thể quay lại vị trí trước ñó Chính vì các lệnh RCALL và RET sử dụng stack một cách tự ñộng nên ta phải khởi ñộng stack ngay từ ñầu, nếu không chương trình sẽ thực thi sai chức năng
Tóm lại cần khởi ñộng stack ở ñầu chương trình và không nên sử dụng stack một cách tùy thích nếu chưa thật cần thiết
IV Thanh ghi trạng thái – SREG (STATUS REGISTER)
Nằm trong vùng nhớ I/O, thanh ghi SREG có ñịa chỉ I/O là 0x003F và ñịa chỉ bộ nhớ là 0x005F (thường ñây là vị trí cuối cùng của vùng nhớ I/O) là một trong số các thanh ghi quan trọng nhất của AVR, vì thế mà tôi dành phần này ñể giới thiệu về thanh ghi này Thanh ghi SREG chứa 8 bit cờ (flag) chỉ trạng thái của bộ xử lí, tất cả các bit này ñều bị xóa sau khi reset, các bit này cũng có thể ñược ñọc và ghi bởi chương trình Chức năng của từng bit ñược mô tả như sau:
Trang 8Hình 7 Thanh ghi trạng thái
• Bit 0 – C (Carry Flag: Cờ nhớ): là bit nhớ trong các phép ñại số hoặc logic, ví dụ thanh ghi R1 chứa giá trị 200, R2 chứa 70, chúng ta thực hiện phép cộng có nhớ: ADC R1, R2, sau phép cộng, kết quả sẽ ñược lưu lại trong thanh ghi R1, trong khi kết quả thực là 270
mà thanh ghi R1 lại chỉ có khả năng chứa tối ña giá trị 255 (vì có 8 bit) nên trong trường hợp này, giá trị lưu lại trong R1 thực chất chỉ là 14, ñồng thời cờ C ñược set lên 1 (vì 270=100001110, trong ñó 8 bit sau 00001110 =14 sẽ ñược lưu lại trong R1)
• Bit 1 – Z (Zero Flag: Cờ 0): cờ này ñược set nếu kết quả phép toán ñại số hay phép Logic bằng 0
• Bit 2 – N (Negative Flag: Cờ âm): cờ này ñược set nếu kết quả phép toán ñại số hay phép
Logic là số âm
• Bit 3 – V (Two’s complement Overflow Flag: Cờ tràn của bù 2): hoạt ñộng của cờ này có
vẻ sẽ khó hiểu cho bạn vì nó liên quan ñến kiến thức số nhị phân (phần bù), chúng ta sẽ
ñề cập ñến khi nào thấy cần thiết
• Bit 4 – S (Sign Bit: Bit dấu): Bit S là kết quả phép XOR giữa 1 cờ N và V, S=N⊕V
• Bit 5 – H (Half Carry Flag: Cờ nhờ nữa): cờ H là cờ nhớ trong 1 vài phép toán ñại số và phép Logic, cờ này hiệu quả ñối với các phép toán với số BCD
• Bit 6 – T (Bit Copy Storage): ñược sử dụng trong 2 Instruction BLD (Bit LoaD) và BST
(Bit STorage) Tôi sẽ giải thích chức năng Bit T trong phần giới thiệu về BLD và BST
• Bit 7 – I (Global Interrupt Enable : Cho phép ngắt toàn bộ): Bit này phải ñược set lên 1 nếu
trong chương trình có sử dụng ngắt Sau khi set bit này, bạn muốn kích hoạt loại ngắt nào cần set các bit ngắt riêng của ngắt ñó Hai instruction dùng riêng ñể Set và Clear bit I
là SEI và CLI
Chú ý: tất cả các bit trong thanh ghi SREG ñều có thể ñược xóa thông qua các instruction không
toán hạng CLx và set bởi SEx, trong ñó x là tên của Bit.Ví dụ CLT là xóa Bit T và SEI là set bit I
Tôi chỉ giải thích ngắn gọn chức năng của các bit trong thanh ghi SREG, cụ thể chức năng và cách sử dụng của từng bit chúng ta sẽ tìm hiểu trong các trường hợp cụ thể sau này, người ñọc có thể tự tìm hiểu thêm trong các tài liệu về INSTRUCTION cho AVR
Tôi cung cấp thêm 1 bảng tóm tắt sự ảnh hưởng của các phép toán ñại số, logic lên các Bit trong thanh ghi SREG
Trang 9Hình 8 Ảnh hưởng của các phép toán lên SREG
V Giới thiệu một số Imstruction cơ bản
Sau khi tìm hiểu cấu trúc bộ nhớ và phương thức hoạt ñộng của chip, phần này tôi giới thiệu một số instruction mà chúng ta rất hay sử dụng khi lập trình cho AVR Tôi sẽ chia các instruction này ra thành nhiều nhóm dựa theo phạm vi tác ñộng và chức năng của chúng
Trước hết chúng ta thống nhất một số cách sử dụng ký hiệu trong cách viết cú pháp của các instruction như sau:
• Rd: thanh ghi nguồn và cũng là ñích thuộc Register File
• Rr: thanh ghi nguồn thuộc Register File
Khái niệm nguồn (Source), ñích (Destination) là chỉ các toán hạng và kết quả trong
các phép toán ñại số và Logic, ví dụ ADD R1, R2 là lệnh cộng 2 giá trị chứa trong 2
thanh ghi R1, R2, trong trường hợp này cả R1 và R2 ñều ñược gọi là nguồn vì chứa giá trị trước khi thực hiện phép cộng Sau khi phép cộng ñược thực hiện, kết quả ñược chứa lại trong R1 và vì thế R1 ñược gọi là ñích trong trường hợp này R1 vừa
là nguồn, vừa là ñích trong khi R2 chỉ là nguồn, nếu viết ví dụ này dưới dạng tổng quát sẽ là : ADD Rd, Rr
• R: kết quả sau khi lệnh ñược thực thi
• K: hằng số
• k: hằng số chỉ ñịa chỉ tuyệt ñối của thanh ghi
• b: (0 ñến 7) số thứ tự bit trong các thanh ghi của Register File và vùng nhớ I/O
• s: (0 ñến 7) số thứ tự bit trong thanh ghi trạng thái SREG
• X,Y,X: các thanh ghi ñịa chỉ tương ñối (X=R27:R26, X=R29:R28, X=R31:R30)
Trang 10• A: ñịa chỉ I/O
• q: ñộ dịch chuyển của ñịa chỉ tuyệt ñối
1 Instruction chỉ dùng cho Register Files:
- LDI (LoaD Immediate)
• Cú pháp: LDI Rd, K
• Chức năng: Load hằng số K vào thanh ghi Rd
• Giới hạn: chỉ áp dụng cho các thanh ghi từ R16 ñến R31
• Ví dụ: LDI R16, 99 kết quả là thanh ghi R1 mang giá trị 99
- MOV (MOVE)
• Cú pháp: MOV Rd, Rr
• Chức năng: Copy giá trị trong thanh ghi Rr vào thanh ghi Rd
• Giới hạn: áp dụng cho tất cả các thanh ghi trong RF
• Ví dụ: MOV R15, R16 kết quả là R15 có cùng giá trị với R16 (R15=R16=99)
- CLR (CLEAR Register)
• Cú pháp: CLR Rd
• Chức năng: xóa thanh ghi Rd, sau lệnh này thanh ghi Rd=0x00
• Giới hạn: áp dụng cho tất cả các thanh ghi trong RF
• Ví dụ: CLR R16 kết quả là R16 = 0x00
- SER (SET Register)
• Cú pháp: SER Rd
• Chức năng: set tất cả các bit tronh thanh ghi Rd lên 1, sau lệnh này thanh ghi Rd=0xFF
• Giới hạn: chỉ áp dụng cho các thanh ghi từ R16 ñến R31
• Giới hạn: chỉ áp dụng cho các thanh ghi từ R16 ñến R31
• Ví dụ: CBR R16, 0xF0 kết quả là 4 bit cao nhất của R16 bị xóa vì K=11110000 (B)
- SBR (SET Bit in Register)
• Cú pháp: SBR Rd, K
• Chức năng: set các bit trong thanh ghi Rd với “mặt nạ” K, nếu Bit nào trong K là 1 thì Bit tương ứng trong Rd sẽ ñược set lên 1
• Giới hạn: chỉ áp dụng cho các thanh ghi từ R16 ñến R31
• Ví dụ: SBR R16, 0xF0 kết quả là 4 bit cao nhất của R16 ñược set lên 1 vì K=11110000 (B)
- BLD (Bit LoaD from T Flag)
• Cú pháp: BLD Rd, b
• Chức năng: Load giá trị trong cờ T của thanh ghi SREG vào bit thứ b trong thanh ghi
Rd Đây cũng chính là chức năng chính của cờ T
Trang 11• Giới hạn: áp dụng cho tất cả các thanh ghi trong RF
• Ví dụ:
SET ; set bit T lên 1 BLD R16, 4
Kết quả là bit 4 của thanh ghi R16 ñược set lên 1 vì giá trị của bit T là 1
- BST (Bit Storage from T Flag)
• Cú pháp: BST Rd, b
• Chức năng: Copy bit thứ b trong thanh ghi Rd vào trong cờ T của thanh ghi SREG Đây cũng chính là chức năng chính của cờ T
• Giới hạn: áp dụng cho tất cả các thanh ghi trong RF
• Ví dụ: BST R16, 4 kết quả là cờ T chứa giá trị của bit 4 của thanh ghi R16
- CPI (COMPARE with Immediate)
• Cú pháp: CPI Rd, K
• Chức năng: so sánh thanh ghi Rd với hằng số K, lệnh này làm thay ñổi nhiều bit trong thanh ghi SREG trong ñó sự thay ñổi của cờ Zero là quan trọng nhất, nếu Rd = K cờ Z=1, ngược lại Z=0, sử dụng ñặc ñiểm thay ñổi của cờ Z kết hợp với lệnh BRNE hoặc BREQ chúng ta có thể tạo thành một lệnh rẽ nhánh
• Giới hạn: chỉ áp dụng cho các thanh ghi từ R16 ñến R31
• Ví dụ:
LDI R16, 10 CPI R16, 10 Kết quả là cờ Z ñược set thành 1 vì lúc này R16 =10
- ANDI (AND with Immediate)
Kết quả là R1=0xAA vì 11111111 & 10101010 =10101010
- ORI (Logical OR with Immediate)
• Cú pháp: ORI Rd, K
• Chức năng: thực hiện phép Logic OR giữa thanh ghi Rd với hằng số K và kết quả ñặt lại trong Rd
Trang 12• Giới hạn: chỉ áp dụng cho các thanh ghi từ R16 ñến R31
• Giới hạn: áp dụng cho tất cả các thanh ghi trong RF
- LSR (Logical Shift Right)
• Cú pháp: LSR Rd
• Chức năng: dịch tất thanh ghi Rd sang phải 1 vị trí, Bit 0 (bit nhỏ nhất) của Rd sẽ ñược chứa trong cờ nhớ C, bit 7 của Rd bị xóa thành 0 Thực chất LSR tương ñương với phép chia thanh ghi Rd cho 2 Bạn xem hình minh họa bên dưới
• Giới hạn: áp dụng cho tất cả các thanh ghi trong RF
• Ví dụ:
LDI R1, 0B11000110 ; (dạng nhị phân của 195) LSR R1