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

error char with #int_ext and #int_asr

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



Joined: 24 Mar 2004
Posts: 53
Location: Portugal

View user's profile Send private message Send e-mail MSN Messenger

error char with #int_ext and #int_asr
PostPosted: Wed Jun 30, 2004 7:08 am     Reply with quote

Hello:

My program send and receive data for Modem and PC. Have a real time clock to register event and send AT command to modem.
When I receive the data from software port, have a char error like �����������������.
It liked to know if the Interrupt OK

Code:



#include <16F877.h>
#fuses HS,NOPROTECT,NOWDT,NOLVP,PUT,NOBROWNOUT
#use delay(clock=16000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, STREAM=COM_A) 
#USE RS232(BAUD=9600, XMIT=PIN_B1, RCV=PIN_B0, STREAM=COM_B)


#int_ext   //interrupt for sotftware COM_B USART port
void vira()   
{
   dado_b=fgetc(COM_B);
   dado_b=toupper(dado_b);
   fputc(dado_b,COM_B);

}

#int_rda      //interrupt for hardware COM_A USART port
void seirala_isr()
{

   cmd=fgetc(COM_A);
        cmd=toupper(cmd);
        fputc(cmd, COM_A);

}

#int_timer0      //interrupt for real time clock

timer0_isr()
{
   clock-=256; // 256 > dois elevado a 8
   if(clock<256)
      {
      clock+=CLOCK_VAL;
      tick=1;
      seconds++;
      }
}


void init_chip()
{

   setup_adc_ports(No_Analogs);
   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_32);
   enable_interrupts(int_timer0); // Enable timer0 interrupt
   enable_interrupts(INT_RDA);
   enable_interrupts(int_ext);
   enable_interrupts(GLOBAL);
}


//...

void main()
{
      static boolean led2;
      init_ext_eeprom();

    init_chip();
   fprintf(COM_A,"\r\nRead or Write: ");
   
   while(1)
   {
         if (tick) // real time clock 1 second
         {
            tick=0;
            update_clock();
               led2 = !led2; // led flash 1 second
      output_bit (pin_c0,led2);
             
            }
     
      if(dado_b=='A')
      fprintf(COM_A,"Tunga........->");
     
      if(cmd=='R')
      {
     
      //...       
      read_eeprom_string(s, ROM_SMTP, ROM_SMTP_SIZE);
      fprintf(COM_B,"AT#ESMTP=\"%s\"\r\n",s);
      //...
       }


ckielstra



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

View user's profile Send private message

PostPosted: Wed Jun 30, 2004 10:14 am     Reply with quote

Code:
#int_ext   //interrupt for sotftware COM_B USART port
void vira()   
{
   dado_b=fgetc(COM_B);
   dado_b=toupper(dado_b);
   fputc(dado_b,COM_B);

}

This is not going to work for two reasons:
1) Don't put an fputc under software control in your interrupt routine! It will take as long as sending the whole character, resulting in the loss of an character on your receive pin.
2) The int_ext interrupt will be triggered on the first edge of the received start bit. Then your call to fgetc() will also wait for detection of a start bit... There are no 2 start bits and you are out of sync resulting in the garbage data you showed.

Conclusion: The CCS routines for software emulation of an UART are not compatible with interrupts. It is difficult, but possible, to create an interrupt based software UART. Search this forum for examples.
Ttelmah
Guest







PostPosted: Wed Jun 30, 2004 10:58 am     Reply with quote

Two comments.
You need to program the external interrupt to be on the falling edge.
Secondly (and more probably the problem), you may well find it impossible to do what you want at this baud rate, with everything else going on. At 9600bps, the 'bit time', is just 104uSec. Your processor clock gives 4 million instructions per second. Unfortunately, the behaviour will depend on the sequence of events, but if (for instance), your code is allready in the 'timer' interrupt, when the edge occurs on the software RS232, it'll take perhaps as much as 100 instructions, to execute this routine, then enter the software handler, which itself takes perhaps another 30 instructions. The software handler can be used in an interrupt like this, _but_ the routine will assume that the 'edge' of the start bit has occured at the momnt the fgetc is called (it looks for levels, not 'edges'). Hence the sample timing in the data, could be as much as 50u to 60uSec 'late' in the example given. In fact this is only a guess, and is probably an underestimate. I'd not expect this to work reliably, with any other interrupt in use, at baud rates above perhaps 1200bps...
I'm afraid you need to rethink your hardware to make this work properly.

Best Wishes
carlosma



Joined: 24 Mar 2004
Posts: 53
Location: Portugal

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Wed Jun 30, 2004 1:43 pm     Reply with quote

hello

now the system works, because I added the line:

Code:

ext_int_edge( H_TO_L );   // Sets up EXT


Carlos
ckielstra



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

View user's profile Send private message

PostPosted: Wed Jun 30, 2004 4:15 pm     Reply with quote

Congatulations! You have proven my second point to be wrong.

Still, the other remarks (from me and Ttelmah) are still standing and I hope you give them a serious thought...
carlosma



Joined: 24 Mar 2004
Posts: 53
Location: Portugal

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Thu Jul 01, 2004 2:36 am     Reply with quote

Thanks for all

both the PORTS, COM_A and COM_B function when sending or receive char, but I think that I go to have problems when to try to send strings.
To reduce the problems I go to lower baud rate.

Carlos
Ttelmah
Guest







PostPosted: Thu Jul 01, 2004 7:27 am     Reply with quote

carlosma wrote:
Thanks for all

both the PORTS, COM_A and COM_B function when sending or receive char, but I think that I go to have problems when to try to send strings.
To reduce the problems I go to lower baud rate.

Carlos

It is much more likely to be reliable on the software receive, in the long run. However there is then another 'caveat'. Unfortunately, while it is receiving the character inside the ISR, all the other interrupts are effectively disabled if you run the soft uart at 1200, and data arrives on the 9600bps 'hardware' link while you are in the ISR, if more tha a couple of characters arrive, you will trigger a com overrun on the hardware link, and lose data. So long as none of your interrupt routines are going to get any longer, stick at 9600bps, use the #priority statement to set the software receive isr to have the highest priority, followed by the hardware serial receive, and do some testing.

Best Wishes
carlosma



Joined: 24 Mar 2004
Posts: 53
Location: Portugal

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Thu Jul 08, 2004 12:26 pm     Reply with quote

After some alterations, I continue with problems in both Interrupts, because I can't read the data incoming by Modem GSM on EXT_INT.
When I test with hyperterminal all the system work fine but not with modem.
Only wanted to read the "RING" or "OK"


now my code:

Code:

#use delay(clock=16000000)
#use rs232(baud=1200, xmit=PIN_C6, rcv=PIN_C7, STREAM=COM_B)  //hardware
#USE RS232(BAUD=9600, XMIT=PIN_B1, RCV=PIN_B0, STREAM=COM_A)

//...

#int_rda
void vira()   

{
char c;

        c=fgetc(COM_B);

        if ((c>=' ')&&(c<='~'))
          { 
           buffer1[len] = c;
           len++;
          }
 
       if(c==0x0A ||c==0x0D) // I gues End Of String
        {
          bit_com_b=1;  // All OK
        }
      if(len >=  BUFFER_SIZE)
        {
          //bit_set(ModemFlag,RecErr);  // Something wrong !!
          disable_interrupts(INT_RDA); // Get out & ovoid reentrance
          len=0;
        }
        fputc(c, COM_A);//just for test arrive char
}


#int_ext
void seirala_isr()
{
      
        cmd=fgetc(COM_A);
        cmd=toupper(cmd);
        fputc(cmd, COM_A);
 }


//..
// now, read and compare with String "RING" or "OK"

read_eeprom_string(s, ROM_ackmodem, ROM_askmodem_SIZE);
           
      if (strncmp (buffer1, s, 5)==0)
            {
            fprintf(COM_A,"\r\nComutado\r\n");
            disable_interrupts(INT_RDA);//disable interrupt port b
            fprintf(COM_B,"AT+CMGR=1\n");
            delay_us( 1000 );
            enable_interrupts(INT_RDA);
            len=0;
            bit_com_b=0;


       

Thank you
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