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

Delay in sending the UART data frame 18F25K50

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



Joined: 14 Aug 2017
Posts: 1
Location: Mexico

View user's profile Send private message

Delay in sending the UART data frame 18F25K50
PostPosted: Mon Aug 14, 2017 10:35 am     Reply with quote

Hi guys,

I am making a counter with a microcontroller 18F25K50 which is activated to send a pulse to the input C0. This program also sends via RS232 to a computer in which it communicates to a LABVIEW program. This program sends a type "G" string type every 250 ms. The microncontroller once it receives with the command GETC () that character, sends a frame containing date and time obtained from ds1307 and the counter. The counter is increased every second.

The problem is that the counter is delayed each time it sends an incomplete frame and that causes the counter to delay seconds. I have doubt if the problem is in my Labview program or in my microcontroller code.

Delay in sending the UART data frame 18F25K50:
Code:

#include <18F25K50.h>
#fuses NOIESO,NOFCMEN,NOBROWNOUT,NOPUT,NOPBADEN,NOMCLR
#use delay (INTERNAL=10,000,000)
#define RTC_SDA PIN_B0
#define RTC_SCL PIN_B1
#include <DS1307.c>
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PC, timeout=250)
#include "stdlib.h"
#include <input.c>
#include "limits.h"
#rom int 0xf00000={1,2,3,4}

void main()
{
  int css=0, cmm=0, chh=0, cdd=0, cmeses=0;
 int x;
 BYTE sec, min, hrs, day, month, yr, dow;
 ds1307_init();   
// ds1307_set_date_time(14,8,17,1,8,53,30);  //(day,mth,year,dow,hour,min,sec)     // Configuracion de Hora
 
  long long v = read_eeprom( 7 );      //lectura y almacenamiento en variable de la localidad 7 de memoria eeprom(segundos)
  long long v1= read_eeprom( 6 );      //lectura y almacenamiento en variable de la localidad 6 de memoria eeprom(minutos)
  long long v2= read_eeprom( 5 );      //lectura y almacenamiento en variable de la localidad 5 de memoria eeprom(horas)
  long long v3= read_eeprom( 4 );      //lectura y almacenamiento en variable de la localidad 4 de memoria eeprom(dias)
  long long v4= read_eeprom( 3 );      //lectura y almacenamiento en variable de la localidad 6 de memoria eeprom(meses)
  long long v12= v1*60;                //Conversión de minutos a segundos
  long long v13= v2*3600;              //Conversión de horas a segundos
  long long v14= v3*86400;             //Conversión de dias a segundos
  long long v15= v4*2592000;           //Conversión de meses a segundos
  long long vt=v+v12+v13+v14+v15;
  printf( "%lu  %lu  %lu  %lu  %lu  %lu     ",v, v1, v2, v3, v4, vt);
  delay_ms(1000);
  long long  contador=vt;
 
while(TRUE)
{
  ds1307_get_date(day,month,yr,dow);
  ds1307_get_time(hrs,min,sec);
  output_low(PIN_A6);            //RECEPCIÓN
  output_low(PIN_A7);
  output_low(PIN_A0);

   for (x = 0; x < 3; x ++)
   {
   if(getc()=='G')
           {
            output_high(PIN_A0);
            output_HIGH(PIN_A6);            //Envio de Datos
            output_HIGH(PIN_A7);
            delay_ms(25);
            printf("I%Lu %02u%02u%u%02u%02u%02uF %u ",contador,day,month,yr,hrs,min,sec, x); //Trama Almancenando datos
            delay_ms(225);
           } 
   }
   if(INPUT(PIN_C0)==1)       //Optoacoplador
         {         
            contador++; 
            css++;
            if((css+v)<=59)      //Segundos
            {
             write_eeprom(7,css+v);     
            } 
            else
            {
            css=0;
            v=0;
            cmm++;
            }
            if((cmm+v1)<=59)      //Minutos
           {
             write_eeprom(6,cmm+v1);
           }
            else
           {
            cmm=0;
            v1=0;
            chh++;
           }
            if((chh+v2)<=24)       //Horas
           {
             write_eeprom(5,chh+v2);
           }
            else
           {
            (chh)=0;
            v2=0;
            cdd++;
           
           }
            if((cdd+v3)<=30)        //Dias
           {
             write_eeprom(4,cdd+v3);
           }
            else                    //Meses
           {
            cdd=0;
            v3=0;
            cmeses++;
            write_eeprom(3,cmeses+v4);
           }   
           }   
         delay_ms(250);
}
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Mon Aug 14, 2017 11:39 am     Reply with quote

Why all the delays?.

The G does not come except every 250mSec, so you don't want any more than the minimum delays in it's routine. Once the string is sent get back to your main scanning loop ASAP.

You have so many things delaying it getting back to the main loop, it is no wonder things get missed:

First the response to a 'G'. 250mSec in delays, plus all the time to print. Perhaps 40mSec extra.
Then write EEPROM takes something like 4mSec for each write.
Worse you are writing at something like 1 second intervals. This will kill the EEPROM very quickly. EEPROM is _not_ designed for things that are changing regularly. For that use a CMOS RAM. EEPROM is designed for things that change occasionally. If you write every second while the signal is high, you can kill the EEPROM in just over 24 hours. Instead of your current approach with a delay, have a flag, and only write when the input goes high. Then set the flag, and don't write again, till the input goes off.
Add ERRORS to your #use rs232. This should _always_ be used with the hardware UART, unless you are adding your own error handling.
temtronic



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

View user's profile Send private message

PostPosted: Mon Aug 14, 2017 11:57 am     Reply with quote

All that Mr T says and....

Instead of using the EEPROM use the CMOS RAM that's in the DS1307 !

It's 'free', came with the RTC chip..
It's battery backed, so data will be there if/when power fails..
It's easy to use, the RTC driver has the code for you already..
It's FAST, much faster than EEPROM..
Since you only use 5 bytes , LOTS leftover for other data..

Also, since you're using the DS1307, take advantage of it's interrupt capability! Use the SQW output. Once set for say 1Hz, the DS1307 will interrupt the PIC once every second. I typically use that to update a local LCD module and scan temperature sensors in my remote dataloggers.

Jay
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