|
|
View previous topic :: View next topic |
Author |
Message |
ktallevi
Joined: 17 Dec 2005 Posts: 58
|
clock switching and delays |
Posted: Mon Dec 03, 2007 3:21 pm |
|
|
Using the code below, I am operating a PIC18LF8722 at 8Mhz using the internal osc. I want to switch to an external crystal on timer1 to conserve power without going completely to sleep (so I can still execute certain instructions). I compiled a little test program, but it appears that the delay loops are not compiling correctly for the lower crystal frequency. Relevant code snippets posted below....
*config file*
#FUSES INTRC
#use delay(clock=8000000)
*main program file*
void main() {
/*configure timer and osc. */
setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1 | T1_CLK_OUT);
enable_interrupts(INT_TIMER1);
setup_oscillator(OSC_8MHZ | OSC_INTRC);
/*non relevant code here...*/
/* testing low frequency crystal on timer1 */
setup_oscillator(OSC_TIMER1);
#use delay(clock=38400)
do {
delay_ms(1000); <-- problem appears to be here
output_toggle(BLUE_LED);
} while(1);
}
It is my understanding that the delay_ms should be using the last #use delay(clock=38400) statement during compilation, but its not, the delay is MUCH longer than 1 second in that example. any ideas?
thanks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 03, 2007 3:24 pm |
|
|
Post your compiler version. |
|
|
ktallevi
Joined: 17 Dec 2005 Posts: 58
|
|
Posted: Mon Dec 03, 2007 3:25 pm |
|
|
sorry, 3.249 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 03, 2007 11:16 pm |
|
|
Is that you real #fuses statement ? Because it enables things that
shouldn't be enabled in this test program, such as the Watchdog Timer
and Low Voltage Programming mode.
Quote: |
Configuration Fuses:
Word 1: 0900 NOIESO NOFCMEN INTRC RESERVED
Word 2: 1F1F BROWNOUT WDT BORV25 NOPUT WDT32768
Word 3: 83F3 CCP2C1 NOLPT1OSC MCLR MCU RESERVED WAIT BW16 ABW20 ECCPE
Word 4: 0085 STVREN NODEBUG LVP NOXINST RESERVED
Word 5: C0FF NOPROTECT NOCPD NOCPB
Word 6: E0FF NOWRT NOWRTD NOWRTC NOWRTB
Word 7: 40FF NOEBTRB NOEBTR
|
|
|
|
ktallevi
Joined: 17 Dec 2005 Posts: 58
|
|
Posted: Tue Dec 04, 2007 9:37 am |
|
|
PCM Programmer,
I got it working thanks for your help, but im having an issue related to this dual osc. configuration. I found a sample piece of code you posted on another thread. It works great, but I added a 2nd serial port (same pins, hardware uart, different stream name), but it doesnt work. It only works if I define "force_sw" for both rs232 statements. Is it not possible to use the same Hardware UART, at the same baud rate, but at different crystal osc speeds??
code pasted below:
Code: |
#include <18F8722.H>
#fuses INTRC, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 8000000)
#use rs232(baud=300,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=mySerial)
#use delay(clock = 31250)
#use rs232(baud=300,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=SerialPort)
#define LOW 0
#define HIGH 1
int8 speed = LOW;
void my_delay_ms(int16 value);
//==================================
void main()
{
do {
setup_oscillator( OSC_31KHZ | OSC_NORMAL | OSC_IDLE_MODE | OSC_31250 );
speed = LOW;
my_delay_ms(1000);
output_toggle(PIN_D4);
fprintf(SerialPort,"\n\rClock = 31.250Khz");
setup_oscillator(OSC_8MHZ);
speed = HIGH;
my_delay_ms(100);
output_toggle(PIN_D5);
fprintf(mySerial,"\n\rClock = 8Mhz");
} while(1);
while(1);
}
//================================
void my_delay_ms(int16 value)
{
if(speed == HIGH)
{
#use delay(clock=8000000)
delay_ms(value);
}
else
{
#use delay(clock=31250)
delay_ms(value);
}
} |
So in this situation only the 31Khz gets printed on the screen. I understand the last #delay statement is the one used for the delay statements, but it appears the compiler only supports 1 Hardware UART configuration for a single UART.
Perhaps its possible to reconfigure the UART at runtime (for the different clocks) by manually changing the UART registers??
thanks |
|
|
Ttelmah Guest
|
|
Posted: Tue Dec 04, 2007 11:30 am |
|
|
I'd cheat.....
Setup the 'use rs232', for the default fast clock. Then define yourself two statements:
#define FAST_CLOCK_BAUD 300
#define SLOW_CLOCK_BAUD (FAST_CLOCK_BAUD*256)
#define UART_FOR_SLOW_CLOCK() set_uart_speed(SLOW_CLOCK_BAUD)
#define UART_FOR_FAST_CLOCK() set_uart_speed(FAST_CLOCK_BAUD)
In your code, once you change to the slow speed, call 'UART_FOR_SLOW_CLOCK()' and when you return to fast speed, call 'UART_FOR_FAST_CLOCK()'. This way the code to reprogram the BRG should be generated where it is needed. The problem otherwise, is that the speed change will only occur 'retrospectively', requiring you to send a character, before the switch occurs.
Efectively the system will generate the correct settings, for a baud rate that is the ratio of the two clock rates (hence 256*) higher than is used at the faster clock.
Best Wishes |
|
|
Ttelmah Guest
|
|
Posted: Tue Dec 04, 2007 11:32 am |
|
|
Remember also, that the speed change then needs to be done _before_ the new 'use delay' statement.
Best Wishes |
|
|
|
|
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
|