CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

problem int_rda with PIC 16F688
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ttelmah



Joined: 11 Mar 2010
Posts: 19830

View user's profile Send private message

PostPosted: Mon Nov 25, 2013 5:31 am     Reply with quote

The interrupt says _one_ character has been received. 'get_string', will hang waiting for the rest of the data to arrive. Not how it should be done. The whole point is that INT_RDA, should read just one character, save it is wanted, or throw it away, and exit. Nothing else. The 'string' has _not_ been 'received' when the interrupt occurs.
Look at the circular buffer examples.
Then you have get_string set to limit the length received to 9 characters. Can a 9 character array hold a 9 character string?....
I'm presuming you have one of the older faulty compiler versions that disables the GIE, during printf?. If not there is no point in having the extra enable_interrupt(GLOBAL) calls scattered through the code.
ftrax



Joined: 24 Sep 2013
Posts: 22
Location: España

View user's profile Send private message

PostPosted: Mon Nov 25, 2013 8:26 am     Reply with quote

Hi Ttelmah,

thanks for your response.

I already know that I don't have to wait for the rest of the data arrive, but I don't know how to do it if not thus.

I searched the example of "circular buffer" in CCS examples but I have not found.

Answering for the question of my array, I expect an array consisting 5 numbers, one point, and 3 numbers, example: 12365.635.

And yes, answering for your suposicion I put the extra enable_interrupt(GLOBAL) because after running the printf the interrupts are disabled.

I'm using the version 5.010, you think can be a compiler error?.

Thanks for all.
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Mon Nov 25, 2013 9:23 am     Reply with quote

Hi,

You need to store characters in a buffer, on-by-one, as they are received. The example program you want to look at is 'ex_sisr.c' in the Examples folder.

John
Ttelmah



Joined: 11 Mar 2010
Posts: 19830

View user's profile Send private message

PostPosted: Mon Nov 25, 2013 9:30 am     Reply with quote

The GIE problem was discussed here and fixed about three compiler versions ago (about 5.11!...). It was a problem that had show on much older compilers, been fixed, and then 're-appeared' with V5....

Understand that in 'C', a 'string', always has a null terminator character. So a 9 character 'string' _requires_ ten characters to store. The get_string function adds this terminator, so if asked to limit to nine characters, needs ten characters to hold the data. This is in basic C textbooks. It has also been covered here a lot of times.

I'd rather suspect if your number looks like this on a terminal program, that it has 'line feed' or 'carriage return' characters at the end. These are what should be being looked for to mark the end of the number, not just counting (bound to go wrong at some point).

ezflyr covers the other question.

Best Wishes
ftrax



Joined: 24 Sep 2013
Posts: 22
Location: España

View user's profile Send private message

PostPosted: Mon Nov 25, 2013 2:20 pm     Reply with quote

Hi,

Thank you ezflyr for tell me what is the example it I needed, and thank you Ttelmah to explain me the problem of the older versions at the compiler... that unfortunatly re-appeared' with the V5....

Finally I have seen the example of CCS "ex_sisr.c", and I learned a lot...

Then I have decided to create a buffer, to store the characters one-by-one, as they are received.

In my buffer only keep the characters of my interest, that way, I can get a smaller buffer without saving the "carriage return".

This is the source code:
Code:

#include <16F688.h>
//#device adc=10

#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOPUT                      //Power Up Timer
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOPROTECT
#FUSES NOCPD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOIESO
#FUSES NOFCMEN

//////////////////////////////////////////////
//////****CLOCK & RS232 CONFIGURATION****/////
//////////////////////////////////////////////
#use delay(internal=4000000)         
#use rs232(baud=9600,xmit=PIN_C4,rcv=PIN_C5,parity=N,errors)

//////////////////////////////////////////////
/////////****** FILES INCLUDED ******/////////
//////////////////////////////////////////////
#include <stdlib.h>
#include <input_mod.c>
#include <lcdindif.c>

//////////////////////////////////////////////
///////////****I/O CONFIGURATION****//////////
//////////////////////////////////////////////
#use fast_io(ALL)

#define CONFIGA 0b00000110
#define CONFIGC 0b00100000

#bit  BUZZER   = 0x7.0     //Is pin C0
#bit  STOLVA   = 0x5.1     //Is pin A1
#bit  isDIST   = 0X5.3

//////////////////////////////////////////////
/////////******** DEFINITIONS ********////////
//////////////////////////////////////////////
#define MS1       83
#define MS10      820
#define MS100     8320
#define BUFFER_SIZE 9

//////////////////////////////////////////////
////////////***GLOBAL  VARIABLES***///////////
//////////////////////////////////////////////
int1 refresca=0;
int1 alarmRPM=0,alarmAUX=0;

int8 hectarees[BUFFER_SIZE];

int16 counter=0;
int16 t1r=28036;
int16 delay=0;

float proba=0;
//////////////////////////////////////////////
//////////***** INTERRUPTIONS *****///////////
//////////////////////////////////////////////
//**************** INT RDA *****************//
#int_rda
void rda_isr() {
static int8 next_c;
int8 c=0;

   c=getc();

   if ((c>=' ')&&(c<='~')){
      if(next_c<=BUFFER_SIZE) {
         hectarees[next_c]=c;
         next_c=(next_c+1) % BUFFER_SIZE;       
      }
   }
   else
      if(c==13)
         next_c=0;
}
//**************** INT RDA *****************//
//!#int_rda
//!void rda_isr(void){
//!int8 x=0;
//!
//!if(input(PIN_C5))
//!   get_string(hectarees,9);   //Save the string received
//!else
//!   x=getc();   //Clear the interrupt if hasn't a character waiting to be read
//!   
//!}
//****************INT TIMER1****************//
#int_TIMER1
void TIMER1_isr(void) {

static int8 cont=0;
static int8 auxbuzzer;

set_timer1(t1r);        //Timer reloaded every 0.3s
cont++;

if((alarmRPM==1) || ((alarmAUX==1) && (auxbuzzer<4))){
   auxbuzzer++;
   BUZZER=~BUZZER;
}
else
   if(alarmAUX==1){
      auxbuzzer++;
      if (auxbuzzer>=6)       
         auxbuzzer=0;
      BUZZER=0;
   }


if(cont==2){
   cont=0;
   counter=get_timer0();   //Read counter TMR0
   set_timer0(0);          //reset  timer0
   //counter*=(100/2);     //Convert to RPM
                           //there are to pulses for round
   counter*=50;      //simplify -- to pulses for round
   refresca=1;
}
}

//////////////////////////////////////////////
///////////***** MAIN PROGRAM *****///////////
//////////////////////////////////////////////
void main()
{
   setup_adc(ADC_OFF);
   setup_adc_ports(no_analogs);
   setup_comparator(NC_NC_NC_NC);
   setup_counters( T0_EXT_L_TO_H | T0_DIV_1, T0_8_BIT );
   setup_oscillator(OSC_INTRC|OSC_4MHZ);
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
   setup_vref( VREF_HIGH );
   setup_wdt(WDT_OFF);   
     
   enable_interrupts(int_timer1);   
   enable_interrupts(int_rda);
   
   enable_interrupts(global);
   
   set_timer1(t1r);
   set_timer0(0);   

   set_tris_a(CONFIGA);
   set_tris_c(CONFIGC);
   
   output_a(0);
   output_c(0);       
 
   for(delay=0;delay<MS100;delay++);
   
   lcd_init();
   lcd_clear(); 
   
   while(true){
   
      if(refresca==1){
         refresca=0;
         //lcd_erase_line(2);
         lcd_gotoxy(1,2);
         proba=strtof(hectarees,9);
         printf(lcd_putc, "Hect: %10.3f" ,proba);
         enable_interrupts(global);           
      }   
   }
}


Thanks for all and Best Wishes! Wink
Ttelmah



Joined: 11 Mar 2010
Posts: 19830

View user's profile Send private message

PostPosted: Mon Nov 25, 2013 2:29 pm     Reply with quote

OK. Potentially a lot better.
But you need to add the null terminator character to the buffer when the CR is received.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
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