View previous topic :: View next topic |
Author |
Message |
johnl
Joined: 30 Sep 2003 Posts: 120
|
16F636 --> 16F18323 code migration |
Posted: Wed Feb 16, 2022 2:35 pm |
|
|
Well it's time to switch chips. The code is from 10 years ago when Ttelmah, PCM programmer and temtronic all helped me. Here's the link if you're curious: http://www.ccsinfo.com/forum/viewtopic.php?t=47536&highlight=wure
First stumbling block is with fuses. In the '18323 header file, NOIESO (disable switch-over bit for oscillator), NOWURE and INTRC_IO are all invalid fuses.
Since there's no NOWURE, how to tell the '18323 to not reset after wake up.
Here's the beginning of the old code which worked without an issue:
Code: |
#include <16F636.h>
#include "p7dat.h"
#include "LetrSym.h"
#FUSES NOWDT, INTRC_IO, PROTECT, NOCPD, MCLR, NOIESO, NOPUT, NOFCMEN, NOWURE, NOBROWNOUT
#use delay(clock=8000000)
#byte WPUDA=0x95
#byte WDA=0x97
#byte OPTION_REG=0x81
#byte T1CON = 0x10
#byte PORTA = 5
#byte PORTC = 7
|
For the '18323, there are lots of oscillator choices in the fuses. What combination would be the equivalent of INTRC_IO? If I want 8Mhz, can the setup_oscillator(OSC_HFINTRC_8MHZ) function simply be used? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
Re: 16F636 --> 16F18323 code migration |
Posted: Wed Feb 16, 2022 4:06 pm |
|
|
johnl wrote: |
Since there's no NOWURE, how to tell the '18323 to not reset after wake up. |
How are you waking up the PIC ?
If you are waking up by an interrupt, the PIC just continues running.
From the data sheet:
Quote: | 9.3.1 WAKE-UP FROM SLEEP
The device can wake-up from Sleep through one of the
following events:
1. External Reset input on MCLR pin, if enabled
2. BOR Reset, if enabled.
3. POR Reset.
4. Watchdog Timer, if enabled
5. Interrupts by peripherals capable of running
during Sleep (see individual peripheral for more
information).
The first three events will cause a device Reset.
The last two events are considered a continuation
of program execution.
|
johnl wrote: |
For the '18323, there are lots of oscillator choices in the fuses. What combination would be the equivalent of INTRC_IO? If I want 8Mhz, can the setup_oscillator(OSC_HFINTRC_8MHZ) function simply be used? |
What's your compiler version ? If it's a modern version, let the
compiler handle the oscillator. Example:
Code: | #use delay(internal=8M) |
|
|
|
johnl
Joined: 30 Sep 2003 Posts: 120
|
|
Posted: Wed Feb 16, 2022 4:34 pm |
|
|
It wakes from int on A0:
Code: | do {
dummy=input(BUTTON); //Pin A0
clear_interrupt(INT_RA);
enable_interrupts(INT_RA0);
SENSOR_POWER = 0;
sleep();
delay_cycles(1);
disable_interrupts(INT_RA0); //////(INT_RA); //Now turn the interrupt off
delay_ms(100); //debounce switch
SENSOR_POWER=1;
while (dummy = !input(BUTTON) )
{button_time++;
delay_ms(100);
if (button_time>20)
prog_mode();
}
run_mode();
} while (TRUE); |
Compiler is 5.056. Are you saying no oscillator-related fuses are necessary to set the osc at 8Mhz? Will that hold after sleep and wake-up without resets?
Thank you. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Feb 16, 2022 4:49 pm |
|
|
I'm saying the compiler sets the oscillator fuses for you. Look at the
end of the .LST file after you compile. It will show the fuses that the
compiler has selected. The fuses don't change once they are set.
It doesn't matter whether you set them or the compiler sets them.
They don't change. |
|
|
johnl
Joined: 30 Sep 2003 Posts: 120
|
PIC16F18323 Gate function |
Posted: Thu Feb 17, 2022 3:03 pm |
|
|
The timer 1 block diagram on page 265 of the '18323 datasheet shows the T1GSPM bit enabling single pulse mode when low, but the text says otherwise:
Quote: | Timer1 Gate Single-Pulse mode is first enabled by setting the
T1GSPM bit in the T1GCON register |
Is the diagram a misprint or am I missing something? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Thu Feb 17, 2022 3:44 pm |
|
|
since your original PIC doesn't have 'single pulse ' mode, simply use the timer1 as before. Reading the datasheet, it appears to use single pulse more is a 2 or 3 step process....
I don't have the PIC to try stuff( or a newish compiler).
BTW since that PIC is 'PPS', be 100% sure that's all setup before you cut 'real code'....... |
|
|
johnl
Joined: 30 Sep 2003 Posts: 120
|
|
Posted: Thu Feb 17, 2022 6:32 pm |
|
|
temtronic wrote: | since your original PIC doesn't have 'single pulse ' mode, simply use the timer1 as before.
BTW since that PIC is 'PPS', be 100% sure that's all setup before you cut 'real code'....... |
Yes, I don't want to use it, but was questioning the discrepancy between the diagram and the wording in the data sheet. Guess I'll go with the words.
Set up PPS, good advice. Thank you. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Feb 17, 2022 6:56 pm |
|
|
I think it's a bug in the diagram. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Fri Feb 18, 2022 1:08 am |
|
|
I'd say diagram is wrong.
The Register setting (27-2), agrees with the text, and also the waveform
diagrams showing this in use. Also Microchip's note section on this:
[url]
https://microchipdeveloper.com/8bit:timer1gate
[/url]
Also if you look at other chips with the gate control, they agree with the text.
However assuming you are not using this (since it wasn't present in the
older chip), have to agree totally with PCM, and "don't worry". If you don't
set this up the default is to behave as a chip without gate control.
This also agrees with the text, since the default on the bit is '0'.
Impressive thing about this chip is how few errata it has. The few it does
have are unlikely to affect normal operation. So a nice choice.
The key difference as has already been pointed out is PPS. Understand
that with CCS, you can't 'assume' the default PPS assignments. Always
set it up. Read the sticky about PPS at the head of the forum. |
|
|
johnl
Joined: 30 Sep 2003 Posts: 120
|
|
Posted: Fri Feb 18, 2022 4:35 pm |
|
|
temtronic, PCM Programmer and Ttelmah:
Thank you all again for taking the time to help with this project... both now and ten years ago!
All is working now after configuring PPS and getting timer1 to accept external clock and gate inputs.
The only detail left is reducing sleep current. With the '636 running in the same board, I measure under a microamp. With the 18323, about 5 microamps which is a little high but almost acceptable. I'm going to try setting bit one of VREGCON to put it in low power sleep mode. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Fri Feb 18, 2022 5:47 pm |
|
|
one hint...
to reduce power, be sure to disable any peripherals you're not using.
another
be sure output pins are either high or low NOT 'floating'. |
|
|
johnl
Joined: 30 Sep 2003 Posts: 120
|
|
Posted: Sat Feb 19, 2022 12:14 pm |
|
|
temtronic wrote: | one hint...
to reduce power, be sure to disable any peripherals you're not using.
another
be sure output pins are either high or low NOT 'floating'. |
The '636 draws sleep current that I can't measure with 0-100 microamp analog meter.
The '18323 draws 3-4 microamps in the same board.
In sleep mode, all measured pin voltages are the same for both chips.
I tried turning everything off:
Code: | #FUSES WDT_SW, NOPROTECT, NOCPD, MCLR, NOPUT, NOFCMEN, NOBROWNOUT , NOLVP
#fuses NOEXTOSC,NOCLKOUT
|
Code: | setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_counters(RTCC_OFF,0);
setup_timer_1(T1_DISABLED );
setup_timer_2(T2_DISABLED,1,1 );
setup_ccp1(CCP_OFF );
setup_ccp2(CCP_OFF );
setup_spi(SPI_DISABLED);
setup_dac(DAC_OFF);
setup_cwg(CWG_DISABLED , 0, 0, 0);
setup_adc(ADC_OFF);
setup_wdt(WDT_OFF);
PMD0 = 0b01000010;
PMD1 = 0b10000101;
PMD2 = 0b01100110;
PMD3 = 0b01110011;
PMD4 = 0b00100010;
PMD5 = 0b00000111;
set_tris_a(0b00110001); // A0, A4, A5 inputs
set_tris_c(0);
T1CON = 0b10000001;
T1GCON = 0b11000000;
VREGCON = 0b10;
setup_adc_ports(NO_ANALOGS); |
I could live with a few microamps since the battery will still have a very long life, but I'm very curious what I'm doing wrong. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Sun Feb 20, 2022 3:50 am |
|
|
The point being made by Jay about the pins is critical. If a pin is left
undriven, and the chip is put to sleep, on some chips it'll be OK, but on
others, if the signal floats into the 'transition region', the chip will start
to draw extra current. This can vary between even different chip batches,
but even more between different actual chips.
Simple rule is that when asleep, no pins must ever be left floating.
If one or more pins does float this way, it can make a factor of a
hundred difference in the power drawn in sleep.... |
|
|
johnl
Joined: 30 Sep 2003 Posts: 120
|
|
Posted: Sun Feb 20, 2022 5:22 pm |
|
|
Got it working. After disabling most of the functions controlled by PMD0:
Code: |
PMD0 = 0b11111110; // all off except pin change interrupt
|
Then restoring PMD0 after wakeup from a pin change:
Code: |
sleep();
delay_cycles(1);
disable_interrupts(INT_RA0); //Now turn the interrupt off
delay_ms(100); //debounce switch
PMD0 = 0b01000010;
|
The sleep current went down from 3-4 microamps to a fraction of one microamp. Not sure why the three instructions following the sleep instruction work with Fosc disabled (bit 7) but it seems to run as desired.
Thanks for your help. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Mon Feb 21, 2022 3:02 am |
|
|
The clock has restarted.
Look at the timing diagrams for sleep. The program counter does not advance
to the next instruction till Tost has completed. This is a long time if starting
an external oscillator (1024 cyles), but is zero for the internal oscillators.
In either case the next instruction is not executed till the oscillator has
started. It also executes two 'forced nop' instructions before executing the
next real instruction.
The PMD bit doesn't stop Fosc. It disconnects it from the peripherals. You are
not using a peripheral before you turn it back on. |
|
|
|