![]() |
|
Tài trợ cho PIC Vietnam |
||||||||
| 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 |
|
|
#1 |
|
Nhập môn đệ tử
Tham gia ngày: Oct 2007
Bài gửi: 4
: |
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
}
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
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. |
|
|
|
|
|