vietlong04
15-03-2010, 06:36 PM
Chào các bạn, mình đã biết đến diễn đàn picvn này từ lâu nhưng giờ mới có việc thực sự rất cần ý kiến trao đổi của các bạn. Mình dùng Pic 18f4331(sơ đồ mạch http://www.mediafire.com/?mjmjm5w3myv ) lập trình điều khiển động cơ và dùng encoder để đo nhưng không hiểu sao nếu không có động cơ mắc vào chân PWM thì chương trình đếm xung rất tốt con nếu có động cơ thì tự động thực hiện chương trình. Ví dụ chương trình đơn giản của mình. Viết bằng CCS
mình dùng encoder 100 xung 2 sign 2 nguồn, động cơ kéo kính hoặc 3000vong (nói chung động cơ nào dùng cũng bị nhiễu)
#include <18f4550.h>
#FUSES HS //High speed Osc (> 4mhz)
#FUSES PUT //Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOCPD //No EE protection
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOWDT
#use delay(clock=20000000)
#use fast_io(b)
#use fast_io(c)
#use fast_io(a)
#use fast_io(d)
#use fast_io(e)
int1 flag_ngat1=0,flag_ngat2=0,ngat1=0,ngat2=0;
int16 signA,signB,en_t,en_p;
int8 en;
/**************************************/
#int_ext1 //dem xung encoder banh trai
void ngat_int1()
{
disable_interrupts(int_ext1);
signA++;
if ((signA >= en_t)&&(flag_ngat1 == 0))
{
ngat1 = 1;
flag_ngat1 = 1;
signA = 0;
}
enable_interrupts(int_ext1) ;
}
#int_ext2 //dem xung encoder banh phai
void ngat_int2()
{
disable_interrupts(int_ext2);
signB ++;
if ((signB >= en_p)&&(flag_ngat2 == 0))
{
ngat2 = 1;
flag_ngat2 = 1;
signB = 0;
}
enable_interrupts(int_ext2) ;
}
/**************************************/
void main(){
set_tris_A(0xB1); // pin A7 -> pin A0 1011 0001
set_tris_B(0xC0); // pin B7 -> pin B0 1100 0000
set_tris_C(0x39); // pin C7 -> pin C0 0011 1001
set_tris_D(0x03); // pin D7 -> pin D0 0000 0011
set_tris_E(111);
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
setup_timer_0( RTCC_INTERNAL| RTCC_DIV_256 | RTCC_8_BIT);
setup_timer_2(T2_DIV_BY_16, 255, 1);
/* setup_power_pwm_pins(PWM_BOTH_ON,PWM_BOTH_ON,PWM_O FF,PWM_OFF);
setup_power_pwm(PWM_CLOCK_DIV_128|PWM_FREE_RUN,
1, //postscale, not used
0, //initial PTMR
63, //**************PTPER9 //
0, //compare special event, not used
1, //postscale compare special event, not used
0); //dead_time
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);*/ // su dung mode PWM cua 18f4331
enable_interrupts(int_ext1);
enable_interrupts(int_ext2);
ext_int_edge(1, L_TO_H );
ext_int_edge(2, L_TO_H );
enable_interrupts(GLOBAL);
output_high(PIN_B0);
output_high(PIN_B1);
output_high(PIN_B2);
output_high(PIN_B3);
output_high(PIN_B4);
output_high(PIN_B5);
output_high(PIN_D2);
output_high(PIN_D3);
output_high(PIN_D4);
output_high(PIN_D5);
output_high(PIN_D6);
output_high(PIN_D7);
output_high(PIN_C6);
output_high(PIN_C7);
set_pwm1_duty(255); //đưa full áp trên chân CCP1
set_pwm2_duty(255); //đưa full áp trên chân CCP2
signA=0
while(true){
if(signA>100) output_low(PIN_B0); //nếu quay 1 vòng en thì đèn nói chân B0 ra sẽ sáng
if(signA>200) output_low(PIN_B1); //nếu quay 1 vòng en thì đèn nói chân B1 ra sẽ sáng
if(signA>300) output_low(PIN_B2); //nếu quay 1 vòng en thì đèn nói chân B2 ra sẽ sáng
if(signA>400) output_low(PIN_B3); //nếu quay 1 vòng en thì đèn nói chân B3 ra sẽ sáng
if(signA>500) output_low(PIN_B4); //nếu quay 1 vòng en thì đèn nói chân B4 ra sẽ sáng
}
}
nếu không bắt động cơ vào thì mình quay encoder thấy nó thực hiện chương trình rất đúng,còn nếu có động cơ vào chạy thì chẳng cần quay encoder chương trình vẫn tự động thực hiện @@ ( Đã nối tụ giữa 2 đầu động cơ, diot từ chân pwm đến dương nguồn, nguồn nuôi pic khác với nguồn nuôi động lực)
Mình lên mạng dò hỏi thì biết nếu dùng pic 18f4331 thì nên dùng mode QEI mà đọc encoder khổ nổi lại không biết config nó = CCS
mình dùng encoder 100 xung 2 sign 2 nguồn, động cơ kéo kính hoặc 3000vong (nói chung động cơ nào dùng cũng bị nhiễu)
#include <18f4550.h>
#FUSES HS //High speed Osc (> 4mhz)
#FUSES PUT //Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOCPD //No EE protection
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOWDT
#use delay(clock=20000000)
#use fast_io(b)
#use fast_io(c)
#use fast_io(a)
#use fast_io(d)
#use fast_io(e)
int1 flag_ngat1=0,flag_ngat2=0,ngat1=0,ngat2=0;
int16 signA,signB,en_t,en_p;
int8 en;
/**************************************/
#int_ext1 //dem xung encoder banh trai
void ngat_int1()
{
disable_interrupts(int_ext1);
signA++;
if ((signA >= en_t)&&(flag_ngat1 == 0))
{
ngat1 = 1;
flag_ngat1 = 1;
signA = 0;
}
enable_interrupts(int_ext1) ;
}
#int_ext2 //dem xung encoder banh phai
void ngat_int2()
{
disable_interrupts(int_ext2);
signB ++;
if ((signB >= en_p)&&(flag_ngat2 == 0))
{
ngat2 = 1;
flag_ngat2 = 1;
signB = 0;
}
enable_interrupts(int_ext2) ;
}
/**************************************/
void main(){
set_tris_A(0xB1); // pin A7 -> pin A0 1011 0001
set_tris_B(0xC0); // pin B7 -> pin B0 1100 0000
set_tris_C(0x39); // pin C7 -> pin C0 0011 1001
set_tris_D(0x03); // pin D7 -> pin D0 0000 0011
set_tris_E(111);
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
setup_timer_0( RTCC_INTERNAL| RTCC_DIV_256 | RTCC_8_BIT);
setup_timer_2(T2_DIV_BY_16, 255, 1);
/* setup_power_pwm_pins(PWM_BOTH_ON,PWM_BOTH_ON,PWM_O FF,PWM_OFF);
setup_power_pwm(PWM_CLOCK_DIV_128|PWM_FREE_RUN,
1, //postscale, not used
0, //initial PTMR
63, //**************PTPER9 //
0, //compare special event, not used
1, //postscale compare special event, not used
0); //dead_time
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);*/ // su dung mode PWM cua 18f4331
enable_interrupts(int_ext1);
enable_interrupts(int_ext2);
ext_int_edge(1, L_TO_H );
ext_int_edge(2, L_TO_H );
enable_interrupts(GLOBAL);
output_high(PIN_B0);
output_high(PIN_B1);
output_high(PIN_B2);
output_high(PIN_B3);
output_high(PIN_B4);
output_high(PIN_B5);
output_high(PIN_D2);
output_high(PIN_D3);
output_high(PIN_D4);
output_high(PIN_D5);
output_high(PIN_D6);
output_high(PIN_D7);
output_high(PIN_C6);
output_high(PIN_C7);
set_pwm1_duty(255); //đưa full áp trên chân CCP1
set_pwm2_duty(255); //đưa full áp trên chân CCP2
signA=0
while(true){
if(signA>100) output_low(PIN_B0); //nếu quay 1 vòng en thì đèn nói chân B0 ra sẽ sáng
if(signA>200) output_low(PIN_B1); //nếu quay 1 vòng en thì đèn nói chân B1 ra sẽ sáng
if(signA>300) output_low(PIN_B2); //nếu quay 1 vòng en thì đèn nói chân B2 ra sẽ sáng
if(signA>400) output_low(PIN_B3); //nếu quay 1 vòng en thì đèn nói chân B3 ra sẽ sáng
if(signA>500) output_low(PIN_B4); //nếu quay 1 vòng en thì đèn nói chân B4 ra sẽ sáng
}
}
nếu không bắt động cơ vào thì mình quay encoder thấy nó thực hiện chương trình rất đúng,còn nếu có động cơ vào chạy thì chẳng cần quay encoder chương trình vẫn tự động thực hiện @@ ( Đã nối tụ giữa 2 đầu động cơ, diot từ chân pwm đến dương nguồn, nguồn nuôi pic khác với nguồn nuôi động lực)
Mình lên mạng dò hỏi thì biết nếu dùng pic 18f4331 thì nên dùng mode QEI mà đọc encoder khổ nổi lại không biết config nó = CCS