|
|
View previous topic :: View next topic |
Author |
Message |
Jim Hearne
Joined: 22 Dec 2003 Posts: 109 Location: West Sussex, UK
|
OSCCAL on 10F200, random values at power up ? |
Posted: Thu Aug 27, 2009 2:36 am |
|
|
Hi all.
I'm having a strange problem with pic 10F200's
Using PCWH 4.093 and a CCS Mach-X programmmer.
These chips have an option for clock out on port GP2, this is selected by bit zero of the osccal register.
The initial problem was that the chips would randomly power up with clock out enabled.
I had to clear bit zero of osccal to stop this.
Then i noticed that the clock speed varies from one power up to the next.
This coupled with the oscout problem suggests that either the compiler or the program isn't initalizing osccal correctly but i can't see anything wrong with the code.
I shouldn't have to have line 25 i'm sure.
I've read the blank chips which seem to have the oscal value at the end of memory and checked it again after they've been programmed and it's still the same value, always with bit zero cleared. (oscout off).
Can anybody spot anything ?
Thanks.
Jim
Code: | #include <10F200.h>
#FUSES WDT, NOMCLR, PROTECT
//////// Fuses: MCLR,NOMCLR,PROTECT,NOPROTECT,WDT,NOWDT
#use delay(clock=4000000)
#byte port_b = 0x06
#byte osccal = 0x05
#bit CLK3 = port_b.0
#bit CLK1 = port_b.1
#bit CLK2 = port_b.2
#bit RESET = port_b.3
#use fast_io(B)
#define PERIOD 50 //=20khz
#define DEADBAND 5
#define INSTRUCTION 1 // clock is 4mhz which equals 1us per instruction.
#define TIME1 DEADBAND-INSTRUCTION
#define TIME2 (PERIOD/2)-(DEADBAND*2)-INSTRUCTION
void main()
{
osccal = osccal & 0xfe; // without this line the chip will randomly power up with fosc4 output enabled on GP2 (B.2)
setup_wdt(WDT_18MS | DISABLE_PULLUPS | DISABLE_WAKEUP_ON_CHANGE);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256);
set_tris_b(0b00001000);
CLK1=1;
CLK2=1;
CLK3=1;
while(1)
{
delay_cycles(TIME1-3); // -3 extra instructions to allow for restart wdt and loop back to start.
CLK2=0;
delay_cycles(TIME2);
CLK2=1;
delay_cycles(TIME1);
CLK1=0;
delay_cycles(TIME1);
CLK3=0;
delay_cycles(TIME2);
CLK3=1;
delay_cycles(TIME1);
CLK1=1;
restart_wdt();
}
} |
Asm
Code: | MPASM
CCS PCB C Compiler, Version 4.093, 44429 27-Aug-09 09:14
Filename: \\Server2005\c\Work\All Products\microvision\boiler probe interface\code\clock gen iss2 pcb 10f200.lst
ROM used: 44 words (17%)
Largest free fragment is 212
RAM used: 2 (12%) at main() level
2 (12%) worst case
Stack: 0 locations
0000 0025 00001 MOVWF 05
0001 0A02 00002 GOTO 002
00003 .................... #include <10F200.h>
00004 .................... //////// Standard Header file for the PIC10F200 device ////////////////
00005 .................... #device PIC10F200
00006 .................... //#nolist
00007 .................... //////// Program memory: 256x12 Data RAM: 16 Stack: 2
00008 .................... //////// I/O: 4 Analog Pins: 0
00009 .................... //////// C Scratch area: 10 ID Location: 0100
00010 .................... //////// Oscilator Calibration Address: 05
00011 .................... //////// Fuses: MCLR,NOMCLR,PROTECT,NOPROTECT,WDT,NOWDT
00012 .................... ////////
00013 .................... ////////////////////////////////////////////////////////////////// I/O
00014 .................... // Discrete I/O Functions: SET_TRIS_x(), OUTPUT_x(), INPUT_x(),
00015 .................... // PORT_x_PULLUPS(), INPUT(),
00016 .................... // OUTPUT_LOW(), OUTPUT_HIGH(),
00017 .................... // OUTPUT_FLOAT(), OUTPUT_BIT()
00018 .................... // Constants used to identify pins in the above are:
00019 ....................
00020 .................... #define PIN_B0 48
00021 .................... #define PIN_B1 49
00022 .................... #define PIN_B2 50
00023 .................... #define PIN_B3 51
00024 ....................
00025 .................... ////////////////////////////////////////////////////////////////// Useful defines
00026 .................... #define FALSE 0
00027 .................... #define TRUE 1
00028 ....................
00029 .................... #define BYTE int8
00030 .................... #define BOOLEAN int1
00031 ....................
00032 .................... #define getc getch
00033 .................... #define fgetc getch
00034 .................... #define getchar getch
00035 .................... #define putc putchar
00036 .................... #define fputc putchar
00037 .................... #define fgets gets
00038 .................... #define fputs puts
00039 ....................
00040 .................... ////////////////////////////////////////////////////////////////// Control
00041 .................... // Control Functions: RESET_CPU(), SLEEP(), RESTART_CAUSE()
00042 .................... // Constants returned from RESTART_CAUSE() are:
00043 .................... #define WDT_FROM_SLEEP 0x00
00044 .................... #define WDT_TIMEOUT 0x08
00045 .................... #define MCLR_FROM_SLEEP 0x10
00046 .................... #define NORMAL_POWER_UP 0x18
00047 .................... #define COMP_FROM_SLEEP 0x50
00048 .................... #define PIN_CHANGE_FROM_SLEEP 0x90
00049 ....................
00050 ....................
00051 .................... ////////////////////////////////////////////////////////////////// Timer 0
00052 .................... // Timer 0 (AKA RTCC)Functions: SETUP_COUNTERS() or SETUP_TIMER_0(),
00053 .................... // SET_TIMER0() or SET_RTCC(),
00054 .................... // GET_TIMER0() or GET_RTCC()
00055 .................... // Constants used for SETUP_TIMER_0() are:
00056 .................... #define RTCC_INTERNAL 0
00057 .................... #define RTCC_EXT_L_TO_H 32
00058 .................... #define RTCC_EXT_H_TO_L 48
00059 ....................
00060 .................... #define RTCC_DIV_1 8
00061 .................... #define RTCC_DIV_2 0
00062 .................... #define RTCC_DIV_4 1
00063 .................... #define RTCC_DIV_8 2
00064 .................... #define RTCC_DIV_16 3
00065 .................... #define RTCC_DIV_32 4
00066 .................... #define RTCC_DIV_64 5
00067 .................... #define RTCC_DIV_128 6
00068 .................... #define RTCC_DIV_256 7
00069 ....................
00070 ....................
00071 .................... #define RTCC_8_BIT 0
00072 ....................
00073 .................... // Constants used for SETUP_COUNTERS() are the above
00074 .................... // constants for the 1st param and the following for
00075 .................... // the 2nd param:
00076 ....................
00077 .................... ////////////////////////////////////////////////////////////////// WDT
00078 .................... // Watch Dog Timer Functions: SETUP_WDT() or SETUP_COUNTERS() (see above)
00079 .................... // RESTART_WDT()
00080 .................... // WDT base is 18ms
00081 .................... //
00082 ....................
00083 .................... #define WDT_18MS 8
00084 .................... #define WDT_36MS 9
00085 .................... #define WDT_72MS 10
00086 .................... #define WDT_144MS 11
00087 .................... #define WDT_288MS 12
00088 .................... #define WDT_576MS 13
00089 .................... #define WDT_1152MS 14
00090 .................... #define WDT_2304MS 15
00091 ....................
00092 .................... #define DISABLE_PULLUPS 0x40 // for 508 and 509 only
00093 .................... #define DISABLE_WAKEUP_ON_CHANGE 0x80 // for 508 and 509 only
00094 .................... #ifndef PIN_CHANGE_FROM_SLEEP
00095 .................... #define PIN_CHANGE_FROM_SLEEP 0x90 // for 508 and 509 only
00096 .................... #endif
00097 ....................
00098 ....................
00099 .................... #list
00100 ....................
00101 .................... #FUSES WDT, NOMCLR, PROTECT
00102 .................... //////// Fuses: MCLR,NOMCLR,PROTECT,NOPROTECT,WDT,NOWDT
00103 ....................
00104 .................... #use delay(clock=4000000)
00105 .................... #byte port_b = 0x06
00106 .................... #byte osccal = 0x05
00107 ....................
00108 .................... #bit CLK3 = port_b.0
00109 .................... #bit CLK1 = port_b.1
00110 .................... #bit CLK2 = port_b.2
00111 .................... #bit RESET = port_b.3
00112 ....................
00113 .................... #use fast_io(B)
00114 ....................
00115 .................... #define PERIOD 50 //=20khz
00116 .................... #define DEADBAND 5
00117 .................... #define INSTRUCTION 1 // clock is 4mhz which equals 1us per instruction.
00118 ....................
00119 .................... #define TIME1 DEADBAND-INSTRUCTION
00120 .................... #define TIME2 (PERIOD/2)-(DEADBAND*2)-INSTRUCTION
00121 ....................
00122 .................... void main()
00123 .................... {
0002 0CDF 00124 MOVLW DF
0003 0002 00125 OPTION
0004 0064 00126 CLRF 04
00127 .................... osccal = osccal & 0xfe; // without this line the chip will randomly power up with fosc4 output enabled on GP2 (B.2)
0005 0405 00128 BCF 05.0
00129 .................... setup_wdt(WDT_18MS | DISABLE_PULLUPS | DISABLE_WAKEUP_ON_CHANGE);
0006 0070 00130 CLRF 10
0007 0061 00131 CLRF 01
0008 0C0F 00132 MOVLW 0F
0009 0002 00133 OPTION
000A 0004 00134 CLRWDT
000B 0210 00135 MOVF 10,W
000C 0002 00136 OPTION
00137 .................... setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256);
000D 0C07 00138 MOVLW 07
000E 0002 00139 OPTION
00140 .................... set_tris_b(0b00001000);
000F 0C08 00141 MOVLW 08
0010 0006 00142 TRIS 6
00143 ....................
00144 .................... CLK1=1;
0011 0526 00145 BSF 06.1
00146 .................... CLK2=1;
0012 0546 00147 BSF 06.2
00148 .................... CLK3=1;
0013 0506 00149 BSF 06.0
00150 ....................
00151 .................... while(1)
00152 .................... {
00153 .................... delay_cycles(TIME1-3); // -3 extra instructions to allow for restart wdt and loop back to start.
0014 0000 00154 NOP
00155 .................... CLK2=0;
0015 0446 00156 BCF 06.2
00157 .................... delay_cycles(TIME2);
0016 0C04 00158 MOVLW 04
0017 0030 00159 MOVWF 10
0018 02F0 00160 DECFSZ 10,F
0019 0A18 00161 GOTO 018
001A 0000 00162 NOP
00163 .................... CLK2=1;
001B 0546 00164 BSF 06.2
00165 .................... delay_cycles(TIME1);
001C 0A1D 00166 GOTO 01D
001D 0A1E 00167 GOTO 01E
00168 .................... CLK1=0;
001E 0426 00169 BCF 06.1
00170 .................... delay_cycles(TIME1);
001F 0A20 00171 GOTO 020
0020 0A21 00172 GOTO 021
00173 .................... CLK3=0;
0021 0406 00174 BCF 06.0
00175 .................... delay_cycles(TIME2);
0022 0C04 00176 MOVLW 04
0023 0030 00177 MOVWF 10
0024 02F0 00178 DECFSZ 10,F
0025 0A24 00179 GOTO 024
0026 0000 00180 NOP
00181 .................... CLK3=1;
0027 0506 00182 BSF 06.0
00183 .................... delay_cycles(TIME1);
0028 0A29 00184 GOTO 029
0029 0A2A 00185 GOTO 02A
00186 .................... CLK1=1;
002A 0526 00187 BSF 06.1
00188 .................... restart_wdt();
002B 0004 00189 CLRWDT
00190 .................... }
002C 0A14 00191 GOTO 014
00192 .................... }
002D 0003 0193 SLEEP
Configuration Fuses:
Word 1: 0FE7 NOMCLR PROTECT WDT
SYMBOL TABLE
LABEL VALUE
osccal 00000005
port_b 00000006
CLK3 00000006
CLK1 00000006
CLK2 00000006
RESET 00000006
_RETURN_ 00000011
Allocation: 0000EEEF
main 00000002
MEMORY USAGE |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Aug 27, 2009 2:01 pm |
|
|
Quote: | The initial problem was that the chips would randomly power up with clock out enabled. |
Read this section of the 10F200 data sheet. You probably erased the
MOVLW xx instruction at the end of ROM, or programmed it with some
other value than the factory value. Or the MachX did it.
Quote: |
9.2.2 INTERNAL 4 MHz OSCILLATOR
In addition, a calibration instruction is programmed into
the last address of memory, which contains the calibration
value for the internal oscillator. This location is
always uncode protected, regardless of the code protect
settings. This value is programmed as a MOVLW xx
instruction where xx is the calibration value and is
placed at the Reset vector. This will load the W register
with the calibration value upon Reset and the PC will
then roll over to the users program at address 0x000.
The user then has the option of writing the value to the
OSCCAL Register (05h) or ignoring it.
OSCCAL, when written to with the calibration value, will
“trim” the internal oscillator to remove process variation
from the oscillator frequency. |
Read the value of the last ROM address in the PIC, with your
programmer. What is it ?
Also check to see if the MachX has a setting that will preserve
this value (it probably should do it automatically).
If you have erased the OSCCAL value at the end of ROM, then you could
fix it by adding the ROM statement shown below. This puts the opcode for
a MOVLW 0x00 statement at the end of ROM. That will turn off the
FOSC/4 output, and it will set OSCCAL for the center frequency.
Code: |
#include <10F200.h>
#FUSES NOWDT, NOMCLR, NOPROTECT
#use delay(clock=4000000)
#rom 0xFF = {0xC00} // Put MOVLW 0x00 at end of ROM
//=================================
void main()
{
while(1);
} |
|
|
|
Jim Hearne
Joined: 22 Dec 2003 Posts: 109 Location: West Sussex, UK
|
|
Posted: Fri Aug 28, 2009 3:29 am |
|
|
Hi PCM,
You seem to be correct, the programmer isn't preserving the osccal value at 0x1FFF
I've tested a couple of chips before programming and then read them back.
Before:
Code: | Chip one: 0x0c16
Chip two: 0x0c20 |
After
Code: | Chip one: 0x0064
Chip two: 0x0fff |
I'm not quite sure what it's doing but it's not correct.
The ccsload software for the machx had no specific options for the calibration, there is a calibrate chip button but it just comes back saying "Fail".
The help for this says
Quote: | Calibrate – Only appears for chips that have a calibration constant in program memory.
This function will recalculate the calibration constant and store it in memory.
Note that for these chips the CCSLOAD software does not change this constant on writes or erases. |
Which implies that it should be preserving the calibration value.
Time for another email to CCS i guess :-(
Thanks for you help,
Jim |
|
|
Jim Hearne
Joined: 22 Dec 2003 Posts: 109 Location: West Sussex, UK
|
|
Posted: Fri Aug 28, 2009 3:59 am |
|
|
Oh, forgot, all the chip does is generate 3 clock signals but we'd like to keep them as accurate as is possible with the on chip osc so really want to keep the calibrated oscilator.
Jim |
|
|
|
|
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
|