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

rs232 character receiving

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ssaakmnt



Joined: 03 Dec 2011
Posts: 27

View user's profile Send private message

rs232 character receiving
PostPosted: Sat Dec 03, 2011 2:41 am     Reply with quote

hello every one i have no much experience with pic i try to send character (or int) with rs232 to break a while loop , the code is ok except the second while loop that i cant escape

#include <16F84.H>
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_a0, rcv=PIN_a1)
void main() {

while(1){

char c;
c=getc();

switch (c)
{
case '1':
output_high(pin_b0);
break;
case '4':
output_low(pin_b0);
break;
case '2':
output_high(pin_b1);
break;
case '5':
output_low(pin_b1);
break;
case '3':
output_high(pin_b2);
break;
case '6':
output_low(pin_b2);
break;
case '7':
while(!c == '4')
{output_high(pin_b0);
delay_ms(100);
output_low(pin_b0);
delay_ms(100);}
break;
}
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Sat Dec 03, 2011 3:37 am     Reply with quote

Think about it:
Code:

    case '7':
      while(!c == '4') {
         output_high(pin_b0);
         delay_ms(100);
         output_low(pin_b0);
         delay_ms(100);
     }
     break;
   }

You execute this code, if c=='7'. Now c therefore is _not_ going to be '4', so the while loop will execute. Inside the while loop, c never changes, so the loop _will_ execute for ever.
If (for instance), you wanted this to execute four times, you would need:
Code:

    case '7':
      for (c=0;c<4;c++) {
         output_high(pin_b0);
         delay_ms(100);
         output_low(pin_b0);
         delay_ms(100);
     }
     break;
   }

Also learn to use the code buttons, and indentation....

Now if you want the rs232 to 'break' the loop, you need to rethink big time. You are using software RS232. This implies that characters can't signal your code to do anything. Your code needs to _test_ for the characters all the time, and at 9600bps, if data is not going to be missed, the test needs to be at least 20000 times per second. Are you testing inside the delays?. No. Are you testing in the inner while loop?. No. So the characters will be missed.....

It is possible to program what you want, (I think, from your basic description), but involves much more work. A number of possibilities, and all involve more thinking. For example:
Code:

   int16 ctr;
   c=0;
   do {
      output_high(PIN_B0);
      for (ctr=0;ctr<1000;ctr++) {
        delay_us(90);
        if (kbhit()) {
           c=getc();
           break;
        }
      }
      if (c!=0) break;
      output_low(PIN_B0);
      for (ctr=0;ctr<1000;ctr++) {
        delay_us(90);
        if (kbhit()) {
           c=getc();
           break;
        }
     }
   } while (c==0);
   //You get here if a RS232 character arrives, with the character in c

This is about the crudest way, without involving interrupts for either the flashing, or the RS232. You loop in a much faster delay loop (about 100uSec/loop with the increment and test), and if a character is seen (kbhit) fetch it, and exit.

Best Wishes
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Sat Dec 03, 2011 6:44 am     Reply with quote

Sooner or later and most often it is sooner most realize that in order to avoid the dropping of inbound characters an isr driven circular buffer is needed. I'd recommend searching this forum for examples. CCS has a good example of a circular buffer. Now of course this assumes you will use the hardware UART. Again most will use the hardware inside the PIC chip for RS232 since that's what it is there for.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sat Dec 03, 2011 8:13 am     Reply with quote

The PIC16F84(A) has no hardware UART. Receiving serial data is still possible because the CCS compiler will create a software based UART but this comes with limitations:
- No interrupts possible for received data
- Because no interrupts, no background reception of data.
- Data can only be received when getc() is active. This means you have to call kbhit at least ten times the bit rate.

Some people combined the CCS software UART with an interrupt on the RB0/INT pin, then most of the above mentioned limitations are gone. However, because of delays in interrupt handling this only works when your maximum baudrate is about 400 times smaller than your clockspeed. For example at 4MHz the maximum baudrate would be about 10kbaud. ~ 9600baud.

However, best solution in my opinion is to choose another chip with hardware UART. The PIC16F64 is very, very, old. Newer chips are cheaper, use less power and have more options.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Sat Dec 03, 2011 9:13 am     Reply with quote

I think you are slightly 'overstating' the speeds necessary.

You can use the INT_EXT triggering getc, up to about 1/120th your clock speed, rather than 1/400th your clock speed. You need to use the 'SAMPLE_EARLY' option. Then the getc, starts reading immediately when you arrive in the interrupt, instead of delaying by 1/2 a bit time, and given the typically 30 instruction times needed to get into an interrupt (120 clock cycles), this allows operation up to about 32Kbaud at 4MHz.
Similarly on how often you need to poll the pin, anything over twice, and preferably at least 3* per bit time is OK, not "ten times bit rate".

However agree wholeheartedly, the hardware UART, is simpler, better, just 1000* simpler, etc. etc...

Best Wishes
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Sat Dec 03, 2011 9:35 am     Reply with quote

Quote:

No interrupts possible for received data


sorry not precisely true -- ther are ways to use int and a defined communication protocol that i did almost 2 years ago , based on the hardware ISR method. i wrote a driver that utilizes the edge interrupt of
B port pins to create an ISR for non hardware rs-232 - and posted here
earlier this year.........

http://www.ccsinfo.com/forum/viewtopic.php?t=46369&highlight=

while i agree with the previous post that YES -
it still has the other liabilities of software rs-232 -
a lack of interrupt mediated reception is NOT One of them

if you use host_command --> pic_response protocols - this can work well enough. if data can arrive with really NO warning - then even this will fail you eventually.

Very Happy
ssaakmnt



Joined: 03 Dec 2011
Posts: 27

View user's profile Send private message

PostPosted: Sun Dec 04, 2011 5:29 am     Reply with quote

thank you for all your discussions guys there is a lot to think about .. and thank you Ttelmah for the code i will try it Smile
plainas



Joined: 22 Mar 2010
Posts: 4
Location: Portugal -> Aveiro

View user's profile Send private message MSN Messenger

PostPosted: Wed Dec 07, 2011 5:59 pm     Reply with quote

hello I made a personal code that is tested, works as follows to send pic [sdfsdfsdvfgsd] know that the pic is shows the string and string. and is equal to an integer and a character.

eg to send the pic -> [c] / / character
-> [125] / / decimal integer 125
-> [Pedro] / / string "Peter"

I hope it is useful, this program is not good because the pic for the cycle.

Code:

//***********************************************************

#include <16f877.h>         // identifica microcontrolador alvo
#device ADC=10              // define AD para 10 bits, variando de 0 a 1023
#use delay (clock=4000000)  // <- define cristal para 20Mhz. Para outros valores, mude e recompile.
#use  RS232(baud=9600, xmit=PIN_C6,rcv=PIN_C7,STREAM = COM_1) // configura serial

 // serial configurada para velocidade de 9600 bps
 // sem paridade, 8 bits
#include <string.h>
#include <stdlib.h>

//******************************************************************************
//******************************************************************************
void compara_rx();

//******************************************************************************
//******************************************************************************
//******************************************************************************

// VALORES FINAIS DE RESULTADOS:
   int n=0;
   char valor[30];
   char x='\0';
   int1 f_inicio=0;
   int1 f_fim=0;
   int1 f_inteiro=0;
   int1 f_caracter=0;
   int1 f_string=0; 
   int resultado_int=0;
   char resultado_char='\0';
   char resultado_string[30];
//******************************************************************************
//******************************************************************************
//******************************************************************************
   boolean    f_100ms_0= 0;
   boolean    f_500ms_0= 0;
   boolean    f_1000ms_0= 0;


//*****************************************************************************
//*****************************************************************************
#int_timer0
void trata_t0(){         // FUNÇAO PARA CONTAGEM DE TEMPO DE 4 Ms

 //  static long int cont_rs232=0;
   static long int cont_100=0;
   static long int cont_500=0;
   static long int cont_1000=0;
 
   set_timer0(131 + get_timer0());
   
   cont_100++;
   cont_500++;
   cont_1000++;

   if(cont_100==25){//100ms
      cont_100=0;
      f_100ms_0=!f_100ms_0;
   }
   
   if(cont_500==125){//500ms
      cont_500=0;
      f_500ms_0=!f_500ms_0;
     
   }
 
   if(cont_1000==250){//1000ms
      cont_1000=0;
     f_1000ms_0=1;
   }
}

//******************************************************************************
//***************************** RS232 ******************************************
//******************************************************************************
void recebe_dado_2(){
     
   if(kbhit (COM_1)==0){
      return;
   }
   x=getc();
   valor[n]=x;
 //  putchar(x);
 
// INICIO:
   if(x=='[' && !f_inicio){
      f_inicio=1;
      f_fim=0;
   }
// FIM:   
   if(x==']' && f_inicio){
      f_inicio=0;
      f_fim=1;
   }   
   
//RECEBE UMA STRING E DEPOIS COMPARA:
   if(f_inicio && ((x>=' ' && x<='Z') || (x>='a' && x<='z'))){
      valor[n]=x;
      n++;
   }
   
   if(f_fim){
      f_fim=0;
      valor[n]='\0';
      x='\0';
      //printf("\r\nSTRING ->%s",valor);
      n=0;
      f_string=0;
      compara_rx();
   }
}
//******************************************************************************
//***************************** RS232 ******************************************
//******************************************************************************
void compara_rx(){

   int comp=0;
   int n=0;
   comp=strlen(valor);
   f_inteiro=1;
   f_caracter=1;
   f_string=1; 
   //printf("\n\rCOMPRIMENTO DA STRING -> %u",comp);
   
      for(n=0;n<comp;n++){
         // NUMERO INTEIRO 
         if((valor[n]>='0' && valor[n]<='9') && n<3 && comp<=3){
           
         }
         else{
            f_inteiro=0;
            //printf("\n\r INTEIRO FALHOU!");
         }
      }
     
   for(n=0;n<comp;n++){

      // CHAR     
      if(((valor[n]>=' ' && valor[n]<='/') || (valor[n]>=':' && valor[n]<='Z') || (valor[n]>='a' && valor[n]<='z')) && n==0 && comp==1){
         
      }
      else{
         f_caracter=0;
        // printf("\n\r CARACTER FALHOU!");     
      }
      // STRING     
      if(((valor[n]>=' ' && valor[n]<='Z') || (valor[n]>='a' && valor[n]<='z')) && comp>=2 && !f_inteiro){
         //f_string=1;
      }
      else{
         f_string=0;
         //printf("\n\r STRING FALHOU!");       
      }
   }
   
   if(f_inteiro){
      resultado_int=atoi(valor);
      printf("\r\nO VALOR RECEBIDO FOI INTERIRO: -> %u",resultado_int);
   }
   
   if(f_caracter){
      resultado_char=valor[0];
      printf("\n\rO VALOR RECEBIDO FOI CARACTER: -> %c",resultado_char);
   }
   if(f_string){
      strcpy(resultado_string,valor);
      printf("\r\nO VALOR RECEBIDO FOI STRING: -> %s",resultado_string);
   }
}   
//******************************************************************************
//******************************************************************************
//**************************** MAIN ********************************************
//******************************************************************************
void main(){

  setup_timer_0 ( RTCC_INTERNAL | RTCC_DIV_32 );
  set_timer0(131);
  enable_interrupts(global|int_timer0);

  printf("\n\rLEIRURA DE PORTA COM!");
//******************************************************************************
//******************************************************************************
   while(true){
   
   if(f_100ms_0){
      output_high(pin_b0);
   }
   else{
      output_low(pin_b0);   
   }
   
      recebe_dado_2();
   
      if(f_inteiro){
         f_inteiro=0;
         printf("\r\nO VALOR RECEBIDO FOI INTERIRO: -> %u",resultado_int);
         printf("\r\n -> %u",resultado_int);         
      }
      if(f_caracter){
         f_caracter=0;
         printf("\n\rO VALOR RECEBIDO FOI CARACTER: -> %c",resultado_char);
         printf("\n\r -> %c",resultado_char);         
      }
      if(f_string){
         f_string=0;
         printf("\r\nO VALOR RECEBIDO FOI STRING: -> %s",resultado_string);
         printf("\r\n-> %s",resultado_string);
      } 
   }
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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