User Tag List

View Poll Results: Bạn có nghĩ rằng topic này hữu ích đối với bạn và mọi người?

Voters
506. You may not vote on this poll
  • Có, tất nhiên rồi. Mình là người mới học 8051.

    472 93.28%
  • Cũng tạm tạm thôi.

    18 3.56%
  • Không, tất cả những cái này mình biết hết rùi và nó chẳng có ích gì cả.

    5 0.99%
  • Ý kiến khác.

    11 2.17%
Trang 1/10 123 ... cuốicuối
kết quả từ 1 tới 10 trên 98
Cây cảm ơn38Cảm ơn

Ðề tài: Lập trình ASM cho 8051

  
  1. #1
    Moderator ngohaibac's Avatar
    Tham gia
    Sep 2005
    Nơi Cư Ngụ
    BKHN
    Bài viết
    598
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Lập trình ASM cho 8051

    Mình mở topic này với mong muốn các bạn thảo luận về tệp lệnh và thuật giải cho các bài toán cụ thể.

    Mình nghĩ rằng điều đó thực sự là cần thiết với các bạn mới học vi điều khiển qua đó có tư duy thuật toán rất là rõ ràng.

    Do đó, mình yêu cầu ai post trong này cần ghi rõ giải thuật và chú thích lệnh rõ ràng. Vì thực tế lấy một đoạn code rồi post lên thì chẳng có ý nghĩa gì cả.

    Topic này cũng rất là có tác dụng cho các bạn trong các kì thi Kỹ thuật vi xử lý đó. Bản thân mình học 8051 chỉ sơ sơ, không viết nhiều ứng dụng lắm, đặc biệt là bằng 8051 mà chỉ toàn bằng C thôi. Quan trọng là mình biết nếu lập trình một cái thì mình tìm ở đâu, học ở chỗ nào thôi Click here to enlarge. Trường mình kì này mới dạy 8051 nên phải viết nhiều nhiều để thi nên tiện viết luôn cho các bạn Click here to enlarge.

    Mình có upload tệp lệnh của bọn Atmel lên đây.
    http://www.tailieuvietnam.net/downlo...tion%20Set.pdf

    Đề nghị anh em không được post spam trong đây. Nếu ai không biết cần đặt câu hỏi cụ thể và người trả lời phải cụ thể, nếu có hình minh họa là tốt nhất. Tránh việc cứ hỏi đi hỏi lại mệt lắm.

    Các bạn dùng Keil C để viết chương trình nhé:
    http://www.tailieuvietnam.net/downlo...ac/C51v805.zip

    Và chíp ban đầu mình và các bạn sử dụng để viết những bài đơn giản là con 89S52.8051 tệp lệnh là giống nhau chọn con nào cũng ok.Con 89S52 có nhiều điểm mạnh như có 3 timer, 256 byte RAM on chip... :
    8051 based Full Static CMOS controller with Three-Level Program
    Memory Lock, 32 I/O lines, 3 Timers/Counters, 8 Interrupts Sources,
    Watchdog Timer, 2 DPTRs, 8K Flash Memory, 256 Bytes On-chip RAM.
    Chúc mọi người thành công.

    CHỦ ĐỀ TƯƠNG TỰ:

    Last edited by ngohaibac; 28-12-06 at 16:55.
    LTS, hoaln, trunghoa1 người nữa đã cảm ơn nội dung này.
    Tel. +84-(0) - 915 560 511
    SmartGrid Technology Company
    Email : ngohaibac AT gmail DOT com

  2. #2
    Moderator ngohaibac's Avatar
    Tham gia
    Sep 2005
    Nơi Cư Ngụ
    BKHN
    Bài viết
    598
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Form chuẩn của chương trình ASM

    Đầu tiên mình xin giới thiệu dạng form của chương trình ASM theo form chuẩn của www.picvietnam.com. Các bạn nên đọc để hiểu rõ mục đích của cách viết nhé. Nếu viết rõ ràng thì sẽ rất là đơn giản khi debug đó bạn ạ.

    http://picvietnam.com/forum/showthread.php?t=5

    Code:
    ;========================================================
    ; Ten chuong trinh	: 
    ; Nguoi thuc hien	: Ngo Hai Bac
    ; Ngay thuc hien	: 28/12/06
    ; Phien ban	: 1.0
    ; Mo ta phan cung	: Dung AT89S52 - thach anh 11.0592 MHZ
    ;----------------------------------------------------------------
    ; Ngay hoan thanh	: 
    ; Ngay kiem tra	: 
    ; Nguoi kiem tra	: Ngo Hai Bac
    ;----------------------------------------------------------------
    ; Chu thich	: Mo ta cac diem khac nhau cua cac phien ban khac nhau 
    ;		: hoac cac chu thich khac
    ;		: vd, dung che do Power On Reset, PORTB = 00000000
    ;		: hoac, chuong trinh viet cho PIC Tutorial
    ;		: hoac, chuong trinh nay hoan toan mien phi va co the dung cho
    ;		: moi muc dich khac nhau
    ;========================================================;========================================================
    
    		org		000h			; Reset
    		nop
    		ljmp 	Start
    	
    		org 	003h			; Int EX0
    		nop
    		reti
    	
    		org 	00bh		   	; Int Timer0
    		nop
    		reti
    	
    		org		013h			; Int EX1
    		nop 
    		reti
    	
    		org 	01bh			; Int Timer1
    		nop
    		reti
    		
    		org 	023h			; Int Communication
    		nop 
    		reti
    	
    ;====================================================================
    		stack	equ		2fh
    ;====================================================================
    ; 					Main Program
    ;====================================================================
    		org 	4bh
    
    ;  chuong trinh viet o day
    
    ;====================================================================
    ; Cac chuong trinh con viet o day
    ;====================================================================
    
    		end.
    Chúc các bạn thành công.

    PHUC, LTS, vulongdt101 người nữa đã cảm ơn nội dung này.
    Tel. +84-(0) - 915 560 511
    SmartGrid Technology Company
    Email : ngohaibac AT gmail DOT com

  3. #3
    Thành viên tích cực vinhsnooker's Avatar
    Tham gia
    May 2006
    Nơi Cư Ngụ
    Hà Nội
    Bài viết
    142
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Click here to enlarge Nguyên văn bởi ngohaibac Click here to enlarge
    Đầu tiên mình xin giới thiệu dạng form của chương trình ASM theo form chuẩn của www.picvietnam.com. Các bạn nên đọc để hiểu rõ mục đích của cách viết nhé. Nếu viết rõ ràng thì sẽ rất là đơn giản khi debug đó bạn ạ.

    http://picvietnam.com/forum/showthread.php?t=5

    Code:
    ;========================================================
    ; Ten chuong trinh	: 
    ; Nguoi thuc hien	: Ngo Hai Bac
    ; Ngay thuc hien	: 28/12/06
    ; Phien ban	: 1.0
    ; Mo ta phan cung	: Dung AT89S52 - thach anh 11.0592 MHZ
    ;----------------------------------------------------------------
    ; Ngay hoan thanh	: 
    ; Ngay kiem tra	: 
    ; Nguoi kiem tra	: Ngo Hai Bac
    ;----------------------------------------------------------------
    ; Chu thich	: Mo ta cac diem khac nhau cua cac phien ban khac nhau 
    ;		: hoac cac chu thich khac
    ;		: vd, dung che do Power On Reset, PORTB = 00000000
    ;		: hoac, chuong trinh viet cho PIC Tutorial
    ;		: hoac, chuong trinh nay hoan toan mien phi va co the dung cho
    ;		: moi muc dich khac nhau
    ;========================================================;========================================================
    
    		org		000h			; Reset
    		nop
    		ljmp 	Start
    	
    		org 	003h			; Int EX0
    		nop
    		reti
    	
    		org 	00bh		   	; Int Timer0
    		nop
    		reti
    	
    		org		013h			; Int EX1
    		nop 
    		reti
    	
    		org 	01bh			; Int Timer1
    		nop
    		reti
    		
    		org 	023h			; Int Communication
    		nop 
    		reti
    	
    ;====================================================================
    		stack	equ		2fh
    ;====================================================================
    ; 					Main Program
    ;====================================================================
    		org 	4bh
    
    ;  chuong trinh viet o day
    
    ;====================================================================
    ; Cac chuong trinh con viet o day
    ;====================================================================
    
    		end.
    Chúc các bạn thành công.
    hay qua s co mình tham gia với nhé!

    LTS đã cảm ơn nội dung này.

  4. #4
    Thành viên tích cực vinhsnooker's Avatar
    Tham gia
    May 2006
    Nơi Cư Ngụ
    Hà Nội
    Bài viết
    142
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Chương trình đo dộ rộng xung

    Trước đây mình có làm bào tập về đo độ rộng xung,mình sử dụng thuật toán là sử dụng timer,cho đếm khi có tín hiệu vào,và dừng timer khi kết thúc tín hiệu,mình sử dung 8951,như vậy timer là 16 bit,giá trị mã đếm được là 16bit tương đương với giá trị là 65535us,bạn nào có thuật toán hay hơn không,để có thể đếm được giá trị lớn hơn 16bit!

    duy hai đã cảm ơn nội dung này.

  5. #5
    Moderator ngohaibac's Avatar
    Tham gia
    Sep 2005
    Nơi Cư Ngụ
    BKHN
    Bài viết
    598
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Rất đơn giản, bạn có thể đếm độ rộng xung dài bất kì bằng ngắt:

    + Khi nào timer tràn thì tăng một biến Index nào đó, biến này đếm số lần tràn của Timer

    Do đó thời gian bạn đo sẽ bằng = Index * 65535us + sô giây trong timer.

    Thế là xong :d. Chúc bạn thành công.

    LTS đã cảm ơn nội dung này.
    Tel. +84-(0) - 915 560 511
    SmartGrid Technology Company
    Email : ngohaibac AT gmail DOT com

  6. #6
    Moderator ngohaibac's Avatar
    Tham gia
    Sep 2005
    Nơi Cư Ngụ
    BKHN
    Bài viết
    598
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Chi tiết về không gian nhớ của 8051 các bạn có thể xem ở đây:
    http://dientuvietnam.net/forums/show...t=1163&page=24

    Các bài viết của mình dưới đây có thể chưa tối ưu, mong sự góp ý của các bạn vê thuật giải cũng như cách viết để cho mình thi tốt trong kì thi tới Click here to enlarge.

    1/Bài 1: Cộng hai số 5 byte, yêu cầu và cách làm mình đều viết trong chương trình:

    Code:
    ;========================================================
    ; Ten chuong trinh	: Cong 2 so 5 bytes
    ; Nguoi thuc hien	: Ngo Hai Bac
    ; Ngay thuc hien	: 29/12/06
    ; Phien ban	: 1.0
    ; Mo ta phan cung	: Dung AT89S52 - thach anh 11.0592 MHZ
    ;----------------------------------------------------------------
    ; Ngay hoan thanh	: 29/12/06
    ; Ngay kiem tra	: 
    ; Nguoi kiem tra	: Ngo Hai Bac
    ;----------------------------------------------------------------
    ; Chu thich	: Chuong trinh don gian dung cho thi cu
    ;			Hai so hang deu trong bo nho, ket qua cat vao so hang dau
    ;			Chu y: MSB duoc cat vao o co dia chi nho
    ;			So I: 49 50 51 52 53 54
    ;			So II:   60 61 62 63 64 
    ; O nho 49 dung luu so nho tu phep cong truoc neu co tran
    ;========================================================
    
    		ORG	00h			; Reset
    		NOP
    		LJMP 	Start
    	
    		ORG 	003h			; Int EX0
    		NOP
    		RETI
    	
    		ORG 	0bh		   	; Int Timer0
    		NOP
    		RETI
    	
    		ORG	13h			; Int EX1
    		NOP 
    		RETI
    	
    		ORG 	1bh			; Int Timer1
    		NOP
    		RETI
    		
    		ORG 	23h			; Int Communication
    		NOP 
    		RETI
    	
    ;====================================================================
    		stack	equ		2fh
    ;====================================================================
    ; 					Main Program
    ;====================================================================
    		ORG 	4bh
    
    Start:  	PUSH 	00h
    		PUSH	01h
    		PUSH 	02h			; Cat R0, R1, R2 vao Stack
    
    		MOV 	R0,	#54h
    		MOV	R1,	#64h
    		MOV	R2,	#5
    		CLR 	C			;Xua co nho C
    
    Loop:	CLR		A		 	; Xoa thanh ghi Accumulator
    		MOV	A,	@R0		; A = du lieu co dia chi = R0
    		ADDC	A,	@R1		; A = A + @R1 + C  
    		MOV	@R0,A		; Cat ket qua vao byte so thu nhat
    		DEC	R0		 	; R0 = R0  - 1
    		DEC	R1			; R1 = R1 - 1
    		DJNZ	R2,	Loop	; Giam R2 va kiem tra neu R2 #0 thi nhay ve Loop, 
    							; = 0 thi chay tiep
    				
    		RLC	A			; Quay trai A voi bit C => A = C
    		MOV	@R0,A		; O nho 49h co gia tri = C
    		POP	02h
    		POP	01h
    		POP	00h
    
    		END.
    Mình xin giải thích cách làm:
    2 số 5 byte là:
    Code:
    b5 b4 b3 b2 b1 b0
        a4 a3 a2 a1 a0
    (mõi số là số 1 byte)

    với mỗi cặp tương ứng (bi, ai) thì chúng ta cộng như sau:
    tổng = ai + bi + nhớ từ phép cộng của hàng trước;
    nếu tổng >0xFF thì nhớ sang hàng tiếp theo và bi = tổng - 0xFF
    nếu tổng <0xFF thì gán bi = tổng

    Điều này thực hiện dễ dàng bằng lệnh ADDC, khi có nhớ từ bit 7 thì sẽ set cờ nhớ C, không nhớ thì nó sẽ tự xóa cờ nhớ này. Do đó C như là số nhớ từ phép tính trước.Vì nó tự động xóa hoặc set nên không cần xóa Nên chỉ cần dùng như sau:
    Code:
    ; R0 là địa chỉ của bi
    ; R1 là địa chỉ của ai
    MOV   A, @R0
    ADDC  A, @R1
    MOV   @R0, A
    Như vậy cần thực hiện 5 vòng lặp. Có nhiều cách lặp, mình sử dụng kiểu Do.. While; (trong C);
    Code:
    index = m; // m = const
    Do{
    // Làm việc gì đó
    index -- ;
    } while (index>0)
    Tướng ứng trong ASM:
    Code:
    MOV  R2,#5  ; gán R2 = 5
    
    LOOP:
    
    ; do something
    
              DJNZ  R2,LOOP  ; Giảm R2, nếu chưa = 0 thì nhảy đến Loop
    DJNZ: Decrease and Jump if Not Equal

    Chi tiết hơn về các lệnh anh em xem trong tệp lệnh nhé. Rảnh thì mình sẽ viết luôn cả code C cho anh em so sánh nhé :d.

    Chúc anh em thành công.

    Last edited by ngohaibac; 30-12-06 at 01:22.
    LTS, haunobita, Ck33spkt1 người nữa đã cảm ơn nội dung này.
    Tel. +84-(0) - 915 560 511
    SmartGrid Technology Company
    Email : ngohaibac AT gmail DOT com

  7. #7
    Moderator ngohaibac's Avatar
    Tham gia
    Sep 2005
    Nơi Cư Ngụ
    BKHN
    Bài viết
    598
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    2/ Chương trình con

    Một chương trình con trong 8051 thực chất là tập hợp các công việc được thực hiện tại một địa chỉ nhất định trong ROM. Trong main khi gọi tới chương trình con thì chương trình sẽ tăng con trỏ PC lên 1, đồng thời cất địa chỉ PC vào stack.Nó sẽ lấy lại giá trị đó khi kết thúc chương trình nhờ lệnh RET (Return).

    Chương trình con dùng các biến vào và ra là các thanh ghi, do đó nó như là kiểu dùng biến toàn cục trong C vậy.

    Sau đây là chương trình đảo dấu n byte trong bộ nhớ:

    Code:
    	 ;========================================================
    ; Ten chuong trinh	: Hoan thien chuong trinh con dao dau n byte trong bo nho
    ; Nguoi thuc hien	: Ngo Hai Bac
    ; Ngay thuc hien	: 29/12/06
    ; Phien ban	: 1.0
    ; Mo ta phan cung	: Dung AT89S52 - thach anh 11.0592 MHZ
    ;----------------------------------------------------------------
    ; Ngay hoan thanh	: 29/12/06
    ; Ngay kiem tra	: 
    ; Nguoi kiem tra	: Ngo Hai Bac
    ;----------------------------------------------------------------
    ; Chu thich	: Chuong trinh don gian dung cho thi cu
    ;			Dao dau n byte trong bo nho có địa chỉ <256
    ;			
    ;			Input: R0: dia chi dau
    ;				   R1: dia chi cuoi
    ;			Thuc hien: dao dau tung byte mot
    ;			
    ;========================================================
    Swap_signed:
    			PUSH	02H			
    
    			MOV		02H,	R1   ; R2 = R1
    			DEC		R2	 	; R2 = R2 -1
    			   	
    Loop:		    INC		R2		; Tang R2	
    			
    			MOV		A,	@R2	; A = data trong R2
    			CPL		A		; Dao bit cua A
    			INC		A		; Tang A len 1 don vi
    
    			MOV		@R2,A	; Gan lai gia tri vao o nho do
    
    			MOV		A,	R2
    			XRL		A,	R1	 ; A = R1 or R2 => Neu A = 0 thi R1 = R2
    
    			JNZ		Loop               ; nhảy nếu A khác 0
    
    			POP		02H			
    
    		        RET
    Đảo dấu 1 byte bằng cách lấy số bù 2 của nó.

    Chúc bạn thành công.

    Last edited by ngohaibac; 30-12-06 at 17:40.
    LTS, muachanhchinbknguyen đã cảm ơn nội dung này.
    Tel. +84-(0) - 915 560 511
    SmartGrid Technology Company
    Email : ngohaibac AT gmail DOT com

  8. #8
    Moderator ngohaibac's Avatar
    Tham gia
    Sep 2005
    Nơi Cư Ngụ
    BKHN
    Bài viết
    598
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Vòng lặp For

    Ngẫu hứng viết vài kiểu vòng lặp. Mình suy nghĩ lấy nên k biết có ổn lắm không. Mong các bạn cho ý kiến nhé.

    Sau đây là vòng lặp for trong C và dịch sang ASM.
    Code:
    unsigned char i;
    for(i = n_begin; i< n_end; i++){
    	// do something
    }
    // continue
    Đầu tiên i = n_begin; sau đó thực hiện lệnh trong vòng lặp.
    Thử điều kiện i<n_end, nếu true thì tăng i và tiếp tục.
    Nếu i= n_end rùi thì tiếp tục chạy và làm các công việc sau vòng lặp.

    Code:
    ; Code asm
    		n_begin equ     1
    		n_end	equ	100
    	
    		MOV	R0,	#n_begin
    		MOV	R1,	#n_end
    
    Loop:	    ; Do something here
    		
    		MOV	A,	R0
    		CJNE	A,	R1,	Loop1 ; nếu A không = R1 thì nhảy đến Loop1
    		SJMP	Loop2                   ; A = R1 thì nhảy đến  loop2
    			
    Loop1:	     INC      R0	
    		SJMP	Loop
    Loop2:	; continue
    Nếu bạn thay n<n_end bằng điều kiện khác thì cấu trúc vẫn thế, vẫn jmp đến loop1, chỉ thay đổi điều kiện nhảy thôi.

    Chúc các bạn thành công.

    winsieutocTrường Sơn đã cảm ơn nội dung này.
    Tel. +84-(0) - 915 560 511
    SmartGrid Technology Company
    Email : ngohaibac AT gmail DOT com

  9. #9
    Moderator ngohaibac's Avatar
    Tham gia
    Sep 2005
    Nơi Cư Ngụ
    BKHN
    Bài viết
    598
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sau đây, mình chỉ upload lên đoạn chương trình thôi chứ không viết cả chương trình, cả chương trình là tập hợp các đoạn lệnh thôi, không có gì cả.

    Đây là các đoạn lệnh dùng để thi cử mà. Nếu tiện, mình sẽ viết mấy chương trình ứng dụng nạp chip để test hoặc mô phỏng.

    Đây là chương trình nhân B với số 24 bit.

    Code:
    ;========================================================
    ; Ten chuong trinh	: Nhan B voi so 24 bit
    ; Nguoi thuc hien	: Ngo Hai Bac
    ; Ngay thuc hien	: 30/12/06
    ; Phien ban	: 1.0
    ; Mo ta phan cung	: Dung AT89S52 - thach anh 11.0592 MHZ
    ;----------------------------------------------------------------
    ; Ngay hoan thanh	: 30/12/06
    ; Ngay kiem tra	: 
    ; Nguoi kiem tra	: Ngo Hai Bac
    ;----------------------------------------------------------------
    ; Chu thich	: Chuong trinh don gian dung cho thi cu
    ;			So 24 bit co dia chi A2 - A1 - A0	  (A0 <A1 <A2)
    ;			Ket qua dc ghi vao dia chi: Z3 - Z2 - Z1 - Z0  (Z0 < Z1 < Z2 <Z3)
    ;========================================================
    ; khai bao cac hang so
    
    		A0		equ		30h
    		;... Cac ban tu khai bao nhe.
    ;=========================================================
     
     
     		MOV	R0,	A0
    		DEC	R0
    		MOV	R1,	Z0
    		MOV	@R1,	#00h	; Xoa o nho Z0
    		MOV	B,	#15h	; Thi du B = 15h
    
    		MOV	R2,	B
    
    Loop:	MOV		A,	@R0
    		MOV	B,	R2
    		MUL	AB		   	; Nhan B voi Ai
    		
    		ADD	A,		@R1	 ;Cong byte thap vao trong o nho Zi
    		MOV	@R1,	A	 ;Gan lai Zi
    
    		INC	R1			; Tang R1
    
    		MOV	@R1,	B	 ; Ghi byte cao cua ket qua vao
    
    		INC	R0
    		MOV	A,	R0
    
    		CJNE	A,	#A2,Loop ; Neu R0 # A2 thi nhay den Loop
    
    		MOV	B, 	R2	 ; Gan lai B
    Chúc các ban thành công.

    LTS, tlktdanngu đã cảm ơn nội dung này.
    Tel. +84-(0) - 915 560 511
    SmartGrid Technology Company
    Email : ngohaibac AT gmail DOT com

  10. #10
    Thành viên tích cực vinhsnooker's Avatar
    Tham gia
    May 2006
    Nơi Cư Ngụ
    Hà Nội
    Bài viết
    142
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Click here to enlarge Nguyên văn bởi ngohaibac Click here to enlarge
    Rất đơn giản, bạn có thể đếm độ rộng xung dài bất kì bằng ngắt:

    + Khi nào timer tràn thì tăng một biến Index nào đó, biến này đếm số lần tràn của Timer

    Do đó thời gian bạn đo sẽ bằng = Index * 65535us + sô giây trong timer.

    Thế là xong :d. Chúc bạn thành công.
    mình cũng suy nghĩ như bạn,nhưng mình đang bị vướng vào phần nhân một số bất kỳ với một số 16 bit, giả dụ như cái index mình có được là số nằm trong dải số 8bit,nếu bạn có thuật toán thì hướng dẫn mình nhé


Trang 1/10 123 ... cuốicuối

Quyền Sử Dụng Ở Diễn Ðàn

  • Bạn không được gửi luồng mới
  • Bạn không được trả lời bài viết
  • Bạn không được gửi file đính kèm
  • Bạn không được sửa bài viết của mình
  •