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

serial transmit data truncation 16F18855
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
temtronic



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

View user's profile Send private message

PostPosted: Sat Feb 24, 2024 9:30 am     Reply with quote

Since you are using Delphi, have it display the incoming data from the PIC.
Like Mr. T, I suspect your unnamed 'monitoring software' is buggy.....
dDelage



Joined: 10 Sep 2022
Posts: 20

View user's profile Send private message

PostPosted: Sat Feb 24, 2024 11:16 pm     Reply with quote

Ttelmah wrote:
There is no transmit buffer,
I think you have a receive issue in your monitoring software.


temtronic wrote:
Since you are using Delphi, have it display the incoming data from the PIC.
Like Mr. T, I suspect your unnamed 'monitoring software' is buggy.....


I discovered that the Delphi app logs serial data to a file.
The serial data in the file is also truncated.

So it's not the Serial Port Monitor software, which is actually the name of the product.

On our board, the serial lines from the PIC connect to a TI MAX232, but that just takes care of the voltage conversion and itself doesn't have a buffer.
temtronic



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

View user's profile Send private message

PostPosted: Sun Feb 25, 2024 6:01 am     Reply with quote

Well I'm confused, I was under the impression that you wrote the PC side,using Delphi, but you mention an 'app logging data to a file' ?
So ,to clarify,are you using software someone else wrote ?
dDelage



Joined: 10 Sep 2022
Posts: 20

View user's profile Send private message

PostPosted: Sun Feb 25, 2024 2:25 pm     Reply with quote

temtronic wrote:
Well I'm confused, I was under the impression that you wrote the PC side,using Delphi, but you mention an 'app logging data to a file' ?
So ,to clarify,are you using software someone else wrote ?


Ok, here are the pieces:
1. PIC firmware. I didn't write most of it, but it's my baby now.
2. Delphi application. I didn't write most of it, but it's also my baby now.
3. Serial Port Monitor. Third-party software that does what it says. It's kinda magic in a way, because the Delphi app can have the COM port open to the PIC, and this software shows what is being sent and received.

The piece that logs serial data to a file is my Delphi application.
temtronic



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

View user's profile Send private message

PostPosted: Sun Feb 25, 2024 3:38 pm     Reply with quote

OK, to test the PIC... use 'RealTerm'. It will allow you to send/receive/ log data to/from the PIC..no need for the Delphi 'app'.

I used it a lot for several greenhouse projects,made it easy to log time/temperature data(I sent in CSV format) every second for testing, every minute in real use.

as for the current Delphi app, do you have the original source code ?

I used Delphi for a custom keyboard tester. Keyboard had 163 keys, sent ASCII via RS232( yeah REAL RS232...) so press a key on kbd, display on PC screen, send 'commands' to kbd to turn on/off the LEDs. Nice thing about Delphi was it would work on any PC as a stand alone program.
dDelage



Joined: 10 Sep 2022
Posts: 20

View user's profile Send private message

PostPosted: Sun Feb 25, 2024 10:05 pm     Reply with quote

I downloaded & installed RealTerm, and the truncation is gone. whew!

But, as Clippy once told me, "Problems that go away by themselves can come back by themselves." I wanted to find the reason that the string was truncated at 100 characters. I found a spot in the Delphi app that copies the first 100 characters of the serial data variable and puts the result back into that variable. Problem solved from the Delphi side, but I really wonder how that Serial Port Monitor software showed the same 100 chars. I'm guessing it somehow got a pointer to that memory location, and when the string changed in the Delphi app, it also changed in the Serial Port Monitor app. I didn't think that kind of thing was possible since Windows 95, but who knows?

I also still wonder why the first printf() from my test code gets sent as one serial message, but all subsequent printf()s get mashed into a second serial message. Even if I put a delay statement after the second printf(), it and all the rest go as a single message.

However, I think I need to leave that in the past. This is all for debugging a change to my serial ISR, and none of these printf()s will be used in the real app & firmware.

This could be implied from the text I just wrote, but for clarity I'll directly answer your question. Yes, I do have the Delphi app source code.

Question about RealTerm: at some point I will need to inspect serial data between the Delphi app and the PIC. Does RealTerm let me do that? and if so, how?

Thanks!
dDelage



Joined: 10 Sep 2022
Posts: 20

View user's profile Send private message

PostPosted: Sun Feb 25, 2024 10:28 pm     Reply with quote

Ttelmah wrote:
OK.
...
Test code;
Code:

//#include  "16F18855.H"     //Trying two different chips
#include "16F18445.h"
#device PASS_STRINGS=IN_RAM
#FUSES NOWDT //make sure the watchdog is off
#FUSES NOPPS1WAY

#id CHECKSUM   //stores the checksum, doesn't affect program
#use delay (INTERNAL=4MHZ)   //Says INTERNAL OSCILLATOR is 4MHz rev5
#PIN_SELECT U1RX=PIN_C7    //PPS chip, this is required
#PIN_SELECT U1TX=PIN_C6
#USE RS232 (UART1, BAUD=9600, parity=N, bits=8, ERRORS )

...


I don't want to ask you to explain everything you added above #id CHECKSUM, but is there documentation anywhere that explains what these directives do? (I can infer a little bit, but I like details.)

And likewise for the timer setup constants. Most of them I get, but some of them don't seem to be documented anywhere that I can find. One example is T4_CLK_LFINTRC. It looks to me that this is the LFINTOSC, but what does the RC at the end stand for? (also, in separate places in the datasheet, that clock is specified as 32kHz, 31kHz and 31.0kHz. according to the datasheet, the actual frequency depends on temperature and voltage.)

Plus, what happens if you don't specify a divider? I would have thought that T#_DIV_BY_1 would have a value of 0, to default to dividing by 1, but in the header file, many of these T#_DIV_BY_1 values are nonzero.

Thanks!
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Mon Feb 26, 2024 4:07 am     Reply with quote

There is an explanation of the fuses with the compiler. Look for fuses.txt

You were handling the string incorrectly in two ways. The first is that
=, does not 'copy' a string. It will load the pointer on the left with the
contents of the pointer on the right. To 'copy' you have to use strcpy
or memcpy. The second though is fundamental to the PIC. Because the
PIC uses the Harvard processor architecture, it has two separate memory
'spaces'. The ROM and the RAM. On standard chips these are all in one
large area of memory, but on the PIC they are separate. Problem then
is that if you have a constant string "Hello", this is in the ROM, not the
RAM. The PASS_STRINGS option makes the compiler automatically
'virtualise' references to constant strings, as if they were in the RAM.
Allows you to have pointers to these. Very Happy
Do a search here you will find a lot of threads about the implications
of the architecture.

The NOPPS1WAY, allows the PPS settings to be changed more than once.
I noted the assembler on your chip did seem to be changing it twice,
so this may be needed.

The internal oscillator _is_ and RC oscillator.

The timer options set quite a few other bits in other registers. These
are coded as other bits in the defined values.
temtronic



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

View user's profile Send private message

PostPosted: Mon Feb 26, 2024 6:31 am     Reply with quote

re: Realterm
yes, you can have Realterm do a 'split screen' where everything going TO the PIC is displayed as well as everything coming FROM the PIC.
you can also send a precoded line of text or a file TO the PIC. It should show what the Delphi ap sends. I assume it captures the UART data ? Others may know how it works, I was just happy it did exactly what I needed it to !
Realterm has a zillion features,so there is a learning curve BUT is was always 'stable'
Hint: If you want to capture the incoming data to a file, put that file ON THE DESKTOP ! makes it a lot easier to find......
dDelage



Joined: 10 Sep 2022
Posts: 20

View user's profile Send private message

PostPosted: Mon Feb 26, 2024 9:27 pm     Reply with quote

Ttelmah wrote:
...

You were handling the string incorrectly in two ways. The first is that
=, does not 'copy' a string. It will load the pointer on the left with the
contents of the pointer on the right. To 'copy' you have to use strcpy
or memcpy. The second though is fundamental to the PIC. Because the
PIC uses the Harvard processor architecture, it has two separate memory
'spaces'. The ROM and the RAM. On standard chips these are all in one
large area of memory, but on the PIC they are separate. Problem then
is that if you have a constant string "Hello", this is in the ROM, not the
RAM. The PASS_STRINGS option makes the compiler automatically
'virtualise' references to constant strings, as if they were in the RAM.
Allows you to have pointers to these. Very Happy
Do a search here you will find a lot of threads about the implications
of the architecture.

...


ROM vs. RAM. I don't need constant strings. I've just been developing on bigger systems and am not used to the nuances. It's good to blow the dust off all that stuff I learned in college.

I was just initializing the string that way because that's the way I've done it for years, but not in C. So if I initialize the string the right way with strcpy() -- just for safety -- and then all data that goes in that string is from runtime, do I need the
Code:
#device PASS_STRINGS=IN_RAM
line at all?

Ttelmah wrote:
...
The internal oscillator _is_ and RC oscillator.

The timer options set quite a few other bits in other registers. These
are coded as other bits in the defined values.


Ok. I'm more of a software guy than hardware guy. What does RC stand for in this case? Realtime Clock? or Resistor Capacitor? or something else?

As for the timer options, specifically for the 16F18855, because the values may be different for other micros, what is the functional difference between these two lines of code:
Code:

setup_timer_4(T4_CLK_LFINTRC, 255, 1);      // 0x0400

setup_timer_4(T4_CLK_LFINTRC | T4_DIV_BY_1, 255, 1);    // 0x0480


Thanks
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Tue Feb 27, 2024 2:21 am     Reply with quote

Lest start with the = for a string. Point is that on a normal 'PC' system, what
this results in is a lot of wasted space. Your declaration of the data array
is wasted!....

Understand, you declare this: "some text". On the PIC, this results in
the characters for 'some text" being stored in ROM. On the PC this
results in a RAM array being created, holding this text.
Now you then declare:
char data[32];

and later say:

data="some text".

What happens at this point is that the 32 character array in RAM, is
effectively 'lost'. Still there, but 'data' no longer points to it. Instead
it now points to the "some text" array held elsewhere in RAM. You have
just thrown away 32 byte of memory!...

If instead you declared

char * data;

'data' would now be a pointer, and when you did

data="some text", this pointer would now point at the 'some text' array.

So what you are doing, 'works' on a PC, but is incorrect programming. In
C (it is supported in C++).

No, you don't need the PASS_STRINGS line, but it makes string in the
PIC behave in a perceptually similar way to the way they would work
on a Von Neumann machine.

Yes, RC stands for resistor capacitor. One of the simplest oscillators to
make, and about the only one that is easy to build internally in a chip.
On the PIC all the internal oscillators are RC oscillators, but they are tuned
at the end of manufacture to make their accuracies 'reasonable'.

Key on all the 'what do things mean' is the data sheet. If you look the
top bit of the four bits selecting the prescaler is actually the bit to turn
the timer 'on'. So the '0x80' is saying 000 to the prescaler bits (=/1), and
turn the timer on. Selecting the clock on it's own, does not turn on the
timer. So it won't work. It may however be that the compiler will
automatically turn on the enable bit (I'd gave to look at the assembler
to see).
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
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