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

Can not receive RS-232 data when used I2C

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



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

Can not receive RS-232 data when used I2C
PostPosted: Tue Aug 20, 2013 12:42 am     Reply with quote

Hi all Smile
I'm having a problems when using both Rs232(int_rda) and I2C in one project.
In my project, I receive data from PC throught RS232 port, then PIC will processing data with DS1307 data; fina,l send processed data to matrix led board.
When I reading data from DS1307, the int_rda interrrupts not work, seem it can not true data in int_rda interrupts,so that i can't receive any data.
Pls show me way to fix it, i don't used int_ssp interrupts to avoid conflict between I2C and RS232 interrutps.
Thank so much !
I used PIC18F4680, CCS C ver 5.011.

Code:

Code:



#include <18F4680.h>
#fuses H4,PUT,NOPROTECT,NOLVP,NOWDT,NOBROWNOUT,NOPBADEN, NODEBUG
#use delay(clock=40000000)
#use rs232(baud=4800, xmit=PIN_C6, rcv=PIN_C7, errors) // HARD UART



#include <string.h>
#include <stdio.h>
#include <stdlib.h>

//#priority rda
#include <font.c>
#include <matrix_control_home.c>
#include <ds1307.c>
#include <GLCD_192X64.c>
#include <graph.c>



char str_rs232[19]; // str-time:18 byte
char str_disp[19]; // str-time:18 byte

char str_time_ds1307[19]; // str_time
char str_plan[19]="000";        // str_plan
char str_std_time[19]="00:00";    // str_standard_time

char c;

unsigned int8 l;
unsigned int8 i_str=0;

unsigned int8 index=0;
unsigned int1 chk_time=0;
unsigned int1 check_reset_cpu=0;
unsigned int1 check_data_time=0;

unsigned int1 check_read_ds1307=1;
unsigned int1 dis_read_ds=0;
unsigned int16 count_timer0=0;
unsigned int8 temp=0;


#include <xoa_bufer.c>

void reset_mbi(void);
void out_byte(unsigned int8 b);
void hienthi(void );

void xoaram(void);
void save_ram2(int8 ky_tu);   
void chaychu(void);
void don_chu(int8 chu,int8 irow,int16 icol);




//==============================================================================
//               TIMER0
//==============================================================================
#int_timer0
void ngat_timer0(void)
{
   set_timer0(62);
   count_timer0++;
   if( count_timer0==2)
   {
      //output_toggle( PIN_C2);
      count_timer0=0;
      check_read_ds1307=1;     
   }
   
}


//==============================================================================

#int_rda
void ngat_rs232()
{
 
   
   c=getc();
   switch(c)
      {
     
         case '$':
            {
               index=0;               
            }
         break;
         //------------------------
         
         case '*':
            {
               if((str_rs232[0]=='1')&&(str_rs232[1]=='T')&&(str_rs232[2]=='I')&&(str_rs232[3]=='M')&&(str_rs232[4]=='E'))
               {
                  index=0;
                  chk_time=1;
                 
               }                                         
            }
         break;
         //------------------------- 
         
         case '#':
            {               
               if((chk_time==1)&&(index==18)) // chuoi time 18 ki tu
               {
                  //disable_interrupts(int_rda);
                  chk_time=0;
                  check_data_time=1;
                  index=0;
                  output_toggle(PIN_c2);
               }
               
               if((str_rs232[0]=='1')&&(str_rs232[1]=='T')&&(str_rs232[2]=='R')&&(str_rs232[3]=='S')&&(str_rs232[4]=='T'))
               {
                  check_reset_cpu=1;
               }                           
            }
          break;
         //-------------------------
         
         default:
            {
               str_rs232[index]=c;
               index++;
            }
         break;
     
      }  // end of switch     
}        // end of int_rda


//******************************************************************************
//********************  MAIN PROGRAM               ************************************
//******************************************************************************


void main(void)
{

   delay_ms(100);
   set_tris_a(0);
   set_tris_b(0);//
   //set_tris_c(0x80);
   set_tris_d(0);   
   set_tris_e(0);
   
   output_high( PIN_c2);
   output_high(PIN_C1);
   delay_ms(50);
     
   xoa_buffer();   
   reset_mbi();
   xoaram();   

   cursor=0;
   printf(save_ram2,"000@11:22:33;00:00");
   hienthi();   
   
   set_timer0(62);   
   setup_timer_0 (RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_256);
   
   if(read_eeprom(0)==0xff)
   {
      write_eeprom(0,1);
      init_ds1307 ();               // initial DS1307
      sec = read_ds1307 (0) ;
      write_ds1307 (0, sec & 0x7F);   // enable oscillator (bit 7 = 0) 
      settime_ds1307();
   }
   
   enable_interrupts(int_timer0);
   enable_interrupts(int_rda);
   enable_interrupts(global);
   
   printf(" test ");

   
   while(1)
   { 
         
 //=================================================================================
         
         if(check_reset_cpu==1)
         {
            reset_cpu();
            check_reset_cpu=0;
         }
         
//=================================================================================
         
         if(check_data_time==1)
         {
            check_data_time=0;
            output_toggle( PIN_C2);
           
            for(i_str=0; i_str<3; i_str++)
            {
               str_plan[i_str] = str_rs232[i_str];
            }
           
            for(i_str=0; i_str<4; i_str++)
            {
               str_std_time[i_str] = str_rs232[i_str+14];
            }
         }         
         
//=================================================================================         
         
         if((check_read_ds1307==1))
         {
            check_read_ds1307=0;
            disable_interrupts(int_timer0);
            gettime_ds1307();
            enable_interrupts(int_timer0);
           
            temp = hour;
            hour = ((( hour & 0xf0 )>>4)*10)+(temp & 0x0f);           
            temp = min;
            min  = ((( min & 0xf0)>>4)*10) + (temp & 0x0f);           
            temp = sec;
            sec  = ((( sec & 0xf0)>>4)*10) + (temp & 0x0f);                     
                     

            xoa_str_disp();
            strcpy(str_disp,str_plan);
            sprintf(str_time_ds1307, "@%02u:%02u:%02u;", hour,min,sec);
            strcat(str_disp, str_time_ds1307);
            strcat(str_disp, str_std_time);

         }
         
         xoaram();   
         printf(save_ram2,str_disp);
         xoa_buffer();         
         cursor=0;
         hienthi();         
         
   } // end of while   
}     // end of main
 


_________________
Begin Begin Begin !!!
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Tue Aug 20, 2013 1:28 am     Reply with quote

You never need SSP interrupts on a master. Slave, yes.

There are some things that 'worry' me.

You have no 'bounds' checking on where you write data to the RS232 array. If the 'end of time' sequence gets missed for any reason, or an extra character is received, your buffer will overflow, and destroy data in memory. I'd suggest, making the buffer a character larger, and where you write to the buffer, have something like:
Code:

         default:
            {
               str_rs232[index]=c;
               if (index<19) index++;
            }

This way it'll stop incrementing, if it gets to the end of the array.

Second thing, is strings. You copy the 'time' from str_rs232, but nowhere that I can see, do you add a terminating NULL. A 'string' in C, is _not_ just a sequence of characters. It is a sequence of characters _terminated with a NULL_. Without this, anything using the sequence as a 'string', risks walking over the rest of memory.

Then you have to consider, what happens if a character arrives, at the same moment you are copying the string?. This is why it is much better to effectively always 'process' data in a separate array to the one that is receiving the data. Hence, use a circular buffer (say), and copy the received data from this into the array for processing.

Now, consider switching to using software I2C....
It won't really lose you anything, and unfortunately, your chip has some very nasty I2C hardware bugs. It is possible to bodge round most of them, but there are something like a dozen problems with the I2C hardware, some of which can leave the I2C hung....
It has problems with not initialising correctly (I had to write my own initialisation code), and you have to poll before writing to SSPBUFF, to verify that a transmission is not in progress, when doing sequential writes.
The software implementation is _much_ more reliable on these chips. Unless you need hardware (for a slave), stick with software.

Best Wishes
tienchuan



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

PostPosted: Tue Aug 20, 2013 2:18 am     Reply with quote

Thanks u ! Ttelmah
I tested with DS1307 is run correctly, read time is OK and display true on led matrix board.
I think and done to avoid eerors ,same as you tell by the way:

+
Quote:
Then you have to consider, what happens if a character arrives, at the same moment you are copying the string?

I have disable int_rda after finish receive one string, then processed this string, and final, enable this rda interrupts again, to receive another string come on.
+
Quote:
You copy the 'time' from str_rs232, but nowhere that I can see, do you add a terminating NULL

I calculated and added NULL character to string, so that it length 19 byte ( 18byte+ 1 byte null).
I checked again and saw the rda interrupts receive failure data, not don't receive any data, seems it corrupts data received.
My format data to send led matrix board is:(. exp)
Code:
000@11:22:33;44:55

In which:
- 000: plan exting ( rcv from PC)
- 11:22:33: format hh:mm:ss ( time data read from DS1307)
- 44:55: format standard time (also. rcv from PC)
so that i need processing strings before send to led matrix board to display.
Thanks u so much!!!
_________________
Begin Begin Begin !!!
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Tue Aug 20, 2013 2:41 am     Reply with quote

You do not want to disable interrupts while 'processing' the string. Sure way of missing things. It takes a long time to access characters in an array. Typically a dozen instructions for each character. If you are 'processing', this takes even longer, and you run into losing data. This is why the buffer should be separate from the processing string. Have just a small (8 character) ring buffer, and move dataas needed from this into your processing string.
Other way, disable interrupts, and use memcpy, to copy the 'interrupt' string to a separate processing buffer, then immediately re-enable the interrupts, then process the copy. Memcpy, is written to be as fast as possible to just move a block of memory from one location to another.
I's think you are actually getting an _overrun_ when you process the data, and hence a corrupted character. I suspect if you tested RS232_ERRORS you would find OERR being flagged.


Best Wishes
temtronic



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

View user's profile Send private message

PostPosted: Tue Aug 20, 2013 8:59 pm     Reply with quote

You might consider using the interrupt available from the DS1307 as the INT_EXT source.
You program the DS1307 for a 1Hz interrupt.Be sure to add a pullup ! 3k3 works fine at 5 volts.

I've done this with the 18F46K22 for about 2 years and it easily handles both RTC and Serial at 115K200.

hth
jay
tienchuan



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

PostPosted: Wed Aug 21, 2013 2:49 am     Reply with quote

temtronic wrote:
You might consider using the interrupt available from the DS1307 as the INT_EXT source.
You program the DS1307 for a 1Hz interrupt.Be sure to add a pullup ! 3k3 works fine at 5 volts.

I've done this with the 18F46K22 for about 2 years and it easily handles both RTC and Serial at 115K200.

hth
jay

thanks temtronic
Can you send me a sample code of your project?
If had, pls send me to email: tienchuanct@gmail.com
thanks uSmile
_________________
Begin Begin Begin !!!
tienchuan



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

PostPosted: Wed Aug 21, 2013 7:11 pm     Reply with quote

Quote:
Ttelmah:
Then you have to consider, what happens if a character arrives, at the same moment you are copying the string?. This is why it is much better to effectively always 'process' data in a separate array to the one that is receiving the data. Hence, use a circular buffer (say), and copy the received data from this into the array for processing.

Hi Ttelmah
You can give me a example code for circular buffer, work with RDA interrupts.
I found in library of 4rum but haven't a example code work with 2 modes: tx and rx ( used uart interrupts)
Thanks u.
_________________
Begin Begin Begin !!!
jeremiah



Joined: 20 Jul 2010
Posts: 1346

View user's profile Send private message

PostPosted: Wed Aug 21, 2013 7:16 pm     Reply with quote

if you look in your examples folder in your PICC directory, you will find a file titled ex_sisr.c which has a good example of how to use interrupt driven uart receive. I would start with that.
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