Em có vài chỗ thắc mắc về giao tiếp mong mọi người giúp đỡ:
khi khởi động hay reset pic thì có byte nào trong bọ đệm nhận không? Bởi vì khi em vừa
enable_interrupts(INT_RDA); thì có ngắt xảy ra và lặp lại liên tục?
đây là code của em
Code:
#include <16F877A.h>
#device 16F877*=16 ADC=8
//#fuses HS,NOWDT,NOPROTECT,NOLVP,xt
#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 rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8) // Giao tiep RS232
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
signed int16 so_xung,t1,t2,t3,err,err_temp,err_sum;
int1 chieu_quay,on,a;
int8 i,fini,j,n,cur,dem_chong_nhieu;
char str[10],value[5],data[5],b;
int16 m;
float Kp1,Ki1,Kd1,Kp2,Ki2,Kd2,Kp3,Ki3,Kd3;
float u_t;
float p_r_temp,p_r_temp1,p_r_temp2,p_r;
float p,tb,tf,vmax, amax;
#INT_RDA
void ngat_serial()
{ printf("a\r");
gets(str);
printf("b\r");
if ((str[strlen(str)-2]=='1')&&(str[strlen(str)-1]=='p')) fini = 1;
else if ((str[strlen(str)-2]=='1')&&(str[strlen(str)-1]=='i')) fini = 2;
else if ((str[strlen(str)-2]=='1')&&(str[strlen(str)-1]=='d')) fini = 3;
else if ((str[strlen(str)-2]=='1')&&(str[strlen(str)-1]=='v')) fini = 4;
else if ((str[strlen(str)-2]=='2')&&(str[strlen(str)-1]=='p')) fini = 5;
else if ((str[strlen(str)-2]=='2')&&(str[strlen(str)-1]=='i')) fini = 6;
else if ((str[strlen(str)-2]=='2')&&(str[strlen(str)-1]=='d')) fini = 7;
else if ((str[strlen(str)-2]=='3')&&(str[strlen(str)-1]=='p')) fini = 8;
else if ((str[strlen(str)-2]=='3')&&(str[strlen(str)-1]=='i')) fini = 9;
else if ((str[strlen(str)-2]=='3')&&(str[strlen(str)-1]=='d')) fini = 10;
else if ((str[strlen(str)-2]=='v')&&(str[strlen(str)-1]=='m')) fini = 11;
else if ((str[strlen(str)-2]=='a')&&(str[strlen(str)-1]=='m')) fini = 12;
else if ((str[0]=='o')&&(str[1]=='n')) on = 1;
strncpy(value,str,strlen(str)-2);
for(n=0;n<=9;n++) str[n]=NULL;
if (fini == 1) { Kp1 = (float)atol(value); }
else if (fini == 2) { Ki1 = (float)atol(value); }
else if (fini == 3) { Kd1 = (float)atol(value); }
else if (fini == 4) { p_r = (float)atol(value); }
else if (fini == 5) { Kp2 = (float)atol(value); }
else if (fini == 6) { Ki2 = (float)atol(value); }
else if (fini == 7) { Kd2 = (float)atol(value); }
else if (fini == 8) { Kp3 = (float)atol(value); }
else if (fini == 9) { Ki3 = (float)atol(value); }
else if (fini == 10){ Kd3 = (float)atol(value); }
else if (fini == 11){ vmax = (float)atol(value); }
else if (fini == 12){ amax = (float)atol(value); }
fini=0;
for(n=0;n<=4;n++) value[n]=NULL;
}
void main()
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
set_timer0(5);
setup_timer_1 (T1_INTERNAL|T1_DIV_BY_8);
set_timer1(63035);
enable_interrupts(INT_EXT);
ext_int_edge(H_TO_L);
setup_ccp1(CCP_PWM);
//------gia tri ban dau cua cac bien-----------//
p_r = p_r_temp = err = err_temp = err_sum = so_xung = chieu_quay = i = j = on = cur= dem_chong_nhieu = 0;
fini = u_t = 0; kp1=ki1=kd1=kp2=ki2=kd2=kp3=ki3=kd3=0; vmax=amax=0;
m=t1=t2=t3=0;
//--------------------------------------------//
set_tris_b(0x00);
set_tris_a(0x00);
set_tris_e(0x00);
set_tris_c(0x80);
set_tris_d(0x00);
output_b(0x0);
output_a(0x0);
output_e(0x0);
output_d(0x0);
setup_timer_2 ( T2_DIV_BY_16, 255, 16);
set_pwm1_duty(0);
printf("ready\r");
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
output_a(0xff);
printf("oh\r");
while (on==0) output_d(0xff);
output_e(0xff);
printf("yeah\r");
//delay_ms(10000);
//---------------------------------------------//
}
và đây là kết quả nhận được (em dùng matlab nhận dữ liệu)
Code:
data =
ready
data =
oh
data =
a
data là biến để nhận dữ liệu. Theo như chương trình thì sau khi phát ra chuỗi "ready" và "oh" thì đúng ra phải chờ dữ liệu (while (on==0)). nhưng thực tế lại xảy ra ngắt nhận RDA và in ra "a" và dùng luôn ở đây ( không in ra ký tự "b"). Không biêt tại sao ngay khi enable_interrupts(INT_RDA); thì lại xảy ra ngắt mặc dù em chưa truyền dữ liêu.
Còn khi em thay lệnh
gets(str) băng lệnh
b=getc(); trong ngắt nhận thì chương trình cứ lặp lại liên tục. đây là dữ liệu nhận được:
Code:
data =
ready
data =
oh
data =
a
data =
b
data =
ready
data =
oh
data =
a
data =
b
data =
ready
data =
oh
data =
a
data =
b
data =
ready
data =
oh
data =
a
data =
b
Ở đây sau khi thực hiện ngắt nhận xong chương trình lại quay lại in ra "ready" "oh " rồi lại ngắt (in ra "a" "b" ) rồi lại in ra " ready" "oh" ..... Thế là sao ạ? tại sao chương trình lại lặp lại dược ạ?
Mong mọi người giúp đỡ. Em cảm ơn nhiều.