|
|
View previous topic :: View next topic |
Author |
Message |
duncangray
Joined: 27 Apr 2007 Posts: 14 Location: UK
|
SOLVED: Using the 16F767 internal 8MHz oscillator |
Posted: Wed May 18, 2016 3:36 pm |
|
|
Dear Forum contributors,
I have been programming PICs using the CCS compiler for several years and have occasionally tried to use a PIC's internal oscillator - and always failed, trawled the examples and forum, given up and used an external crystal.
This time I am trying to implement the internal 8MHz oscillator in the 16F767 (28 pin SDIP) using the following code.. Compiler is PCH 5.042
Code: | #include "16f767.h"
#use delay(clock=8MHz)
#use rs232 (baud=19200, xmit=PIN_C6, rcv=PIN_C7, PARITY=N, BITS=8)
void main(){
do{
delay_ms(500); // self contained delay for main loop timing
output_high(PIN_C4);
delay_ms(500);
output_low(PIN_C4);
}while (TRUE); // END OF MAIN LOOP
}
|
The LED on C4 does not flash and the only pin that I have detected activity on is OSC 2 which has an 8kHz (125uS period) square wave. C4 is permanently low.
Please can someone point out what I have missed. Thanks DG
Last edited by duncangray on Thu May 19, 2016 10:39 am; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed May 18, 2016 4:45 pm |
|
|
Right, but you have no fuses. And your #use delay() doesn't tell the
compiler to setup the OSCCON register for 8 MHz internal osc operation.
Example:
Code: | #include <16F767.h>
#fuses INTRC_IO, NOWDT, BROWNOUT, BORV42, PUT
#use delay(internal=8M)
//==========================
void main(void)
{
while(TRUE) // Flash an LED every 1 second
{
output_toggle(PIN_C4);
delay_ms(500);
}
} |
|
|
|
duncangray
Joined: 27 Apr 2007 Posts: 14 Location: UK
|
|
Posted: Wed May 18, 2016 5:28 pm |
|
|
Thanks PCM programmer. That code has moved the game forward.
I have looked for further info on the many fuses and, apart from the 16F767 header file I cannot find anything in the CCS manual, CCS Help or the Microchip data sheet that contains PUT or BORV42 for example. Can you point me in the right direction?
The code now works on my hardware - but there is something odd happening each time I make a mod such as altering the delay.
If I compile code for the first time and download it to the target it doesn't run. If I recompile with ICD=TRUE and run it in debug mode it works.
If I then disable the debugger, remove ICD=TRUE recompile and download the code it works in standalone with or without the ICD connected.
Does that look like a hardware fault or is there something subtle in the code I'm not getting?
Thanks. DG |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9228 Location: Greensville,Ontario
|
|
Posted: Wed May 18, 2016 5:44 pm |
|
|
PUT means Power Up Timer. I always enable it as it forces th epIC to start up in a nice, controlled way. Yeah..'somewhere' in the 500 page datasheet it'll be talked about, me, I just always enable it !
BORV42 probably means Brown Out Reset 4 point2 volts. When the Vdd drops below 4point2, it'll trigger an interrupt flag and may restart the PIC. Again, one of those 'options' I've never used.
others can chime in for better explanations....
You should be aware that the internal oscillators of most PICs aren't super 'tight' or precise when compared to an external xtal and 2 caps. If your projects are indoors(room temperature) and don't need precise nanosecond timings or high baudrates, then the internal osc. is fine. Just something to remember when 'it' doesn't work in -15*C weather !
Also, if using MPLAB, be sure to compile using the 'release' mode NOT 'debug'. While I never use 'debug' mode( the real world is my test !),or ICDs...both odes will affect how the PIC operates. They change fuse settings that you won't be aware of.
Jay |
|
|
duncangray
Joined: 27 Apr 2007 Posts: 14 Location: UK
|
|
Posted: Wed May 18, 2016 5:55 pm |
|
|
Thanks Jay. I also found a list of fuses by device in the compiler under "View/Config Bits". To date I have used a small subset and, by good luck, they have worked. Running on the internal oscillator has highlighted my ignorance! I think it was PCM programmer's suggestion of INTRC_IO that made the device start to work. Now to find out why it needs to be run in debug - then not. DG |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19516
|
|
Posted: Thu May 19, 2016 2:16 am |
|
|
Just a 'further information' on this.
Key place to start for fuses, is the chip data sheet. With this you can see what fuses you need.
If you then look at the start of the chip include file, CCS list for you as comments, all the fuse names they use on your chip. As a further 'useful information', there is a file with the compiler, called 'fuses.txt'. This contains a list of all the Microchip fuse names, and all the CCS names.
Final place that is important, is the end of the .lst file when you have compiled some code.
Key thing here is that CCS (on current versions), leaves most fuses in their default 'erased' state, unless _you_ specify them. (exception below). Now if we look at the 767 data sheet, and look at the configuration words (where the fuse settings are stored), you see that the default for the first word, is:
Code protection off
CCP2 on RC1
Debug disabled
Brownout at 2v
Brownout on
MCLR as MCLR
Power up timer enabled
Watchdog enabled
External RC oscillator with clk0 on RA6
So with no fuses set, it isn't going to work without an external RC circuit on the OSC pin. Hence why the original code didn't work.
So looking at the data sheet again, we can see you need either INTRC with clk output, or INTRC with I/O. Also the watchdog needs to be off.
Now looking at the header file, we see:
Code: |
//////// Fuses: NOWDT,WDT,PUT,NOPUT,LP,XT,HS,EC_IO,INTRC_IO,INTRC,RC_IO,RC
//////// Fuses: NOMCLR,MCLR,NOBROWNOUT,BROWNOUT,BORV45,BORV42,BORV27,BORV20
//////// Fuses: DEBUG,NODEBUG,CCP2B3,CCP2C1,PROTECT,NOPROTECT,NOFCMEN,FCMEN
//////// Fuses: NOIESO,IESO,NOBORSEN,BORSEN
|
So, INTRC or INTRC_IO and NOWDT
Now the other fuses default to workable settings, but it is always best to either set them how they need to be, or read the LST file and _check_ they are set to a safe value.
If one isn't 'sure' what the specified fuse actually does, then this is where 'fuses.txt' comes in, and we see (for example):
Code: |
INTRC Internal RC Osc
INTRC_IO Internal RC Osc, no CLKOUT
|
Fuses.txt answers your question about BORV42. So:
Code: |
BORV42 Brownout reset at 4.2V
|
Now there are some CCS commands that do change fuses 'by implication'. So (for instance), if your clock statement says:
#clock (INTERNAL=8MHz)
This will default to setting the INTRC fuse. However it leaves whether clock out or I/O is selected 'undefined', so it is safer to set this yourself.
Another one, is the selection of debug mode, where the WDT will be disabled for example. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9228 Location: Greensville,Ontario
|
|
Posted: Thu May 19, 2016 5:07 am |
|
|
more about 'fuses'....
Since PICs these days have more fuses than instructions, I now create a file for each PIC type. 'PICtype_basic.FUZ' is a file that has ALL the fuses in it,one per line. The extention FUZ is easy to understand, I also use DVR for any drivers(like LCD,KBD,etc.),it just makes things easier for me !
By having all the fuses in one file it makes the project Main() code 'smaller', one #include line instead of 20 or 30 fuse lines. Besides WHY type all those fuses into every program, do it once, cause programming is supposed to be fun ! The 'basic' file is used for early work,like '1 Hz LED', 'Hello PC' programs. If a project needs specific fuses then simple edit the filename to say 'PICtype_project.FUZ'. That way you have known working sets of fuses you can rely upon.
maybe this will help you....
Jay |
|
|
duncangray
Joined: 27 Apr 2007 Posts: 14 Location: UK
|
|
Posted: Thu May 19, 2016 10:34 am |
|
|
Thank you both Ttelmah and Jay for some good advice - and CCS support too.
My simple code now works in standalone mode without having to go through the debug stage. CCS hinted at a hardware/MCLR problem so I tested resistance of VSS, VDD and MCLR which showed no problems. I built another even less populated PCB and it worked at the first attempt so I went back to PCB1, extracted the PIC, put it back in and now it works every time.
The only thing I can think of is that there was a poor contact between one of the PIC pins and the socket on PCB1.
Still, it works, and I know a lot more about fuses - and I know there's alot more to learn.
Thanks again everyone for your help.
DG |
|
|
|
|
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
|