|
|
View previous topic :: View next topic |
Author |
Message |
Prefekt
Joined: 21 Oct 2010 Posts: 85
|
uart Problem with pic 18F2525 |
Posted: Tue Jul 14, 2015 11:25 pm |
|
|
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
|
|
Posted: Sat Jul 18, 2015 9:21 am |
|
|
I never had good experience with the statement Continue;
Maybe replace it with a Goto and a label? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Sat Jul 18, 2015 10:43 am |
|
|
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
|
|
Posted: Sat Jul 18, 2015 12:03 pm |
|
|
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. |
|
|
|
|
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
|