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

printf/putc problem with 16f873

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







printf/putc problem with 16f873
PostPosted: Thu May 15, 2003 2:37 pm     Reply with quote

I solved the problems I was having using printf and the RS-485
chip. A while back we wanted to use the Receive Enable (RE) pin
on the MAX-487 and control it with C1 from the PIC. The idea
was to monitor the signal that appeared on the bus and compare
it to what was sent. If the two strings did not match then a
collision had occurred and the packet needed to be re-sent. This
was a thought for the future and was never implemented. If any-
one knows how to do this, please let me know. (We have several
PICs that need to talk with a host control computer and need the
RS-485 bus capabilities.)

The code that caused it to work is below. However, another problem has cropped up, and it may be related to the "fix" I used.

The code in the section THIS_WORKS does, but the code in the
#else section does not; nothing is printed on the terminal,
except as noted. I seem to remember seeing this way of printing
in another post, but perhaps the fact that it does not work for
me is related to what I am doing with the C1 output and the
delay needed for the MAX-487 chip.

Another oddity: Instead of printing 1.234 for the voltage, it
prints 1.233999.

I am using version 3.154 of the compiler and have not seen any
printf-related changes in newer versions.
______________________________________________________________

#include <16F873.H>

#fuses HS, NOWDT, NOPROTECT, BROWNOUT, NOLVP, PUT

#use delay(clock = 14745600)
#use rs232(baud = 115200, xmit = PIN_C6, rcv = PIN_C7, enable = PIN_C2, PARITY = N, BITS = 8, ERRORS)

#define C1_DELAY_MS 1 // mS after toggling pin C1 for transmit.

#define MAX_BUFFER_SIZE 32

#define THIS_WORKS

#ifdef THIS_WORKS
void send_buffer(char *buffer)
{
int idx;

output_high(PIN_C1);
delay_ms(C1_DELAY_MS);
for (idx = 0; buffer[idx]; idx++) {
putc(buffer[idx]);
}
output_low(PIN_C1);
}
#else // This does NOT work!!!
void send_buffer(char *buffer)
{
output_high(PIN_C1);
delay_ms(C1_DELAY_MS);
printf(buffer);
//printf("\%s", buffer); // Does NOT work either!
//printf("String: \%s", buffer); // Just prints "String: "!
output_low(PIN_C1);
}
#endif

void main()
{
char buffer[MAX_BUFFER_SIZE];

enable_interrupts(GLOBAL);
set_tris_c(0x86);

sprintf(buffer, "\%s\r", "Program started...");
send_buffer(buffer);

sprintf(buffer, "\%s: \%f\r", "Voltage", 1.234);
send_buffer(buffer);

sprintf(buffer, "\%s\r", "Program ended...");
send_buffer(buffer);

while(TRUE); // Keep PIC from entering SLEEP mode.
}
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514496
Pete Smith
Guest







Re: printf/putc problem with 16f873
PostPosted: Fri May 16, 2003 8:08 am     Reply with quote

:=I solved the problems I was having using printf and the RS-485
:=chip. A while back we wanted to use the Receive Enable (RE) pin
:=on the MAX-487 and control it with C1 from the PIC. The idea
:=was to monitor the signal that appeared on the bus and compare
:=it to what was sent. If the two strings did not match then a
:=collision had occurred and the packet needed to be re-sent. This
:=was a thought for the future and was never implemented. If any-
:=one knows how to do this, please let me know. (We have several
:=PICs that need to talk with a host control computer and need the
:=RS-485 bus capabilities.)
:=
:=The code that caused it to work is below. However, another problem has cropped up, and it may be related to the "fix" I used.
:=
:=The code in the section THIS_WORKS does, but the code in the
:=#else section does not; nothing is printed on the terminal,
:=except as noted. I seem to remember seeing this way of printing
:=in another post, but perhaps the fact that it does not work for
:=me is related to what I am doing with the C1 output and the
:=delay needed for the MAX-487 chip.
:=
:=Another oddity: Instead of printing 1.234 for the voltage, it
:=prints 1.233999.

This is a common problem, to do with the way that the numbers are stored, and will happen with most/all systems. 1.234 can't be stored exactly as 1.234, so corners are cut (so to speak)

As to your other problem : I've never got \%s to work under CCS C, so I normally (if I'm using strings like that) just use puts() (this may not work for you, because it puts a LF or CR at the end).

HTH

Pete.
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514507
R.J.Hamlett
Guest







Re: printf/putc problem with 16f873
PostPosted: Sun May 18, 2003 6:56 am     Reply with quote

:=I solved the problems I was having using printf and the RS-485
:=chip. A while back we wanted to use the Receive Enable (RE) pin
:=on the MAX-487 and control it with C1 from the PIC. The idea
:=was to monitor the signal that appeared on the bus and compare
:=it to what was sent. If the two strings did not match then a
:=collision had occurred and the packet needed to be re-sent. This
:=was a thought for the future and was never implemented. If any-
:=one knows how to do this, please let me know. (We have several
:=PICs that need to talk with a host control computer and need the
:=RS-485 bus capabilities.)
:=
:=The code that caused it to work is below. However, another problem has cropped up, and it may be related to the "fix" I used.
:=
:=The code in the section THIS_WORKS does, but the code in the
:=#else section does not; nothing is printed on the terminal,
:=except as noted. I seem to remember seeing this way of printing
:=in another post, but perhaps the fact that it does not work for
:=me is related to what I am doing with the C1 output and the
:=delay needed for the MAX-487 chip.
:=
:=Another oddity: Instead of printing 1.234 for the voltage, it
:=prints 1.233999.
This will happen, even on a PC!...
The problem is that the normal 'floating point' format, is _not_ an accurate way to store numbers. The format used on the PIC, has 23bits of accuracy (just over 6 1/2 digits), and to this level of accuracy, 1.233999 = 1.234. This is the reason why people needing absolute guarantees that a particular number will not display this type of error, use other numberic formats (for instance in VB, there is a 'currency' type, which uses a scaled integer). Now you can limit the result to just three digits, by using a 'width' limiter on the \%f printout (perhaps something like \%5.3f). The individual bits in the mantissa of the number, correspond to '1', then '0.5', then '0.25', then '0.125' etc., Hence the nearest value that can be acheived, is 1+0.125+0.0625+0.03125 etc.. With some numbers, the result will be perfect (for instance, 1.125), but numbers that are not conventiently constructed from binary multipliers, will end up with errors...
If you want accuracy over a particular range, use a scaled integer instead (which is also generally faster), but otherwise you must bear in mind the limits of standard floating point encoding.

Best Wishes

:=I am using version 3.154 of the compiler and have not seen any
:=printf-related changes in newer versions.
:=______________________________________________________________
:=
:=#include <16F873.H>
:=
:=#fuses HS, NOWDT, NOPROTECT, BROWNOUT, NOLVP, PUT
:=
:=#use delay(clock = 14745600)
:=#use rs232(baud = 115200, xmit = PIN_C6, rcv = PIN_C7, enable = PIN_C2, PARITY = N, BITS = 8, ERRORS)
:=
:=#define C1_DELAY_MS 1 // mS after toggling pin C1 for transmit.
:=
:=#define MAX_BUFFER_SIZE 32
:=
:=#define THIS_WORKS
:=
:=#ifdef THIS_WORKS
:=void send_buffer(char *buffer)
:={
:= int idx;
:=
:= output_high(PIN_C1);
:= delay_ms(C1_DELAY_MS);
:= for (idx = 0; buffer[idx]; idx++) {
:= putc(buffer[idx]);
:= }
:= output_low(PIN_C1);
:=}
:=#else // This does NOT work!!!
:=void send_buffer(char *buffer)
:={
:= output_high(PIN_C1);
:= delay_ms(C1_DELAY_MS);
:= printf(buffer);
:= //printf("\%s", buffer); // Does NOT work either!
:= //printf("String: \%s", buffer); // Just prints "String: "!
:= output_low(PIN_C1);
:=}
:=#endif
:=
:=void main()
:={
:= char buffer[MAX_BUFFER_SIZE];
:=
:= enable_interrupts(GLOBAL);
:= set_tris_c(0x86);
:=
:= sprintf(buffer, "\%s\r", "Program started...");
:= send_buffer(buffer);
:=
:= sprintf(buffer, "\%s: \%f\r", "Voltage", 1.234);
:= send_buffer(buffer);
:=
:= sprintf(buffer, "\%s\r", "Program ended...");
:= send_buffer(buffer);
:=
:= while(TRUE); // Keep PIC from entering SLEEP mode.
:=}
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514529
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