|
|
View previous topic :: View next topic |
Author |
Message |
raflab
Joined: 09 Aug 2011 Posts: 6
|
problem with int_rda and int_ext |
Posted: Thu Aug 18, 2011 4:10 am |
|
|
When I receive the data from the serial port using int_rda !! I can't use the data named x in the main program to complete the desired scenario !! the external doesn't work anymore !!! I don't know why ?! I try to set to 1 PIN_A2 when RB0=0 !! when I change the state of RB0 I execute the principal operation .. Please help me Thanks
Code: |
#include <16F628A.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES LP //Low power osc < 200 khz
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_A3,rcv=PIN_A2,bits=8)
#include <stdlib.h>
#include <string.h>
#use delay (clock=4000000)
#use rs232 (baud=9600, xmit=pin_b2, rcv=pin_b1, parity=N, stop=1)
#define so 10 // définir les adresse mémoir EEPROM qu'on va les utiliser
#define mo 15
#define sf 20
#define mf 25
unsigned char send[5],c[5],select[5],chaine1[20],chaine2[20],str1[20],str2[20]; // déclaration d'une chaine de caractères d'une taille maximale 20
unsigned int16 j,w,s=0,x1=0,y1=0,x2=0,y2=0,a1=0,b1=0,a2=0,b2=0,tmp_on=0,tmp_off=0; // déclaration d'un entier non signé de longueur 16 bits
unsigned int z=0,x=0,count=0;
int calcul(int16 m,int16 n)
{
int16 Res;
Res=2*((m*60)+(n/1000));
return Res;
}
#int_timer1
void timer1(){
//disable_interrupts(int_timer1);
count++;
}
#int_ext
void ext_isr()
{
// DISABLE_INTERRUPTS(INT_ext);
output_low(pin_b4);
output_low(pin_b5);
output_low(pin_b6);
output_low(pin_b7);
output_high(pin_a2);
output_low(pin_a1);
}
#int_rda
void reception(){
z=0;
//disable_interrupts(int_rda);
//if(kbhit()){
count=0;
gets(select);
x=atoi(select);
//}
}
void main()
{
EXT_INT_EDGE(H_TO_L);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
set_timer1(0);
//Setup_Oscillator parameter not selected from Intr Oscillotar Config tab
set_timer0(60);
// TODO: USER CODE!!
a1=read_eeprom(so);
b1=read_eeprom(mo);
a2=read_eeprom(sf);
b2=read_eeprom(mf);
a1=a1*1000;
a2=a2*1000;
tmp_off=calcul(b1,a1);
//tmp_on=calcul(b2,a2);
enable_interrupts(INT_EXT);
//enable_interrupts(int_timer0);
enable_interrupts(int_timer1);
enable_interrupts(GLOBAL);// autorisé tout les intérruptions
while(1)
{
enable_interrupts(INT_RDA);
switch(x){
case 1:{
printf("%lu\r",a1); // time of LED lighting in seconds
printf("%lu\r",b1); // time of LED lighting in minutes
printf("%lu\r",a2); // time of LED switched off in seconds
printf("%lu\r",b2); // time of LED switched off in minutes
x=0;
break;
}
case 2:{
j=2;
strcpy(c,"2");
if(input(pin_b0))
printf("%s\r","F");
while(input(pin_b0)&& j==2) // boucle pour passer au mode config si on l'est pas deja
{
//delay_ms(1000);
gets(c);
j=atol(c);
output_high(pin_a1);
output_low(pin_a2);
if(input(pin_b0)&& j!=8)
printf("%s\r","F");
}
if(j!=8){
printf("%s\r","C");
output_high(pin_a2);
output_low(pin_a1);
output_low(pin_b4);
output_low(pin_b5);
output_low(pin_b6);
output_low(pin_b7);}
while(z==0 && j!=8 ){
gets(send);
printf("%s\r",send);
s=atol(send);
if(s==4){
gets(chaine1); // acquisition des nouveaux valeurs
gets(str1);
gets(chaine2);
gets(str2);
x1=atol(chaine1); // conversion chaine -> entier long
y1=atol(str1);
x2=atol(chaine2);
y2=atol(str2);
printf("%s\r",chaine1); // renvoyer les valeurs reçu pour une confirmation de l'utilisateur
printf("%s\r",str1);
printf("%s\r",chaine2);
printf("%s\r",str2);
gets(select);
w=atol(select);
if (w==1) {
a1=x1;
a2=x2;
b1=y1;
b2=y2;
write_eeprom(so,a1);
write_eeprom(mo,b1);
write_eeprom(sf,a2);
write_eeprom(mf,b2);
a1=a1*1000;
a2=a2*1000;
tmp_off=calcul(b1,a1);
tmp_on=calcul(b2,a2);
z=1;
}
else
{
z=0;
}
}
else
{
z=1;
}
}
x=0;
break;
}
case 3:{
j=3;
strcpy(c,"3");
if(input(pin_b0)==0)
printf("%s\r","C");
while(input(pin_b0)==0 && j==3) // boucle pour passer au mode config si on l'est pas deja
{
gets(c);
j=atol(c);
if((input(pin_b0)==0) && j!=9 )
printf("%s\r","C");
}
if (j!= 9)
printf("%s\r","F");
x=0;
break;
}
}
if((input(pin_b0))){
while(count<=tmp_off){
output_high(pin_b4);
output_high(pin_b5);
output_high(pin_b6);
output_high(pin_b7);
output_high(pin_a1);
output_low(pin_a2);
}
count=0;
while(count<=tmp_on){
output_low(pin_b4);
output_low(pin_b5);
output_low(pin_b6);
output_low(pin_b7);
output_high(pin_a1);
output_low(pin_a2);
}
count=0;
}
else
{
output_high(pin_a2);
output_low(pin_a1);
}
}
} |
|
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu Aug 18, 2011 8:10 am |
|
|
Can you reconfigure your circuit to free up
pin B1 and B2 for the HARDWARE USART?
Using a software should always be the LAST resort IMHO
as it is susceptible to #int interference during reception
AND has the added disadvantage of using more program code space.
I think revisiting what pins do what in your circuit -
would go a long way toward making your life better -
and your code SMALLER too. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Aug 18, 2011 12:42 pm |
|
|
Quote: | #FUSES LP //Low power osc < 200 khz
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_A3,rcv=PIN_A2,bits=8)
#include <stdlib.h>
#include <string.h>
#use delay (clock=4000000)
|
Can you see a problem with your oscillator fuse ?
This means you are likely not running this program in real hardware.
(Unless you're changing the fuse manually in the programmer).
Quote: | #int_rda
void reception(){
z=0;
//disable_interrupts(int_rda);
//if(kbhit()){
count=0;
gets(select);
x=atoi(select);
//}
} |
Don't get a string in #int_rda. It interrupts once per character. Don't sit
in the routine and wait for chars to come in. What if they don't come in ?
What happens to your program ? It locks up. Also, gets() expects a
carriage return character (0x0D) to mark the end of the string. What if
you don't receive it ? Again, your program is locked up in the #int_rda
routine forever. Also, don't use functions like atoi() inside #int_rda
because they can take a lot of time to finish.
Look at the CCS example file, Ex_sisr.c, which shows how to use #int_rda
to make a circular buffer. It shows how to get just one character inside
the #int_rda routine and put it in a buffer. Then you get chars from the
buffer outside of the #int_rda routine, in your main() program.
Also:
CCS has an example of how to use INT_RDA interrupts to get a string.
Look at the bget_string() function (buffered get_string) in this file:
Quote: |
c:\program files\picc\examples\ex_zmd.c |
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|