View Single Post
Old 12-05-2007, 06:07 PM   #360
omlun
Đệ tử 1 túi
 
Tham gia ngày: Mar 2007
Bài gửi: 25
:
cảm ơn bạn!!
mạch của mình ,do chân encoder mình đưa chân timer 1!
nên mình tính dùng timer 1 để đọc encoder, động cơ mình dùng có công
suất thấp với lại encoder 100 xung/1 vòng nên timer 1 ko sợ bị tràn
mình có sửa lại đoạn code của cậu cho phù hợp với mạch của mình!
khi chạy thử thì no báo lỗi
mong bạn giúp đỡ
Code:
#include <16f877a.h>
#fuses HS,NOPROTECT,NOWDT,NOBROWNOUT
#use delay (clock = 20000000)
// Giao tiep vi dieu khien
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8) // Giao tiep RS232

#include <stdlib.h>
#include <string.h>
#include <math.h>
#include<ctype.h>

#byte PR2 = 0x92

int16 e2;
int16 e1;
///////////////////////////////////////////////////////

int16 v_set = 250;

/////////////////////////////////////////////////////////
int16 v_cur;
int16 e_sum;
int16 e_del;
int16 flag_timer1;


///////////////////////////////////////////////////////////
unsigned long kp =5;
unsigned long ki = 0.62;
unsigned long kd = 10;
////////////////////////////////////////////////////////////

int16 i = 1 ;
int16 pw_duty;
int16 counted_round_value;
int16 temp_timer0;
int16 temp_timer1;
int16 update_counted_round_value;

#byte TMR0 = 0x01 //timer0 REGISTER
#byte TMR1_L = 0X0E
#byte TMR1_H = 0X0F

#define START_VALUE_TIMER0 5 //tri khoi tao ban dau cua timer0 5, so xung dem duoc moi khi ngat la 255 - 5
#define START_VALUE_TIMER1 5535 //tri khoi tao ban dau cua timer1 65536-5536=60000

#INT_TIMER0 // ngat timer0 tang bien len 1
void TIMER0_int()
{

set_timer0(START_VALUE_TIMER0);
i++;

}

void doc_xung()
{
if ( i==50 )

temp_timer1 = get_timer1();
set_timer1(START_VALUE_TIMER1);//lan tran thu 50 cua timer0 se set timer1
i=0;
if (temp_timer0 == 0){
temp_timer0= 255;
}
v_cur =  2*(temp_timer1 - START_VALUE_TIMER1);
set_timer1(START_VALUE_TIMER1);
i = 1;
//printf("%ld\t",pw_duty);
flag_timer1 = 1;
}


void init_timer0()
{

setup_timer_0(RTCC_INTERNAL | RTCC_DIV_16); // moi lan tran timer0 tuong ung 250*16*1/5 us = 0.8ms,chu ky lay mau=0.8*50=40ms


setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1); // moi lan tran timer0 , khoi tao lai luon gia tri dem xung timer1

enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER0);

}

void init_PWM(int16 frequency){

setup_ccp1(CCP_PWM); // initiate PWM
PR2 = 20000000/4/frequency - 1; // set PWM period

setup_timer_2(T2_DIV_BY_1,255,1); // initiate time 2 The cycle time will be (1/clock)*4*t2div*(period+1)
// (1/20000000)*4*1*(255+1) = 51.2 us( will over flow every 51.2 us, will intrup every 51.2 uS or 19.5 khz;

}

void cal_pid(){

long temp_kp;
long temp_ki;
long temp_kd;
e2 = v_set - v_cur;
e_sum += e2;
e_del = e2 - e1;
e1 = e2;

temp_kp = kp*e2;
temp_ki = ki*e_sum;
temp_kd = kd*e_del;
pw_duty +=temp_kp;

if (pw_duty <800)
pw_duty += temp_ki;
if (pw_duty <800)
pw_duty += temp_kd;
if (pw_duty <256) // vi khi pw_duty <256 thi PWM chi dieu rong xung 8 bit / //chu khong phai 10 bit,
pw_duty = 256;
if (pw_duty >800) // bao hoa
pw_duty = 800;

printf(" \t%ld", v_cur); // truyen toc do xung ve may tinh hien thi tren Hyperterminal
}

void main()
{
int8 timer0_value;

init_timer0();
init_PWM(19500);

while(true){
if (flag_timer1 ==1){
flag_timer1 = 0;
cal_pid();
set_pwm1_duty(pw_duty);
}
}
}

thay đổi nội dung bởi: namqn, 12-05-2007 lúc 06:50 PM.
omlun vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn