![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
fprintf() -> fputc() |
Posted: Wed Apr 13, 2011 5:14 pm |
|
|
Hi There,
My problem is that it seems like timer interrupts don't kick in while an fprintf() function is sending out the characters and get postponed instead until fprintf is done. I set my timer ISRs to HIGH but still, no luck.
I first thought I could create my own myprintf() that would take the string in the same format as it goes to fprintf() and instead of sending them out all at once, I just go Byte by Byte with fputc(). Then I read somewhere that fputc() has this functionality built in already as I got stuck with myprintf() cause you can pass no static strings to a function...
Ok, I thought, let's go with fputc. I tried to replce my fprintf with an sprintf where i had declared a static char[100] pointer. Ok fine but how do you pass it to fputc()? It's gotta be a constant....great! Doing something like fputc((const char)MyStr, PC); didn't work either... any clues or suggestions?
Thanks,
roN |
|
![](templates/subSilver/images/spacer.gif) |
collink
Joined: 08 Jan 2010 Posts: 137 Location: Michigan
|
|
Posted: Wed Apr 13, 2011 6:09 pm |
|
|
I would have expected that interrupts would fire in your case. A large portion of the time spent in sending data over RS232 (which is what I assume you are doing) is spent waiting for the UART to signal that it has sent the previous byte. I don't see why interrupts would not get through during this time, unless there is some sort of compiler bug that has interrupts disabled for the entire time...
The most pertinent questions are:
1. Why do you think that the interrupt is not firing?
2. Does it fire (or seem to) when you are not using fprintf?
3. What chip?
4. What compiler version?
We can proceed to getting a solution working once it is settled that there isn't some other problem with your code. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Thu Apr 14, 2011 2:11 am |
|
|
Is the print using a software UART, or a hardware UART?.
The obvious things that would cause the interrupts not to fire, are:
1) Using a fputc/fprintf, inside an interrupt.
2) Having 'DISABLE_INTS' in the #use RS232 declaration.
Assuming you are using a hardware UART, let interrupts work for you.
Use the EX_STISR.C example. printf, to bputc, into a circular buffer, rather than using fprintf, and let the serial interrupt do the actual transmission.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
|
Posted: Thu Apr 14, 2011 10:15 am |
|
|
collink wrote: | I would have expected that interrupts would fire in your case. A large portion of the time spent in sending data over RS232 (which is what I assume you are doing) is spent waiting for the UART to signal that it has sent the previous byte. I don't see why interrupts would not get through during this time, unless there is some sort of compiler bug that has interrupts disabled for the entire time...
The most pertinent questions are:
1. Why do you think that the interrupt is not firing?
2. Does it fire (or seem to) when you are not using fprintf?
3. What chip?
4. What compiler version?
We can proceed to getting a solution working once it is settled that there isn't some other problem with your code. |
Okay, I have a bunch of LEDs hooked up to outputs that I turn on and off with timers and it works smootly fine, if I don't use send anything over my serial port to the PC. I'm using the USART1 to do so. When there's stuff sent out, the LEDs start to flicker "randomly", hooking up my scope, i see that the pins(i'm using timers to set and other timers to reset the pins) don't get set/reset on time anymore but all distorted timings is what i get....the chip i'm using is a 18f87k22 and my compiler is 4.119
Ttelmah wrote: | Is the print using a software UART, or a hardware UART?.
The obvious things that would cause the interrupts not to fire, are:
1) Using a fputc/fprintf, inside an interrupt.
2) Having 'DISABLE_INTS' in the #use RS232 declaration.
Assuming you are using a hardware UART, let interrupts work for you.
Use the EX_STISR.C example. printf, to bputc, into a circular buffer, rather than using fprintf, and let the serial interrupt do the actual transmission.
Best Wishes |
1) no, i'm not inside the isr while i print.
2) nope it looks like this:
Code: | #use rs232(baud=BAUDRATE,parity=N,xmit=PC_TX,rcv=PC_RX,bits=8,stream=PC, ERRORS) |
I looked at the EX_STISR.C example but don't quite understand it - or maybe I don't understand CCS ![Rolling Eyes](images/smiles/icon_rolleyes.gif) |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Thu Apr 14, 2011 2:46 pm |
|
|
You are sure there is not even one 'fputc', inside _any_ interrupt?....
It only takes one. If you have one, interrupts _will_ be disabled round all the others.
Other thing, if the PC stream, is using USART1, then change it's definition, to:
Code: |
#use rs232(baud=BAUDRATE,parity=N,UART1,bits=8,stream=PC, ERRORS)
|
This prevents any possibility of having PC_TX, or PC_RX wrongly defined, and the code using a software UART.
On the stisr. Key thing is to understand that in CCS, 'printf', can route it's output to _any_ desired routine. So if you write:
Code: |
printf(bputc,"Demo string %n",val);
|
Then the whole output 'Demo string' and the numeric value, gets sent to the 'bputc' routine.
You just need to load the code from the line '#define T_BUFFER_SIZE', to the line before the 'main', from stisr, into your code, change the putc inside the isr, to use your fputc to the hardware UART, and then if you want to perform 'putc', in your code, instead call 'bputc', and for a printf, redirect it as I show above.
What then happens is that when you print, the data is transferred to the buffer, instead of the code waiting to send, and the characters are then _automatically_ sent when the TBE interrupt says it can take a character.
Interrupts for the serial TX are enabled when you send the first character, and then disabled when the buffer goes empty (since otherwise the routine will keep triggering, trying to send characters that are not there).
Best Wishes |
|
![](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
|