![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
victooritho
Joined: 14 Aug 2017 Posts: 1 Location: Mexico
|
Delay in sending the UART data frame 18F25K50 |
Posted: Mon Aug 14, 2017 10:35 am |
|
|
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);
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Mon Aug 14, 2017 11:39 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9174 Location: Greensville,Ontario
|
|
Posted: Mon Aug 14, 2017 11:57 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|