PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   dsPIC - Bộ điều khiển tín hiệu số 16-bit (http://www.picvietnam.com/forum/forumdisplay.php?f=29)
-   -   nhờ xe, giúp e (http://www.picvietnam.com/forum/showthread.php?t=7323)

robotpic 05-11-2010 12:27 AM

nhờ xe, giúp e
 
e viêt chương trình sau có 2 lổi e chưa hiểu nguyên nhân:

đặt câu hỏi trước gởi code sau:

chương trình e dùng ngắt ngoài chân rc3 rc4 rc5 của pic 4331 để đọc encoder

câi 1: nếu encoder quay thì xung tang theo theo tốc đọ của encoder , nhưng mà e không quay encoder thì nó cũng tăng lên?
câu 2: còng if nếu e viết :
while(TRUE)
{
IF(XUNG>1000||xung1>1000||xung2>1000) RA0=0;
else IF(XUNG>1200||xung1>1200||xung2>1200) RA1=0;
else IF(XUNG>1300||xung1>1300||xung2>1300) RA2=0;
else IF(XUNG>1400||xung1>1400||xung2>1400) RA3=0;
else IF(XUNG>1500||xung1>1500||xung2>1500) RA4=0;
else IF(XUNG>1600||xung1>1600||xung2>1600) RA5=0;
else IF(XUNG>2000||xung1>2000||xung2>2000) CT_PWM_POWER();
else IF(XUNG>3000||xung1>3000||xung2>3000) CT_PWM_CCP ();
else IF(XUNG>3000||xung1>3000||xung2>3000)
{
RD0=0;
DELAY_MS(500);
RD1=0;
DELAY_MS(500);
RD2=0;
DELAY_MS(500);
RD3=0;
DELAY_MS(500);
RD4=0;
DELAY_MS(500);
}
}
thì nó khi encoder quay mấy vòng đi chăng nữa nó cũng chỉ dừng lệnh if đầu tiên tức chỉ có ra0 sáng.

còn khí e viết như thế nầy thì nhận hết ok:
while(TRUE)
{
IF(XUNG>1000||xung1>1000||xung2>1000) RA0=0;
IF(XUNG>1200||xung1>1200||xung2>1200) RA1=0;
IF(XUNG>1300||xung1>1300||xung2>1300) RA2=0;
IF(XUNG>1400||xung1>1400||xung2>1400) RA3=0;
IF(XUNG>1500||xung1>1500||xung2>1500) RA4=0;
IF(XUNG>1600||xung1>1600||xung2>1600) RA5=0;
IF(XUNG>2000||xung1>2000||xung2>2000) CT_PWM_POWER();
IF(XUNG>3000||xung1>3000||xung2>3000) CT_PWM_CCP ();
IF(XUNG>3000||xung1>3000||xung2>3000)
{
RD0=0;
DELAY_MS(500);
RD1=0;
DELAY_MS(500);
RD2=0;
DELAY_MS(500);
RD3=0;
DELAY_MS(500);
RD4=0;
DELAY_MS(500);
}
}


đây là toàn bộ code của e:


#include <18f4331.h>
#INCLUDE <def_4331.h>

#FUSES HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT,NOPUT,NOCPD,NO DEBUG,NOFCMEN,NOCPB,STVREN,NOPWMPIN,HPOL_LOW
#FUSES MCLR,NOWINEN,NOIESO,NOWRTC,NOWRTB,NOWRTD,NOEBTR,NO WRT,NOEBTRB,EXCLKD0,T1STANDARD

#use delay(clock=20000000)

#use fast_io(a)
#use fast_io(d)
#use fast_io(c)
#use fast_io(e)

long XUNG,XUNG1,XUNG2;

#INT_EXT //RC3
VOID DEM_NGAT()
{
XUNG++;
return ;
}

#INT_EXT1 //RC4
VOID DEM_NGAT_1()
{
XUNG1++;
return ;
}

#INT_EXT2 //RC5

VOID DEM_NGAT_2()
{

XUNG2++;
return;
}

VOID CT_PWM_POWER()
{
SET_POWER_PWM0_DUTY(100);

SET_POWER_PWM2_DUTY(500);

SET_POWER_PWM4_DUTY(200);

SET_POWER_PWM6_DUTY(500);

}
VOID CT_PWM_CCP ()
{

SET_PWM2_DUTY(250);
SET_PWM1_DUTY(500);
}


void main()
{
trisa=0x00;
porta=0xff;

trisb=0x00;
portb=0x00;

trisc=0b00111000;
portC=0x0f;

trisd=0x00;
portd=0xff;

trise=0x00;
porte=0xff;

setup_power_pwm_pins( PWM_ODD_ON,PWM_ODD_ON,PWM_ODD_ON,PWM_ODD_ON);
setup_power_pwm(PWM_CLOCK_DIV_4|PWM_FREE_RUN,1,0,1 24,0,1,0);
set_power_pwm_override(1, false, 0);
set_power_pwm_override(3, false, 0);
set_power_pwm_override(5, false, 0);
set_power_pwm_override(7, false, 0);

SETUP_CCP1(CCP_PWM);
SETUP_CCP2(CCP_PWM);
setup_timer_2(T2_DIV_BY_4,124,1);

enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT);
enable_interrupts(INT_EXT1);
enable_interrupts( INT_EXT2);
ext_int_edge(0, L_TO_H );
ext_int_edge(1, L_TO_H );
ext_int_edge(2, L_TO_H );


xung=0;
xung1=0;
xung2=0;

while(TRUE)
{
IF(XUNG>1000||xung1>1000||xung2>1000) RA0=0;
IF(XUNG>1200||xung1>1200||xung2>1200) RA1=0;
IF(XUNG>1300||xung1>1300||xung2>1300) RA2=0;
IF(XUNG>1400||xung1>1400||xung2>1400) RA3=0;
IF(XUNG>1500||xung1>1500||xung2>1500) RA4=0;
IF(XUNG>1600||xung1>1600||xung2>1600) RA5=0;
IF(XUNG>2000||xung1>2000||xung2>2000) CT_PWM_POWER();
IF(XUNG>3000||xung1>3000||xung2>3000) CT_PWM_CCP ();
IF(XUNG>3000||xung1>3000||xung2>3000)
{
RD0=0;
DELAY_MS(500);
RD1=0;
DELAY_MS(500);
RD2=0;
DELAY_MS(500);
RD3=0;
DELAY_MS(500);
RD4=0;
DELAY_MS(500);
}
}

}

falleaf 05-11-2010 09:19 AM

Viết code như vậy nó chạy vậy thì chả có gì lạ. Nhưng không có thời gian sửa lỗi cho bạn, chỉ nói sơ bạn biết lỗi ngay.

Trường hợp 1, nếu bạn viết dạng if XUNG > và ELSE IF thì tất nhiên nếu XUNG lớn hơn 1000, thì lúc nào nó cũng đã lớn hơn 1000 rồi, nên nó chỉ chạy cái IF đầu tiên.

Trường hợp 2, khi bạn viết một loạt IF, thì nó kiểm đúng XUNG > 1000, sau đó nó kiểm tiếp xem XUNG có lớn hơn 1200 không, nếu lớn hơn 1200 thì nó thực thi RA1 = 0. Vậy nên bạn nhận được kết quả đúng như mong đợi.

Code của bạn viết bản thân không hiểu rõ về code nên dẫn tới sai lung tung.

Nếu chưa quen viết code, viết ra thành lời những gì mình muốn, sau đó hãy viết code.

Còn nữa, trong C thì XUNG1 và xung1 phân biệt nhau, chứ không phải như ASM, viết như vậy thì làm sao nó chạy đúng được.

Sẽ chẳng ai trả lời chi tiết cho bạn cái này được với cách viết code như thế này.

Chúc vui.

dinhminh09 05-11-2010 12:03 PM

while(TRUE)
{
IF(XUNG>1000||xung1>1000||xung2>1000) RA0=0;
IF(XUNG>1200||xung1>1200||xung2>1200) RA1=0;
IF(XUNG>1300||xung1>1300||xung2>1300) RA2=0;
IF(XUNG>1400||xung1>1400||xung2>1400) RA3=0;
IF(XUNG>1500||xung1>1500||xung2>1500) RA4=0;
IF(XUNG>1600||xung1>1600||xung2>1600) RA5=0;
IF(XUNG>2000||xung1>2000||xung2>2000) CT_PWM_POWER();
IF(XUNG>3000||xung1>3000||xung2>3000) CT_PWM_CCP ();
IF(XUNG>3000||xung1>3000||xung2>3000)
{


khúc này chỉ cần thêm vài cái {}
là ok rôi



while(TRUE)
{
IF(XUNG>1000||xung1>1000||xung2>1000)
{ RA0=0;

{
IF(XUNG>1200||xung1>1200||xung2>1200) RA1=0;

{
IF(XUNG>1300||xung1>1300||xung2>1300) RA2=0;

{
IF(XUNG>1400||xung1>1400||xung2>1400) RA3=0;

{
IF(XUNG>1500||xung1>1500||xung2>1500) RA4=0;

{
IF(XUNG>1600||xung1>1600||xung2>1600) RA5=0;

{
IF(XUNG>2000||xung1>2000||xung2>2000) CT_PWM_POWER();

{
IF(XUNG>3000||xung1>3000||xung2>3000) CT_PWM_CCP ();

{
IF(XUNG>3000||xung1>3000||xung2>3000)
}}}}}}}}

chưa thử nó mô phỏng thế nào nhừng mình nghĩ chắt cái này dúng ý bạn
http://www.picvietnam.com/forum/showthread.php?t=3266

falleaf 05-11-2010 12:07 PM

Toi !!!

Chúc vui

robotpic 05-11-2010 10:40 PM

while(TRUE)
{
IF(XUNG==1000||xung1==1000||xung2==1000) RA0=0;
else IF(XUNG==1200||xung1==1200||xung2==1200) RA1=0;
else IF(XUNG==1300||xung1==1300||xung2==1300) RA2=0;
else IF(XUNG==1400||xung1==1400||xung2==1400) RA3=0;
else IF(XUNG==1500||xung1==1500||xung2==1500) RA4=0;
else IF(XUNG==1600||xung1==1600||xung2==1600) RA5=0;
else IF(XUNG==2000||xung1==2000||xung2==2000) CT_PWM_POWER();
else IF(XUNG==3000||xung1==3000||xung2==3000) CT_PWM_CCP ();
else IF(XUNG>4000||xung1>4000||xung2>4000)
{
RD0=0;
DELAY_MS(500);
RD1=0;
DELAY_MS(500);
RD2=0;
DELAY_MS(500);
RD3=0;
DELAY_MS(500);
RD4=0;
DELAY_MS(500);
}
}

mình đã sửa được câu 1. chạy ok,

nhưng còn câu 2 chưa giả được.

mình không quay encorder vong nao ma nó vẫn thăng giá trị xung,

nếu mình ko quay để thời gian cũng thấy chương trình chạy từ đầu đến cuối.

bác falleaf nói cũng sai ah.

mình viết thế cũng dc, nhưng do định nghĩa sai thôi.

dinhminh09 06-11-2010 12:46 PM

ngửi cái sơ đồ nguyên lý hay cái mô phỏng lên mình xem với. thật ra mình không biết bạn so sanh encorder như thế nào

robotpic 07-11-2010 08:41 AM

mình thực hành trên boad test nên không vẻ.

chân rc3 vào encoder tương ứng chương trình ngăt ext
chân rc4 vào encoder1 tương ứng ngắt ext1
chân rc5 vào encoder2 tương ứng ngắt ext2


mình viết như thế đó bạn dinhminh09

dinhminh09 07-11-2010 09:38 AM

thật sự mình không nắm rõ về hoạt động của encorder. nhưng encoder gửi dữ liệu theo cách nào. nhưng nếu bạn dùng ngắt thì khi có ngắt xảy ra thì hàm ngắt hoạt động

#INT_EXT
VOID DEM_NGAT()
{
XUNG++;
return ;
}

vậy encorder đưa về nó hoạt động như thế nào?
nếu encorder không quay mà xung vẫn tăng lên thì chứng tỏ hàm ngắt vẫn đang thực hiện.
theo ý của mình thì như zậy có sai sót j mong bỏ qua cho.

robotpic 07-11-2010 11:52 AM

mình cung không rỏ vì sao ngắt nó lại tự chạy.
dùng encoder này mình khai báo như trền trang đầu tiên thì các chân rc3-rc5 mỗi khi có thay đổi từ o lên 1 thì nhảy đến ngắt. encoder của mình dùng 100 xung. tức mỗi vòng quay thì chương trình sẽ ngắt 100 lần. nhưng đàn này không quay nó vẫn ngắt xảy ra.

dinhminh09 07-11-2010 01:34 PM

If the GIE and INTE bits
are also set, the processor will redirect program
execution to the interrupt vector.

chắt là bạn chưa xoá cờ ngắt thì phải
#bit INTEDG = 0x81.6
#bit GIE = 0x0b.7
#bit INTE = 0x0b.4
INTEDG = 1;// cho phép ngắt cạnh lên
#INT_EXT
VOID DEM_NGAT()
{
XUNG++;
GIE = 0; //xoá cờ ngắt
INTE =0; //xoá cờ ngắt
return ;
}

thử lại xem sao mình cũng không biết có đúng không nữa.
thử lại rồi thông báo cho mình với

robotpic 08-11-2010 09:29 PM

Uh mÌnh chƯa xÓa cỜ ngẮt.
NhƯng viẾt nhƯ bẠn ĐÂu phẢi xÓa cỜ ngẮt nhỈ.

dinhminh09 09-11-2010 12:06 AM

vậy à. mình cũng đâu có biết. mình chỉ đọc trong datasheet rồi viết ra vậy thôi.
ủa viết lệnh xóa cờ ngắt là lệnh j nhỉ

robotpic 10-11-2010 11:29 PM

bạn set dung bit chứ bạn, nếu không chương trình hiểu nhầm

dinhminh09 11-11-2010 08:49 AM

nói thật là mình không hiểu ý bạn cho lắm. trước giờ để gán cho một bit bằng 0 mình vẫn làm như vậy cái sai ở đây là gì. và như thế nào là đúng

bit_set(var,bit); dùng hàm này à. bit_set(var,bit) Hàm này tương đương: var |= (1<<bit); dùng nó được à. mình nghĩ là không

mà cai code của banjchay chưa zậy. chạy rồi cho mình bản hoang chỉnh luôn đi :D

robotpic 11-11-2010 10:42 PM

uh nó chạy rồi. nhưng vẫn không tốt. mình đang tìm hiểu, cái chính là mình xóa cờ ngắt sau mõi lần gọi chương trình ngắt. nhưng 3 ngắt mình thấy chu kỳ khác nhau.

vì sao ngăt ext2 lại số vong quay nhiều hơn.
#include <18f4331.h>
#INCLUDE <def_4331.h>

#FUSES HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT,NOPUT,NOCPD,NO DEBUG,NOFCMEN,NOCPB,STVREN,NOPWMPIN,HPOL_LOW
#FUSES MCLR,NOIESO,NOWRTC,NOWRTB,NOWRTD,NOEBTR,NOWRT,NOEB TRB,EXCLKD0,T1STANDARD,NOWINEN

#use delay(clock=20000000)

#use fast_io(a)
#use fast_io(d)
#use fast_io(c)
#use fast_io(e)


#DEFINE GIAI_MA1 RE0
#DEFINE GIAI_MA2 RE1
#DEFINE GIAI_MA3 RE2

#DEFINE NUT_AN RA0
#DEFINE CT_HT RA4

long XUNG,XUNG1,XUNG2;
int1 nut1,nut2,nut3,nut4,nut5,nut6,nut7,nut8;
int1 CT_HT1,CT_HT2,CT_HT3,CT_HT4,CT_HT5,CT_HT6,CT_HT7,C T_HT8;
#INT_EXT //RC3
VOID DEM_NGAT()
{
XUNG++;
INT0IF=0;
return ;
}

#INT_EXT1 //RC4
VOID DEM_NGAT_1()
{

XUNG1++;
INT1IF=0;
return ;
}

#INT_EXT2 //RC5

VOID DEM_NGAT_2()
{
XUNG2++;
INT2IF=0;
return;
}

VOID CT_PWM_POWER()
{
SET_POWER_PWM0_DUTY(100);

SET_POWER_PWM2_DUTY(500);

SET_POWER_PWM4_DUTY(200);

SET_POWER_PWM6_DUTY(500);

}
VOID CT_PWM_CCP ()
{

SET_PWM2_DUTY(250);
SET_PWM1_DUTY(500);
}
void main()
{
trisa=0x00;
porta=0xff;

trisb=0x00;
portb=0x00;

trisc=0b00111000;
//portC=0b00111000;

trisd=0x00;
portd=0xff;

trise=0x00;
porte=0xff;



setup_power_pwm_pins( PWM_ODD_ON,PWM_ODD_ON,PWM_ODD_ON,PWM_ODD_ON);
setup_power_pwm(PWM_CLOCK_DIV_4|PWM_FREE_RUN,1,0,1 24,0,1,0);
set_power_pwm_override(1, false, 0);
set_power_pwm_override(3, false, 0);
set_power_pwm_override(5, false, 0);
set_power_pwm_override(7, false, 0);

SETUP_CCP1(CCP_PWM);
SETUP_CCP2(CCP_PWM);
setup_timer_2(T2_DIV_BY_4,124,1);

enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT);
enable_interrupts(INT_EXT1);
enable_interrupts(INT_EXT2);
ext_int_edge(0, L_TO_H );
ext_int_edge(1, L_TO_H );
ext_int_edge(2, L_TO_H );


xung=0;
xung1=0;
xung2=0;


while(TRUE)
{
IF(xung2==100) RA0=0;
else IF(XUNG2==1200) RA1=0;
else IF(XUNG2==1300) RA2=0;
else IF(xung2==1400) RA3=0;
else IF(xung2==1500) RA4=0;
else IF(xung2==1600) RA5=0;
else IF(xung2==2000) CT_PWM_POWER();
else IF(xung2==3000) CT_PWM_CCP ();
else IF(xung2>4000)
{
RD0=0;
DELAY_MS(500);
RD1=0;
DELAY_MS(500);
RD2=0;
DELAY_MS(500);
RD3=0;
DELAY_MS(500);
RD4=0;
DELAY_MS(500);
RD5=0;
DELAY_MS(500);
RD6=0;
DELAY_MS(500);

}
}

}


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

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam