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 support@ccsinfo.com

16f877a problem rs232 and delay_ functions

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



Joined: 08 Apr 2014
Posts: 3

View user's profile Send private message

16f877a problem rs232 and delay_ functions
PostPosted: Tue Apr 08, 2014 5:01 pm     Reply with quote

Hi all!!
I'm sorry to write on forum for a so stupid answer for almost of all but i can't get out.. Sad

I can't have a very simple working routine with a putc() and a delay_ms(500) together in the same while1...
Code:

#include <RS232doppio.h>

//#include <stdlib.h>

#define LCD_ENABLE_PIN PIN_D3
#define LCD_RS_PIN PIN_D2
#define LCD_RW_PIN PIN_D1
#define LCD_DATA4 PIN_D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7
#define codifica PIN_C0
#include <lcd.c>
#use rs232 (baud=9600, xmit=pin_c6, rcv=pin_c7, parity=N, stop=1, bits=8)

char rxMESS;
char txMESS;

#int_rda
void rda_isr()
{
      rxMESS=getc();//delay_ms(10)   
}

void main(){
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
      lcd_init();
      delay_ms(100);
   txMESS=0;
    while(1)
    {
         putc(txMESS);
         if (input(codifica)==0){
         txMESS++;
         }
         else{
         txMESS--;
         }
         output_high(PIN_B3);
         lcd_putc("\f");
         lcd_putc("SINISTRA ricevo ");
         printf(lcd_putc,"%d", rxMESS);
         lcd_putc("\n invio ");
         printf(lcd_putc,"%d", txMESS);       
         output_low(PIN_B3);
         delay_ms(500);
    }

}

This work perfectly in double pic comunication on Proteus but nothing arrive to hyperterminal.
Everything is ok if i put // to all my delay_ms in the code
Anyone have answer or I'm just in a stupid mystake???
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Tue Apr 08, 2014 5:07 pm     Reply with quote

Work on the KISS principal.
Get rid of Proteus/ISIS.
Use real hardware.
Test one thing at a time.
Learn to use the code button.
Post short, complete, compilable code we can copy & paste to test.

Mike
temtronic



Joined: 01 Jul 2010
Posts: 9164
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Apr 08, 2014 7:38 pm     Reply with quote

What Mike says plus...

always add 'errors' to to the use rs232(...options...), as it prevents the UART from 'locking up' after 3 characters...

always add a delay)ms(500); BEFORE the lcd_init(); function. This allows the LCD hardawre to 'get organized' before the PIC tries to access it.

also have a look at the examples that CCS supplies to see how to code.

hth
jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Apr 08, 2014 8:13 pm     Reply with quote

Quote:
#int_rda
void rda_isr()
{
rxMESS=getc();//delay_ms(10)
}

The problem is the same issue we get at least once a week on this forum.
He has a delay_ms() statement in his #int_rda and in his main().
The compiler is disabling interrupts during all delay_ms() statements in
main(), because the delay_ms() routine is not re-entrant in CCS.

The best solution is to just remove the delay_ms() from the #int_rda
routine. There's no reason to ever have a delay statement inside your
#int_rda routine.
lucadjr



Joined: 08 Apr 2014
Posts: 3

View user's profile Send private message

rs232 problem
PostPosted: Wed Apr 09, 2014 2:50 am     Reply with quote

Thx all for interest and quick answer!

I'm looking for a similar problem in internet since a week and didnt find, seems to be im the only one who want to have putc and delay funcions in while(1) together.

Quote:
Work on the KISS principal.
Get rid of Proteus/ISIS.
Use real hardware.
Test one thing at a time.
Learn to use the code button.
Post short, complete, compilable code we can copy & paste to test.


I cant write more stupid than this, this is just a test for implement rs232 in a bigger project and i cant use real hardware now :(
hope the code now is "compatible" to copy and paste, sorry im newbie of this forum.

This is more simple code to explain better what is my problem
Code:


#include <RS232doppio.h>

#include <lcd.c>

#define LCD_ENABLE_PIN PIN_D3
#define LCD_RS_PIN PIN_D2
#define LCD_RW_PIN PIN_D1
#define LCD_DATA4 PIN_D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7

#define codifica PIN_C0

#use rs232 (baud=9600, xmit=pin_c6, rcv=pin_c7, parity=N, stop=1, bits=8, ERRORS)

char rxMESS;
char txMESS;

#int_rda
void rda_isr()
{
      rxMESS=getc();   
}

void main(){
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);

      delay_ms(500);
      lcd_init();
      delay_ms(500);
      txMESS=0;
   
    while(1)
    {
         putc(txMESS);
         txMESS++;
         output_high(PIN_B3);
         lcd_putc("\f");
         lcd_putc("receive");
         printf(lcd_putc,"%d", rxMESS);
         lcd_putc("\n send ");
         printf(lcd_putc,"%d", txMESS);       
         output_low(PIN_B3);
         

         delay_ms(500);
    }

}


my problem is the last delay_ms(500) in the while (1) routine, when it is hyperterminal dont receive tx from pic, when its not everything work well.

On 2 pic comunication no problem with or without delay.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Wed Apr 09, 2014 10:18 am     Reply with quote

I said COMPILABLE not COMPATIBLE.

I want to be able to copy & paste your code, than run it as is.

Your code is not complete is any sense.

You do not tell us which PIC or compiler version you are using.

I do not have Proteus/ISIS, so test on REAL hardware only.

Mike
Ttelmah



Joined: 11 Mar 2010
Posts: 19346

View user's profile Send private message

PostPosted: Wed Apr 09, 2014 11:32 am     Reply with quote

There is a key thing to understand.

9600bps serial characters can potentially arrive at around 1000 characters per second.
Even if you are typing them, and 'think' you are only sending single characters, you can easily be sending multiple characters at a time (just hit enter - immediate CR+LF in most configurations.).
The serial ISR, must do just one job. Receive a character. Save it. Exit ASAP.
Delays break number 3 (in a 10mSec delay, 9 more characters could have arrived - immediate hardware overflow.....). Worse though is that because the PIC does not have a software stack, code must not be 're-entrant' (can't be called inside itself). So if you put a delay in the ISR, and then another in the main code, the compiler _has_ to ensure the ISR cannot be called from inside the delay in main.
There is no reason to delay in the ISR. If you want to delay the response, then do this outside in the main code. Re-write the ISR, so it uses a larger buffer (to deal with multiple characters arriving one after the other.

Look at the thread about 'RTC frequency of 1Hz'. Look at the suggestions for how to delay output, without using an actual delay in the main loop. Realise that this would apply to you as well.
ckielstra



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

View user's profile Send private message

PostPosted: Wed Apr 09, 2014 3:07 pm     Reply with quote

Code:
#include <lcd.c>

#define LCD_ENABLE_PIN PIN_D3
#define LCD_RS_PIN PIN_D2
#define LCD_RW_PIN PIN_D1
#define LCD_DATA4 PIN_D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7
Why did you change this from your first program???
The LCD data pin defines must be located before the #include !!! Rolling Eyes
lucadjr



Joined: 08 Apr 2014
Posts: 3

View user's profile Send private message

PostPosted: Thu Apr 10, 2014 8:40 am     Reply with quote

Quote:
I said COMPILABLE not COMPATIBLE.

I want to be able to copy & paste your code, than run it as is.

Your code is not complete is any sense.

You do not tell us which PIC or compiler version you are using.

I do not have Proteus/ISIS, so test on REAL hardware only.

Mike

Sorry Mike! I'm using CCS C 5.008 and the only thing i didn't write is the RS232.h file here below
Code:
#include <16F877A.h>
#device ADC=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O


#use delay(crystal=20000000,restart_wdt)


Quote:
...........Look at the thread about 'RTC frequency of 1Hz'. Look at the suggestions for how to delay output, without using an actual delay in the main loop. Realise that this would apply to you as well.


Thx very much Ttelmah! i understood the example and Timer is a thing i will test but i prefer to use not in this case.
REALLY THERE IS NO WAY TO DO SOMETHING LIKE:

Code:
while(1) {
putc(txMess);
delay_ms(123);
}

??????????? Sad

Quote:
Why did you change this from your first program???
The LCD data pin defines must be located before the #include !!! Rolling Eyes

I changed just to make a more understandable, i didn't test it and i don't know it will work.

Again thx very much all for help!! i studied this things at school many years ago and its very difficult now to do it without a teacher that kick me when I'm wrong... xD
jeremiah



Joined: 20 Jul 2010
Posts: 1322

View user's profile Send private message

PostPosted: Thu Apr 10, 2014 10:33 am     Reply with quote

I have a spare hardware board with an LCD, but it is a different model LCD and the PIC is a PIC24 chip.

I tossed in your program changing my FUSES, #use delay, pin assignments, and the program ran fine. I saw no problems with the output. Every character that I typed went through without an issue and was displayed.

Something to note:
Your pic's receiver buffer is only 2 chars deep. If it receives more than that during the delay, you'll miss chars

This means your problem is likely:
Proteus issue
Some code other than the test program you posted
LCD initialization (my LCD has a different initialize than yours)
Ttelmah



Joined: 11 Mar 2010
Posts: 19346

View user's profile Send private message

PostPosted: Fri Apr 11, 2014 8:23 am     Reply with quote

Yes.
There is no problem at all in doing:
Code:

while(1) {
putc(txMess);
delay_ms(123);
}   


So long as you don't delay in the INT_RDA, and rewrite the interrupt handler to use a reasonable sized buffer.

Key difference with Jeremiah's chip, is larger hardware buffers.

Use ex_sisr.c as an example of how to handle INT_RDA. If you want to delay after a character is received (only reason to have a delay in INT_RDA), then use:
Code:

    char c;
    //Inside the main loop
    if (bkbhit())
    {
        c=bgetc(); //get the character from the buffer
        delay_ms(xxx); //delay if you want
        //do what you want with the character.
    }
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