I have a PIC16F88 program that runs on a battery and I want to cut power usage by sarting at 31.25 kHz and when a button is pressed switch to 8MHZ run a section of the program the switch bak to 31.25 khz and wait for the button press and do it all again. Does anyone have any sample code to switch the internal oscilator from 31.25 khz to 8 MHZ?
Thank you
Craig
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
About a 100 times less power in sleep, 3 mA's at 8mhz intrc, 35 uA's at 31.25khz. Check out the DC characteristic charts in the data sheet.
Since interrupts have been a bit of a topic lately, here is an example for the 16f88. Normally wouldn't go this far for fear of doing someones homework. But will chance it here in order to clarify(?) using GCBasic with an interrupt.
Found something out here during the investigation, there is a conflict betweent the chipdata files and the 16f88 datasheet. The chipdata files expect INTE and INTF for the RB0/Int enable and flags respectively, while the 16f88 data sheet says INT0IE and INT0IF, use the chipdata bit definitions.
In theory, you shouldn't have to use GIE and the interrupt vector. In other words you could set GIE = 0, and instead of having an interrupt subroutine, you would inline your code after sleep.
'A program to put the PIC device to sleep (low power mode).
'By pressing the RB0/Int button an interrupt is generated, an LED is turned on,
'then goes back to sleep until next button press.
'A 10k pullup resistor is tied to RB0. A 0.1uf cap from RB0 to
'ground is used to help debounce the switch.
'I would expect the RB0 to be an input, but by setting the INTE bit, it doesn't
'seem to matter.
'Chip model
#chip 16f88, 8
'Use internal osc, so don't have to mess with OSCCON register
#config OSC = INTRC_IO, WDT = OFF, BODEN = OFF, PWRTE= ON, LVP = OFF
#define LED1 PortB.3
dir PortB.0 in 'Interrupt is tied high with 10k resistor
'High Z RB2 because on board Olimex Pic-18 button will be jumpered from RB2 to RB0
dir PortB.2 in
dir LED1 out
GIE = 1 'Enable global interrupts
INTE = 1 'Enable RB0/Int interrupt, Expected INTOIE here per 16f88 datasheet
INTEDG = 1 'Look for rising edge on RB0 (OPTION_REG <6>)
Start:
'GCBasic recognizes assembler instructions like sleep
'Puts the pic in low power mode using internal 31khz rc osc
sleep
'Uncomment the following line to see effect of next instruction
'execution after sleep command
'If Not_PD = 0 then set LED1 On
nop 'Data sheet says next command is executed before going into sleep
goto Start
Sub Interrupt
GIE = 0 'Disabled further attempts to interrupt
INTE = 0 'Expected INTOIE here per 16f88 datasheet
INTF = 0 'Clear the RB0/Int flag, Expected INT0IF here per 16f88 datasheet
Set LED1 on
wait 1 s
Set LED1 Off
wait 1 s
GIE = 1 'Re-enable interrupts
INTE = 1 'Expected INTOIE here per 16f88 datasheet
end sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Internal pullups even better yet, thanks for checking on me, need that at 54. So for those people who haven't used the internal PortB pullups, "NOT_RBPU = 0" will do the trick during initialization.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Another thought, probably don't need to clear and re-enable the GIE and INTE bits in the interrupt example, as it looks like GIE is cleared in hardware.
The assembler retfie(return from interrrupt) command is inserted by GCBasic. You can look it up in the compile.asm file in the GCBasic directory.
The Not_PD = 0 is the power down bit in the STATUS directory. If the sleep command has executed, it will be zero.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have a PIC16F88 program that runs on a battery and I want to cut power usage by sarting at 31.25 kHz and when a button is pressed switch to 8MHZ run a section of the program the switch bak to 31.25 khz and wait for the button press and do it all again. Does anyone have any sample code to switch the internal oscilator from 31.25 khz to 8 MHZ?
Thank you
Craig
I'm just curious, and don't have an answer, but does the MCU use less power at the lower frequency?
About a 100 times less power in sleep, 3 mA's at 8mhz intrc, 35 uA's at 31.25khz. Check out the DC characteristic charts in the data sheet.
Since interrupts have been a bit of a topic lately, here is an example for the 16f88. Normally wouldn't go this far for fear of doing someones homework. But will chance it here in order to clarify(?) using GCBasic with an interrupt.
Found something out here during the investigation, there is a conflict betweent the chipdata files and the 16f88 datasheet. The chipdata files expect INTE and INTF for the RB0/Int enable and flags respectively, while the 16f88 data sheet says INT0IE and INT0IF, use the chipdata bit definitions.
In theory, you shouldn't have to use GIE and the interrupt vector. In other words you could set GIE = 0, and instead of having an interrupt subroutine, you would inline your code after sleep.
'A program to put the PIC device to sleep (low power mode).
'By pressing the RB0/Int button an interrupt is generated, an LED is turned on,
'then goes back to sleep until next button press.
'A 10k pullup resistor is tied to RB0. A 0.1uf cap from RB0 to
'ground is used to help debounce the switch.
'I would expect the RB0 to be an input, but by setting the INTE bit, it doesn't
'seem to matter.
'Chip model
#chip 16f88, 8
'Use internal osc, so don't have to mess with OSCCON register
#config OSC = INTRC_IO, WDT = OFF, BODEN = OFF, PWRTE= ON, LVP = OFF
#define LED1 PortB.3
dir PortB.0 in 'Interrupt is tied high with 10k resistor
'High Z RB2 because on board Olimex Pic-18 button will be jumpered from RB2 to RB0
dir PortB.2 in
dir LED1 out
GIE = 1 'Enable global interrupts
INTE = 1 'Enable RB0/Int interrupt, Expected INTOIE here per 16f88 datasheet
INTEDG = 1 'Look for rising edge on RB0 (OPTION_REG <6>)
Start:
'GCBasic recognizes assembler instructions like sleep
'Puts the pic in low power mode using internal 31khz rc osc
sleep
'Uncomment the following line to see effect of next instruction
'execution after sleep command
'If Not_PD = 0 then set LED1 On
nop 'Data sheet says next command is executed before going into sleep
goto Start
Sub Interrupt
GIE = 0 'Disabled further attempts to interrupt
INTE = 0 'Expected INTOIE here per 16f88 datasheet
INTF = 0 'Clear the RB0/Int flag, Expected INT0IF here per 16f88 datasheet
Set LED1 on
wait 1 s
Set LED1 Off
wait 1 s
GIE = 1 'Re-enable interrupts
INTE = 1 'Expected INTOIE here per 16f88 datasheet
end sub
Thank You for the help, no chance of doing my homework at 47 my days of homework are long past:')
Craig
BTW you say to use 10k pullups will the internal pullups work as well?
It will be a day or 2 befor I can try this.
Craig
Internal pullups even better yet, thanks for checking on me, need that at 54. So for those people who haven't used the internal PortB pullups, "NOT_RBPU = 0" will do the trick during initialization.
How does the chip go back to sleep after the interrupt routine runs?
Also, what does "Not_PD = 0" mean?
Thanks!
Another thought, probably don't need to clear and re-enable the GIE and INTE bits in the interrupt example, as it looks like GIE is cleared in hardware.
The assembler retfie(return from interrrupt) command is inserted by GCBasic. You can look it up in the compile.asm file in the GCBasic directory.
The Not_PD = 0 is the power down bit in the STATUS directory. If the sleep command has executed, it will be zero.