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

uart Problem with pic 18F2525

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



Joined: 21 Oct 2010
Posts: 85

View user's profile Send private message

uart Problem with pic 18F2525
PostPosted: Tue Jul 14, 2015 11:25 pm     Reply with quote

PIC 18F2525, compiler version 5.0.32

I want to read data from UART stream DATA and send send an answer back after validity check through the stream CONTROL.

Here is my header file:
Code:

#include <18F2525.h>
#device ADC=10
#define FOSC 40000000 
#fuses WDT, WDT512, NOPROTECT, BROWNOUT, PUT, NOLVP, H4 //,NOMCLR,
#use delay(clock=FOSC,  restart_wdt)

#define SPI_MODE_0_0 0x4000
#define SPI_MODE_0_1 0x0000
#define SPI_MODE_1_0 0x0010
#define SPI_MODE_1_1 0x4010

#define EEPROM_SELECT PIN_B4
#define EEPROM_CLK    PIN_C3
#define EEPROM_DO     PIN_C5
#define EEPROM_DI     PIN_C4


//serial interface
#use rs232(stream=DATA, baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8, ERRORS)
#use rs232(stream=CONTROL, baud=115200,parity=N,xmit=PIN_B5,rcv=PIN_B0,bits=8, ERRORS)

//pin definiton
#define SIGN_ON PIN_C0           //indicates wehn sign is shown 8 importand for flsher

//global constants
#define C_TOTAL_LED     576      //led count per sign
#define C_INP_DATA_LEN  2347     //input data lenght
#define C_START_S1      38       //arrayposition start S1 data
#define C_START_S2      1193     //arrayposition start S2 data


My source file:

Code:

/////////////////////////////////////////////////////////////////////////////
//
// Include libraries
//
/////////////////////////////////////////////////////////////////////////////
#include <modulControl.h>
#include <stdlib.h>
#include <ds1302.c>
#include "25LC640.c"

/////////////////////////////////////////////////////////////////////////////
//
// Global definitions
//
/////////////////////////////////////////////////////////////////////////////
char InputData[C_INP_DATA_LEN];  //Input data array
int16 InputIndex=0;              //Input data index
unsigned int16 value=0;          //Photoresistor adc value
int1 NewData=FALSE;              //New data available
int1 isDataOk=0;                 //Data received ok?
int16 Counter=0;
unsigned int16 sumvalue=0;
unsigned int16 pwmvalue=500;     //Output pwm value (max. 500);
int1 isSignOn=true;              //indicates sign is on or off
char chr='A';

//rtc variables
unsigned int8 day=20;
unsigned int8 mth=6;
unsigned int8 year=15;
unsigned int8 dow=0;
unsigned int8 hour=0;
unsigned int8 min=0;
unsigned int8 sec=0;
unsigned int8 interval=0;          //interval duration in ms
unsigned int8 starthour=0;         //hour begin display sign one
unsigned int8 startmin=0;          //minute begin display sign one
unsigned int8 stophour=0;          //hour stop display sign one
unsigned int8 stopmin=0;           //minute stop display sign one

/////////////////////////////////////////////////////////////////////////////
//
// Sub Functions
//
/////////////////////////////////////////////////////////////////////////////
// Convert two hex characters to a int8
unsigned int atoi_b16(char *s)

   unsigned int result = 0;
   int i;

   for (i=0; i<2; i++,s++)  {
      if (*s >= 'A')
         result = 16*result + (*s) - 'A' + 10;
      else
         result = 16*result + (*s) - '0';
   }

   return(result);
}

/////////////////////////////////////////////////////////////////////////////
//Send data to the sign
void SendData(int16 from)
{
   char s[3];
   char x;
   int16 i=1;
   int16 bytecount=0;
   
   set_pwm1_duty(0xffff);
     
   for(bytecount=from; bytecount<C_TOTAL_LED*2+from; bytecount+=2)
   {
       s[0]= read_ext_eeprom(bytecount);
       s[1]= read_ext_eeprom(bytecount+1);
       s[2]='\0';
       char x = atoi_b16(s);
       fputc(x, DATA); 
       
      if((i)%24==0)
      {
         fputc('#', DATA); 
         delay_ms(7); //delay between each pic !!! important
      }
      i++;
      restart_wdt();
   }
   set_pwm1_duty(pwmvalue);
}

/////////////////////////////////////////////////////////////////////////////
//Write new data to the EEPROM
void WriteToEEPROM(void)
{
   int16 bytecount=0;
   for(bytecount=0; bytecount<C_INP_DATA_LEN; bytecount++)
   {
      write_ext_eeprom(bytecount, InputData[bytecount]);
      restart_wdt();
   }
}

/////////////////////////////////////////////////////////////////////////////
//Read last data from the EEPROM
void ReadFromEEPROM(void)
{
   int16 bytecount=0;
   for(bytecount=0; bytecount<C_INP_DATA_LEN; bytecount++)
   {
      InputData[bytecount] = read_ext_eeprom(bytecount);
      restart_wdt();
   }
}

/////////////////////////////////////////////////////////////////////////////
//Analyse data
void AnalyseData(void)
{
   //012345678901234567890123456789012345
   //XXTT:1032TS:2000TE:2300IV:50SI:1152S1:[576]S2:[576]
   char help[3];
   
   //hour
   help[0]=read_ext_eeprom(5);
   help[1]=read_ext_eeprom(6);
   help[2]='\0';
   hour = atoi(help);
   
   //minute
   help[0]=read_ext_eeprom(7);
   help[1]=read_ext_eeprom(8);
   help[2]='\0';
   min = atoi(help);
   
   //starthour
   help[0]=read_ext_eeprom(12);
   help[1]=read_ext_eeprom(13);
   help[2]='\0';
   starthour = atoi(help);
   
   //startmin
   help[0]=read_ext_eeprom(14);
   help[1]=read_ext_eeprom(15);
   help[2]='\0';
   startmin = atoi(help);
   
   //stophour
   help[0]=read_ext_eeprom(19);
   help[1]=read_ext_eeprom(20);
   help[2]='\0';
   stophour = atoi(help);
   
   //stopminute
   help[0]=read_ext_eeprom(21);
   help[1]=read_ext_eeprom(22);
   help[2]='\0';
   stopmin = atoi(help);
   
   //interval
   help[0]=read_ext_eeprom(26);
   help[1]=read_ext_eeprom(27);
   help[2]='\0';
   interval = atoi(help);
   
   //if end time less than start time add twelve hours
   if(starthour > stophour) { stophour += 24; }
}

/////////////////////////////////////////////////////////////////////////////
//Set pwm value
void SetPWMValue(int1 start)
{
   
   value=read_adc();
   if(value > 500) { value=500; }
   
   //if start, set pwm direct to display sign
   if(start==TRUE)
   {
      set_pwm1_duty(value);    //PWM output 1
      set_pwm2_duty(value);    //PWM output 2 
   }
   sumvalue+=value;
   Counter++;

   if(Counter == 50)
   {
      Counter=0;
      pwmvalue=sumvalue/50;
      sumvalue=0;
      set_pwm1_duty(pwmvalue);    //PWM output 1
      set_pwm2_duty(pwmvalue);    //PWM output 2 
   }
   restart_wdt();
   //fprintf(CONTROL,"%02d:%02d:%02d - %Ld PWM %Lu\r",hour, min, sec, counter, pwmvalue);
}

/////////////////////////////////////////////////////////////////////////////
void SetOutputForBlinker(void)
{
   int16 i;
   int1 isSignNull=TRUE;
   
   //check sign 1
   for(i=C_START_S1; i<C_TOTAL_LED*2+C_START_S1;i+=2)
   { 
      if(read_ext_eeprom(i)!='0')
      {
         isSignNull = FALSE;
      }
   }
   
   //check sign 2
   for(i=C_START_S2; i<C_TOTAL_LED*2+C_START_S2;i+=2)
   {
      if(read_ext_eeprom(i)!='0')
      {
         isSignNull = FALSE;
      }
   }
                 
   //switch output for blinker on or off
   if(isSignNull==TRUE)
      output_low(SIGN_ON);
   else
      output_high(SIGN_ON);
}
/////////////////////////////////////////////////////////////////////////////
//
// Interrupts
//
/////////////////////////////////////////////////////////////////////////////
#INT_RDA
void rs232_handler(void)
{
   chr=fgetc(DATA);
   //InputData[InputIndex]=chr;
   
   //if(InputIndex < C_INP_DATA_LEN)
   //  InputIndex++;
   
   NewData=TRUE;
}

/////////////////////////////////////////////////////////////////////////////
//
// Main
//
/////////////////////////////////////////////////////////////////////////////
void main()
{
   delay_ms(1000);
   int16 i;

   //disable led's
   set_pwm1_duty(0xffff);
   
   //InitialData
   for(i=0;i<C_INP_DATA_LEN;i++) { InputData[i]='0'; }
   restart_wdt();
   //inidicates witch sign is acutaly shown
   char SignShown=0; 
   
   //Init external eeprom
   init_ext_eeprom();
   
   //interupt setup
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_RDA);
   
   //PWM setup
   setup_timer_2(T2_DIV_BY_16, 127, 1);
   setup_ccp1(CCP_PWM);
   setup_ccp2(CCP_PWM);
   
   //Analog setup
   setup_adc_ports(AN0);
   setup_adc(adc_clock_internal);
   set_adc_channel(0);

   //Init RTC
   rtc_init();
             
   AnalyseData();
   fprintf(CONTROL,"interval: %02d#", interval);
   fprintf(CONTROL,"time: %02d:%02d#", hour, min);
   fprintf(CONTROL,"start time: %02d:%02d#", starthour, startmin);
   fprintf(CONTROL,"stop time: %02d:%02d#", stophour, stopmin);
   restart_wdt();
   isDataOk=TRUE;
   
   //Set pwm start value to display data direct
   SetPWMValue(TRUE);
   
   //Set flasher on or off
   SetOutputForBlinker();
   InputIndex=0;
   
   while(TRUE)
   {
      restart_wdt();
      if(NewData)
      {
         isDataOk=FALSE;
         if(chr!='#')
         {
            InputData[InputIndex]=chr;
   
            if(InputIndex < C_INP_DATA_LEN)
               InputIndex++;
               
            NewData=FALSE;
         }
         else
         {
            NewData=False;
               
            //Get message "XXGS" (get state)
            if((InputData[2]=='G' && InputData[3]=='S') || (InputData[0]=='G' && InputData[1]=='S'))
            {
               if(isSignOn==TRUE)
                  fprintf(CONTROL, "GS:1#");
               else
                  fprintf(CONTROL, "GS:0#");
               
               restart_wdt();
               InputIndex=0;
               NewData=FALSE;
               Continue;
            }
     
            //Set message "XXSS" (set state)
            if((InputData[2]=='S' && InputData[3]=='S') || (InputData[0]=='S' && InputData[1]=='S'))
            {
               if(InputData[3]=='0')
               {
                  isSignOn=FALSE;
                  output_low(SIGN_ON);
                  set_pwm1_duty(0xffff);
                  set_pwm2_duty(0xffff);
               }
               else
               {
                  isSignOn=TRUE;
                  output_high(SIGN_ON);
                  set_pwm1_duty(pwmvalue);
                  set_pwm2_duty(pwmvalue);
               }
               restart_wdt();
               InputIndex=0;
               NewData=FALSE;
               Continue;
            }
     
            //Data message XXTT...
            if((InputData[2]=='T' && InputData[3]=='T') || (InputData[0]=='T' && InputData[1]=='T'))
            {   
               fprintf(CONTROL, "DataLen: %Ld#", InputIndex);
               if((InputIndex==C_INP_DATA_LEN-2) || (InputIndex==C_INP_DATA_LEN-4))
               {
                  fprintf(CONTROL, "Data OK#");
                 
                  InputIndex=0;
                  SignShown=0;
                                 
                  //Write to external eeprom
                  fprintf(CONTROL,"write data to eeprom...#");
                  WriteToEEPROM();
                 
                  //analyse data
                  AnalyseData();
                 
                  //if all bytes '0' disable flasher
                  SetOutputForBlinker();

                  //set rtc
                  rtc_set_datetime(day,mth,year,dow,hour,min);
                  restart_wdt();
                  NewData=FALSE;
                  isDataOk=TRUE;
                  Continue;
               }
               else
               {
                  fprintf(CONTROL, "Data NOK#");
                  restart_wdt();
                  InputIndex=0;
                  NewData=FALSE;
               }
               
               //get wrong data with # -> reset pic
               if(NewData)
               {
                    //reset();
                    fprintf(CONTROL, "Data NOK#");
                    InputIndex=0;
                    NewData=FALSE;
               }
            }
         }
         Continue;
      }
     
     
      //if initerval set toggle between sign1 and sign2
      if(isDataOk)
      {
         //rtc_get_time(hour,min,sec);
         if(interval>0)
         {
            SetPWMValue(FALSE);
           
            SendData(C_START_S1);
            delay_ms(800*interval);
           
            SendData(C_START_S2);
            delay_ms(800*interval);
         }
         else
         {
            SetPWMValue(FALSE);
            delay_ms(1000);
            //if start time and end time set, display sign1 between start time and end time, otherwise sign2
            if(starthour>0 && startmin>0 && stophour>0 && stopmin>0)
            {
               if(hour>=starthour && min>=startmin && hour<=stophour && min<stopmin)
               {
                  if(SignShown!=2)
                  {
                     SendData(C_START_S2);
                     SignShown=2;
                  }
               }
               else
               {
                  if(SignShown!=1)
                  {
                     SendData(C_START_S1);
                     SignShown=1;
                  }
               }
            }
            else
            {
               //send new data
               if(SignShown!=1)
               {
                  SendData(C_START_S1);
                  SignShown=1;
               }
            }
         }
         restart_wdt();
      }
   }
}


Everything is working all right if I leave out this code:

Code:

if(isDataOk)
      {
         //rtc_get_time(hour,min,sec);
         if(interval>0)
         {
            SetPWMValue(FALSE);
           
            SendData(C_START_S1);
            delay_ms(800*interval);
           
            SendData(C_START_S2);
            delay_ms(800*interval);
         }
         else
         {
            SetPWMValue(FALSE);
            delay_ms(1000);
            //if start time and end time set, display sign1 between start time and end time, otherwise sign2
            if(starthour>0 && startmin>0 && stophour>0 && stopmin>0)
            {
               if(hour>=starthour && min>=startmin && hour<=stophour && min<stopmin)
               {
                  if(SignShown!=2)
                  {
                     SendData(C_START_S2);
                     SignShown=2;
                  }
               }
               else
               {
                  if(SignShown!=1)
                  {
                     SendData(C_START_S1);
                     SignShown=1;
                  }
               }
            }
            else
            {
               //send new data
               if(SignShown!=1)
               {
                  SendData(C_START_S1);
                  SignShown=1;
               }
            }
         }
         restart_wdt();
      }


If the code above is included I get no answer from the Pic anymore.

Can anybody explain me what is going wrong?

Thanks in advance and best regards.
guy



Joined: 21 Oct 2005
Posts: 297

View user's profile Send private message Visit poster's website

PostPosted: Sat Jul 18, 2015 9:21 am     Reply with quote

I never had good experience with the statement Continue;
Maybe replace it with a Goto and a label?
temtronic



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

View user's profile Send private message

PostPosted: Sat Jul 18, 2015 10:43 am     Reply with quote

I'd get rid of all that code as you say you want to 'get data from DATA( a PC ?), check it, send to CONTROL ( another PC ??).

Cut code for a SIMPLE main(), using two ISRs and buffers. Some examples are in this forum,the CCS help and examples areas as well.
Hopefully that PIC has 2 hardware UARTs, I didn't check.


Also get rid of the 'restart_wdt'. In fact you should never use WDT until the entire program is working 100%. The WDT is generally used as a 'reboot' mechanism for a program that's gone 'funny'.


Jay
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Sat Jul 18, 2015 12:03 pm     Reply with quote

and then there are things like this
Code:

set_pwm1_duty(0xffff);

The greatest value the PWM can accept is 10 bits -
what is setting a value of 65535 supposed to do that setting 1023 will not?

and a hint
while debugging ,
get rid of all the watchdog code.

lastly YES the way you read, handle, and act on received EUSART data IS sketchy...so much so that i'm not really sure where to start.
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