baquyen
17-05-2010, 10:10 PM
Em đang lập trình phần ngắt nt cho 16f887, em thử nghiệm ngắt khi nhận được tín hiệu từ máy tính, em dùng #int_RDA nhưng ko thành công, chương trình của em như sau:
#include <16f887.h>
#device adc=8
#include <def_877a.h>
#include <stdio.h>
#include <stdlib.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use fast_io(D)
#use fast_io(b)
#use delay(clock=12000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C7,rcv=PIN_C6,bi ts=8)
//thiet ke nguoc hai chan C7 va C6//
int8 q; // q = 1 chieu thuan, q = 0 chieu nghich
signed int16 gtdem = 0; // dem vi tri encoder
signed int16 gtdat = 100; // gia tri dat
signed int16 y = 0; // do lech giua vi tri dat va gt dem
//int16 count = 0; // bien dem trong timer0, max = 65536
int8 i=0;
int8 x1=0;
int8 x2=0;
//=============== ngat TIMER0 ========================//
// thoi diem khac nhau thi gtdat khac nhau //
/*#int_timer0
void interrupt_timer0()
{
set_timer0(4); // 256 - 4 = 252 so nay chia het cho 3
count++; // count tang len 1 sau 256*(256-4)*4/12M = 21.504 ms
if(count==50) // 21.504*500 = 10.752 s
{
gtdat=100; //90 do
}
if(count==100) //21.504 s
{
gtdat=200; //180 do
}
if(count==150) //32.256 s
{
gtdat=300; //270 do
}
if(count==200) //43.008 s
{
gtdat=400; //360 do
}
if(count==250) //53.76 s
{
count=0;
gtdat=0;
}
}*/
#INT_RDA
void gtdat_RDA()
{
/*++i;
if(i==1)
{
x1=getc();
}
if(i==2)
{
x2=getc();
}
gtdat=make16(x1,x2);
i=0;*/
printf("OK");
}
//=============== ngat ngoai RB0 va RB1 ========================//
//dem vi tri encoder (gtdem) va chieu quay (q)//
#INT_EXT
void encoder_EXT()
{
// y=gtdat-gtdem;// de o day la ko on//
if(rb1==0) // chieu thuan
{
gtdem++;
q=0x00;
}
else // chieu nghich
{
gtdem--;
q=0xff;
}
}
//====================== HAM CHINH ==============================//
void main()
{
//printf("khong phai em");
//=================== INTERRUPT ====================//
//set_tris_b(0xff);
set_tris_D(0x00); // tat ca ngo d la output
//portd=0x00;
//set_timer0(4);
//enable_interrupts(int_timer0);
//setup_timer_0(RTCC_internal|RTCC_div_128);
ext_int_edge(l_to_h);
//ext_int_edge(h_to_l);
enable_interrupts(INT_EXT);
enable_interrupts(INT_RDA);
enable_interrupts(Global);
//===================== PWM ========================//
setup_ccp1(ccp_pwm);
setup_ccp2(ccp_pwm);
setup_timer_2(T2_div_by_4,140,1); //TR2 = 140, prescale = 4
// T = 4/12M*(140+1)*4 = 1.88*10^-4 s
// f = 1/T = 5.319 kHz
// Prescale value = ((1/PWM Frequency)/Prescale value * (4/OSC frequency))-1
// PWM resolution = ( log ( OSC freq / PWM freq ) ) / log 2
set_pwm1_duty(0);
set_pwm2_duty(0);
//================== DIEU KHIEN ===================//
while(true)
{
y=gtdat-gtdem;
portd=q; // xem chieu dong co qua tt PORTD
if(y>0) // chua toi vi tri nen cho dc chay theo chieu thuan
{
set_pwm2_duty(0);
set_pwm1_duty(30);
}
if(y==0) // ok roi`
{
set_pwm1_duty(0);
set_pwm2_duty(0);
}
if(y<0) // chay qua' roi, cho chay nguoc lai
//(tai sao ko dung ELSE o day dc?)
{
set_pwm1_duty(0);
set_pwm2_duty(30);
}
}
}
//========================== KET THUC=============================//
- ban đầu em thử đặt hàm printf("khong phai em")trong main(), thì trên máy tính hiện lên chuỗi ký tự "khong phai em" trên màn hình của chương trình trên máy tính. Vậy là việc gửi chuỗi ký tự lên PC là bình thường.
- sau đó em đặt hàm printf("OK") vào hàm ngắt #int_RDA, ý tưởng của em là khi máy tính gửi 1 ký tự bất kỳ đến PIC thì Pic sẽ gửi chữ OK lên màn hình máy tinh, nhưng em thử nghiệm thì ko đc gì cả.
- chú ý là trong thiết kế phần cứng em nối nhầm 2 chân C6 và C7, em thay đổi khai báo trong rs232 thì hàm printf() hoạt động bình thường, không biết việc nhầm lẫn này có ảnh hưởng đến ngắt #int_RDA ko, hay là do code của em có lỗi
Mong được mọi người giúp đỡ
#include <16f887.h>
#device adc=8
#include <def_877a.h>
#include <stdio.h>
#include <stdlib.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use fast_io(D)
#use fast_io(b)
#use delay(clock=12000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C7,rcv=PIN_C6,bi ts=8)
//thiet ke nguoc hai chan C7 va C6//
int8 q; // q = 1 chieu thuan, q = 0 chieu nghich
signed int16 gtdem = 0; // dem vi tri encoder
signed int16 gtdat = 100; // gia tri dat
signed int16 y = 0; // do lech giua vi tri dat va gt dem
//int16 count = 0; // bien dem trong timer0, max = 65536
int8 i=0;
int8 x1=0;
int8 x2=0;
//=============== ngat TIMER0 ========================//
// thoi diem khac nhau thi gtdat khac nhau //
/*#int_timer0
void interrupt_timer0()
{
set_timer0(4); // 256 - 4 = 252 so nay chia het cho 3
count++; // count tang len 1 sau 256*(256-4)*4/12M = 21.504 ms
if(count==50) // 21.504*500 = 10.752 s
{
gtdat=100; //90 do
}
if(count==100) //21.504 s
{
gtdat=200; //180 do
}
if(count==150) //32.256 s
{
gtdat=300; //270 do
}
if(count==200) //43.008 s
{
gtdat=400; //360 do
}
if(count==250) //53.76 s
{
count=0;
gtdat=0;
}
}*/
#INT_RDA
void gtdat_RDA()
{
/*++i;
if(i==1)
{
x1=getc();
}
if(i==2)
{
x2=getc();
}
gtdat=make16(x1,x2);
i=0;*/
printf("OK");
}
//=============== ngat ngoai RB0 va RB1 ========================//
//dem vi tri encoder (gtdem) va chieu quay (q)//
#INT_EXT
void encoder_EXT()
{
// y=gtdat-gtdem;// de o day la ko on//
if(rb1==0) // chieu thuan
{
gtdem++;
q=0x00;
}
else // chieu nghich
{
gtdem--;
q=0xff;
}
}
//====================== HAM CHINH ==============================//
void main()
{
//printf("khong phai em");
//=================== INTERRUPT ====================//
//set_tris_b(0xff);
set_tris_D(0x00); // tat ca ngo d la output
//portd=0x00;
//set_timer0(4);
//enable_interrupts(int_timer0);
//setup_timer_0(RTCC_internal|RTCC_div_128);
ext_int_edge(l_to_h);
//ext_int_edge(h_to_l);
enable_interrupts(INT_EXT);
enable_interrupts(INT_RDA);
enable_interrupts(Global);
//===================== PWM ========================//
setup_ccp1(ccp_pwm);
setup_ccp2(ccp_pwm);
setup_timer_2(T2_div_by_4,140,1); //TR2 = 140, prescale = 4
// T = 4/12M*(140+1)*4 = 1.88*10^-4 s
// f = 1/T = 5.319 kHz
// Prescale value = ((1/PWM Frequency)/Prescale value * (4/OSC frequency))-1
// PWM resolution = ( log ( OSC freq / PWM freq ) ) / log 2
set_pwm1_duty(0);
set_pwm2_duty(0);
//================== DIEU KHIEN ===================//
while(true)
{
y=gtdat-gtdem;
portd=q; // xem chieu dong co qua tt PORTD
if(y>0) // chua toi vi tri nen cho dc chay theo chieu thuan
{
set_pwm2_duty(0);
set_pwm1_duty(30);
}
if(y==0) // ok roi`
{
set_pwm1_duty(0);
set_pwm2_duty(0);
}
if(y<0) // chay qua' roi, cho chay nguoc lai
//(tai sao ko dung ELSE o day dc?)
{
set_pwm1_duty(0);
set_pwm2_duty(30);
}
}
}
//========================== KET THUC=============================//
- ban đầu em thử đặt hàm printf("khong phai em")trong main(), thì trên máy tính hiện lên chuỗi ký tự "khong phai em" trên màn hình của chương trình trên máy tính. Vậy là việc gửi chuỗi ký tự lên PC là bình thường.
- sau đó em đặt hàm printf("OK") vào hàm ngắt #int_RDA, ý tưởng của em là khi máy tính gửi 1 ký tự bất kỳ đến PIC thì Pic sẽ gửi chữ OK lên màn hình máy tinh, nhưng em thử nghiệm thì ko đc gì cả.
- chú ý là trong thiết kế phần cứng em nối nhầm 2 chân C6 và C7, em thay đổi khai báo trong rs232 thì hàm printf() hoạt động bình thường, không biết việc nhầm lẫn này có ảnh hưởng đến ngắt #int_RDA ko, hay là do code của em có lỗi
Mong được mọi người giúp đỡ