View previous topic :: View next topic |
Author |
Message |
OldGuy
Joined: 03 Feb 2013 Posts: 27 Location: Seattle Area
|
18F25K80 Timer/RS-232 off by factors of four |
Posted: Sat Aug 08, 2020 5:47 pm |
|
|
Hello - I've looked around on the forum, and can't seem to find what I'm looking for. With any luck, perhaps one of you can help me.
I'm using an 18F25K80, with a 16MHz ceramic resonator connected to pins RA6 and RA7. Also doing RS232 using pins B6 and B7.
The problem is that the RS-232 output is four times the frequency, so that in order to get 9600 out, I need to set it to 2400 baud. Then it seems to work OK.
The other problem is that Delay_ms() calls go by in about 1/4 the time that they should.
This is how the program initialization is set up:
Code: |
#device PIC18F25K80 ADC=8
#include <18F25K80.h>
#include <stdlib.h>
#fuses NOWDT, HSH, NOPUT, NOPROTECT, NOWDT
#use delay (clock=16MHZ)
#use rs232 (stream=XBEE, baud=2400, xmit=PIN_B6, rcv=PIN_B7, PARITY=N, BITS=8, ERRORS)
|
Can anyone shed any light on changes I should make so that I get proper delays and bauds? I'd really appreciate it. I'm a little worried that if I don't get this fixed properly, I'll have trouble once I start working with the CAN bus IO.
- Brian |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Sat Aug 08, 2020 5:55 pm |
|
|
My 'gut' says it's a PLL problem. Could be a 'bug' that's enabling the PLL ( I think it's 4x).
Others will know for sure.
Dump out the listing to see the 'fuses' to see what IS being configured.
Jay |
|
|
OldGuy
Joined: 03 Feb 2013 Posts: 27 Location: Seattle Area
|
|
Posted: Sat Aug 08, 2020 7:22 pm |
|
|
Thanks Jay, that would make sense.
Now I just have to figure out how to see what it is set it, not sure where to look in the IDE. The data sheet says that PLL is register 28-2, address 300001H, bit 4, but the register addresses I see in the device table editor are in the Fxx and Exx address space.
Sorry to be ignorant in the area, but can you tell me how to see what the fuses are set to? If I can find it, I can tell if it's correct.
Thanks,
Brian |
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Sat Aug 08, 2020 9:36 pm |
|
|
If you look at the output files there should be a .LST file. Inside there will be a thing at the end I think, showing what the config registers are set as. Then you can compare them to the config registers of the datasheet. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Sun Aug 09, 2020 1:17 am |
|
|
Yes, the issue will be the PLL will be enabled.
The compiler by default leaves all fuses in their erased state, unless you
set them. The erased state for a fuse cell. is '1'. A '1' in the PLLEN cell
enables the PLL.
So as posted, the fuses will actually be:
Code: |
Configuration Fuses:
Word 1: D215 VREGSLEEP INTRC_HP SOSC_DIG NOXINST HSH PLLEN FCMEN IESO
Word 2: 7C7F NOPUT BROWNOUT BORV18 ZPBORM NOWDT WDT1048576
Word 3: 8900 CANB MSSPMSK7 MCLR
Word 4: 0091 STVREN BBSIZ2K NODEBUG
Word 5: C00F NOPROTECT NOCPB NOCPD
Word 6: E00F NOWRT NOWRTC NOWRTB NOWRTD
Word 7: 400F NOEBTR NOEBTRB
|
As a general 'other comment' though, change your layout slightly.
Comments inline:
Code: |
#include <18F25K80.h> //Loading this already sets the device
#device adc=8
#fuses NOWDT, HSH, NOPUT, NOPROTECT, NOWDT, NOPLLEN
#use delay (clock=16MHZ)
#use rs232 (stream=XBEE, baud=2400, xmit=PIN_B6, rcv=PIN_B7, PARITY=N, BITS=8, ERRORS)
//Generally, it is much safer to always have your #clock, and #use
//rs232 before you include anything else. Otherwise a few of the libraries
//may not operate correctly, since they depend on the settings used
//for these. Just a 'caveat'.....
#include <stdlib.h>
|
Worth getting into the 'habit' of doing the chip & I/O configuration
before loading other stuff.... |
|
|
OldGuy
Joined: 03 Feb 2013 Posts: 27 Location: Seattle Area
|
|
Posted: Sun Aug 09, 2020 9:26 am |
|
|
Thank you gentlemen for your thoughts.
It was indeed a PLL issue, and things are working now that I added a NOPLLEN to my fuses list:
#fuses NOWDT, HSH, NOPUT, NOPROTECT, NOWDT, NOPLLEN
I'm appreciative that you pointed me in the right direction, and now I also know more about ordering the program.
Brian |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Sun Aug 09, 2020 9:37 am |
|
|
Yes, as you saw I had added that!.
Have a great day. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Sun Aug 09, 2020 11:16 am |
|
|
It's nice when SOMETHING finally, actually works...... !
One 'trick' I do is have a 'fuses file' like '46k22fuses.h'. It's EVERY fuse for that PIC, one per line with comment. Yeesh most PICS today have more fuses than instructions !
Used as follows....
...
#include <18f46k22.h>
#include "46k22_fuses.h"
#use delay(clock=32000000,internal)
#use rs232(baud=57600, UART1,errors,stream=PCLINK)
...
It does 2 things for me..
1, saves me a LOT of typing, and retyping......
2, main() is 'cleaner' and I KNOW it shouldn't be a fuses issue
Jay |
|
|
OldGuy
Joined: 03 Feb 2013 Posts: 27 Location: Seattle Area
|
|
Posted: Mon Aug 10, 2020 10:06 am |
|
|
That's a good idea to have that list of fuses, after researching this issue I've just scratched the surface of them - so much more to learn.
At least now I've got the transmitter side of the RS232 working well, allowing me to debug the receiver side of the RS-232. First experience using the receive_buffer capability. Mostly works, just have to figure out why it starts to get a little error-prone after the sixteenth or eighteenth character sent. New things to explore and learn!
Thanks to the forum, I've been able to move past the clock issue to new things.
- Brian |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Mon Aug 10, 2020 10:33 am |
|
|
CCS supplies an example 's_isr.c' that is a basic buffered serial ISR. Some have 'tweaked' it for better performance.
Also now you can have a 'buffer' in the #use RS232( ...options...) though I've neve rused it..maybe my compier version is too old...like me....
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Mon Aug 10, 2020 10:59 am |
|
|
The 'receive buffer' ability in the function, has one major issue. It throws
characters if there is an overflow. The ex_sisr.c driver is 'better'. However
it is nicer 'rewritten' as:
Code: |
#int_rda
void serial_isr() {
int t;
buffer[next_in]=getc();
t=next_in++;
if (next_in>=BUFFER_SIZE)
next_in=0;
if(next_in==next_out)
next_in=t; // Buffer full !!
}
#define bkbhit (next_in!=next_out)
BYTE bgetc() {
BYTE c;
while(!bkbhit) ;
c=buffer[next_out++];
if (next_out>=BUFFER_SIZE)
next_out=0;
return(c);
}
|
The changes in this allow it to work efficiently with any buffer size
(that fits in an int8), without incurring the massive overhead from '%'
that happens with non binary buffer sizes. |
|
|
OldGuy
Joined: 03 Feb 2013 Posts: 27 Location: Seattle Area
|
|
Posted: Mon Aug 10, 2020 11:03 am |
|
|
Hi Jay -
I'm an old guy too (70's) and my compiler is a few years old, but it does support the buffer declaration in the use 232 directive. Little documentation about using it. Instead of kbhit, you use rcv_buffer_bytes(), the rest seems to be the same. I did learn that it doesn't work unless you enable interrupts global since it uses int RDA.
- Brian |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1345
|
|
Posted: Mon Aug 10, 2020 11:47 am |
|
|
OldGuy wrote: | Hi Jay -
I'm an old guy too (70's) and my compiler is a few years old, but it does support the buffer declaration in the use 232 directive. Little documentation about using it. Instead of kbhit, you use rcv_buffer_bytes(), the rest seems to be the same. I did learn that it doesn't work unless you enable interrupts global since it uses int RDA.
- Brian |
Another gotcha with the #use rs232() buffers is that if you accidentally let the fill up, they "lose" all of the data in them and reset (as opposed to the SISR example in the examples folder). So make sure you make the buffers large enough that you don't accidentally lose them while doing other operations.
NOTE: By "lose" I mean they reset their index cursors. The data is still technically there until more data comes in, but the CCS functions can no longer return it. |
|
|
OldGuy
Joined: 03 Feb 2013 Posts: 27 Location: Seattle Area
|
|
Posted: Mon Aug 10, 2020 11:48 am |
|
|
Hi Jay -
Sorry, but your most recent post came after I responded to the previous one.
If I use your example code, do I need to define the buffer, and this replaces the buffer used in the use RS232 directive? If I don't put the receive_buffer argument in the use RS232, do I need to have my own set-up for initiating int_RDA?
Appreciate your thoughts.
Brian |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Mon Aug 10, 2020 11:59 am |
|
|
Look at the ex_sisr.c example. It shows the example buffer being used,
and how it all works. |
|
|
|