PIC Vietnam

Go Back   PIC Vietnam > Microchip PIC > dsPIC - Bộ điều khiển tín hiệu số 16-bit

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Tìm Kiếm Bài Trong Ngày Ðánh Dấu Ðã Ðọc Vi điều khiển

dsPIC - Bộ điều khiển tín hiệu số 16-bit Theo dự kiến của Microchip, vào khoảng năm 2011 dsPIC sẽ có doanh số lớn hơn PIC

 
 
Ðiều Chỉnh Xếp Bài
Prev Previous Post   Next Post Next
Old 10-05-2008, 07:35 PM   #1
hanhthien184
Nhập môn đệ tử
 
Tham gia ngày: Oct 2007
Bài gửi: 4
:
Red face Nhờ các bác giải quyết một vấn đề về ngắt

Em sử dụng dsPIC33FJ256GP710 cấu hình hoạt động ở 40MIPS.
Hàm phục vụ ngắt (ngắt ngoài INT4) của em như sau:
Code:
    void interrupt_int4() org 0x80 {        //When ADS is asserted
            addr_select = PORTA;
            addr_select &= 0x3F;
            if (addr_select == 0)
            {
            LATD = ADC_1;                   //ADC_1
            LATFbits.LATF0 = 0;             //LRDYi active
            LATFbits.LATF0 = 1;             //LRDYi inative
            }
            else if (addr_select == 2)
            {
            LATD = ADC_2;                   //ADC_2
            LATFbits.LATF0 = 0;             //LRDYi active
            LATFbits.LATF0 = 1;             //LRDYi inative
           }
           else
            {
           LATD = addr_select;
           LATFbits.LATF0 = 0;             //LRDYi active
           LATFbits.LATF0 = 1;             //LRDYi inative
           }
          IFS3bits.INT4IF = 0;              //ensure interrupt not pending
          }
Yêu cầu của trình phục vụ ngắt này phải thực hiện trong thời gian rất ngắn (khoảng 0.5us).
Tuy nhiên khi viết chương trình với C (MikroC) thì nó tự động push tất cả các thanh ghi làm việc nên mất khá nhiều chu kỳ lệnh:
View assembly của chương trình trên ta thấy:
Code:
$0200	$	_interrupt_int4:
$0200	$F80036			PUSH	RCOUNT
$0202	$781F80			PUSH	W0
$0204	$200020			MOV	#2, W0
$0206	$09000C			REPEAT	#12
$0208	$781FB0			PUSH	[W0++]
;INT_TEST.c,15 :: 		void interrupt_int4() org 0x80 {        //When ADS is asserted
;INT_TEST.c,16 :: 		addr_select = PORTA;
$020A	$801610			MOV	PORTA, W0
$020C	$8A2000			MOV	W0, _addr_select
;INT_TEST.c,17 :: 		addr_select &= 0x3F;
$020E	$2003F1			MOV	#63, W1
$0210	$244000			MOV	#@_addr_select, W0
$0212	$608090			AND	W1, [W0], W1
$0214	$8A2001			MOV	W1, _addr_select
;INT_TEST.c,18 :: 		if (addr_select == 0)
$0216	$508060			SUB	W1, #0, W0
$0218	$3A000A			BRA NZ	L_interrupt_int4_0, L_interrupt_int4_0
;INT_TEST.c,20 :: 		LATD = ADC_1;                   //ADC_1
$021A	$822010			MOV	_ADC_1, W0
$021C	$8816B0			MOV	W0, LATD
;INT_TEST.c,21 :: 		LATFbits.LATF0 = 0;             //LRDYi active
$021E	$2FFFE1			MOV	#65534, W1
$0220	$202E20			MOV	#@LATFbits+0, W0
$0222	$608810			AND	W1, [W0], [W0]
;INT_TEST.c,22 :: 		LATFbits.LATF0 = 1;             //LRDYi inative
$0224	$200011			MOV	#1, W1
$0226	$202E20			MOV	#@LATFbits+0, W0
$0228	$708810			IOR	W1, [W0], [W0]
;INT_TEST.c,23 :: 		}
$022A	$040258			GOTO	L_interrupt_int4_1
$022E	$	L_interrupt_int4_0:
;INT_TEST.c,24 :: 		else if (addr_select == 2)
$022E	$822001			MOV	_addr_select, W1
$0230	$508062			SUB	W1, #2, W0
$0232	$3A000A			BRA NZ	L_interrupt_int4_2, L_interrupt_int4_2
;INT_TEST.c,26 :: 		LATD = ADC_2;                   //ADC_2
$0234	$822020			MOV	_ADC_2, W0
$0236	$8816B0			MOV	W0, LATD
;INT_TEST.c,27 :: 		LATFbits.LATF0 = 0;             //LRDYi active
$0238	$2FFFE1			MOV	#65534, W1
$023A	$202E20			MOV	#@LATFbits+0, W0
$023C	$608810			AND	W1, [W0], [W0]
;INT_TEST.c,28 :: 		LATFbits.LATF0 = 1;             //LRDYi inative
$023E	$200011			MOV	#1, W1
$0240	$202E20			MOV	#@LATFbits+0, W0
$0242	$708810			IOR	W1, [W0], [W0]
;INT_TEST.c,29 :: 		}
$0244	$040258			GOTO	L_interrupt_int4_3
$0248	$	L_interrupt_int4_2:
;INT_TEST.c,32 :: 		LATD = addr_select;
$0248	$822000			MOV	_addr_select, W0
$024A	$8816B0			MOV	W0, LATD
;INT_TEST.c,33 :: 		LATFbits.LATF0 = 0;             //LRDYi active
$024C	$2FFFE1			MOV	#65534, W1
$024E	$202E20			MOV	#@LATFbits+0, W0
$0250	$608810			AND	W1, [W0], [W0]
;INT_TEST.c,34 :: 		LATFbits.LATF0 = 1;             //LRDYi inative
$0252	$200011			MOV	#1, W1
$0254	$202E20			MOV	#@LATFbits+0, W0
$0256	$708810			IOR	W1, [W0], [W0]
;INT_TEST.c,35 :: 		}
$0258	$	L_interrupt_int4_3:
$0258	$	L_interrupt_int4_1:
;INT_TEST.c,36 :: 		IFS3bits.INT4IF = 0;              //ensure interrupt not pending
$0258	$2FFBF1			MOV	#65471, W1
$025A	$2008A0			MOV	#@IFS3bits+0, W0
$025C	$608810			AND	W1, [W0], [W0]
;INT_TEST.c,37 :: 		}
$025E	$	L_end__interrupt_int4:
$025E	$2001A0			MOV	#26, W0
$0260	$09000C			REPEAT	#12
$0262	$78104F			POP	[W0--]
$0264	$78004F			POP	W0
$0266	$F90036			POP	RCOUNT
$0268	$064000			RETFIE
?Có cách nào cải thiện được tốc độ của ngắt (có thể không push các thanh ghi không cần thiết trong trình phục vụ ngắt)bằng MikroC là tốt nhất (hoặc chuyển sang C30 cũng được)
vì chương trình của em rất lớn nên nếu chuyển tất cả sang ASM thì không đủ thời gian thực hiện.
=>Các bác nào có hướng giải quyết nào hay giúp em với.
hanhthien184 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
 

Ðiều Chỉnh
Xếp Bài

Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến


Múi giờ GMT. Hiện tại là 09:32 PM.


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam