|
|
View previous topic :: View next topic |
Author |
Message |
JMarysse
Joined: 27 Oct 2017 Posts: 9
|
Sleep on pic24 with RTCC not working |
Posted: Fri Oct 27, 2017 6:13 am |
|
|
I want to wakeup the pic every 10 seconds.
This is what i see on the terminal:
Program started
Friday 27/10/2017 09:02:00
Wakeup from sleep => after ±4 seconds
Friday 27/10/2017 09:02:00
Wakeup from sleep => after ±4 seconds
...
after 7 times this is as the program runs WITHOUT the sleep.
Please can someone advise ?
I have CCS PCWHD compiler V5.075
Thanks!
This is the code :
main.h :
Code: |
#include <24FJ64GB406.h>
#device ADC=12
#device ICSP=1
#use delay(internal=8000000,restart_wdt)
#FUSES WDT //Watch Dog Timer
#FUSES WDT32 //Watch Dog Timer uses 1:32 Postscale
#FUSES WPOSTS13 //Watch Dog Timer PostScalar 1:4096
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOJTAG //JTAG disabled
/* UART6 */
#use rs232(xmit=PIN_B7, rcv=PIN_B12, baud=19200, restart_wdt, stream=UART_PORT)
|
main.c :
Code: |
#include "main.h"
/**************************
*** PORT B definitions ***
**************************/
struct port_b_layout {
unsigned int8 pged : 1; /* For Debuger => B0 */
unsigned int8 pgec : 1; /* For Debugger => B1 */
unsigned int8 i2c_scl3 : 1; /* I2C Bus 3 => B2 */
unsigned int8 i2c_sda3 : 1; /* I2C Bus 3 => B3 */
unsigned int8 co2_input : 1; /* Analog input from CO2 sensor => B4 */
unsigned int8 i2c_sda2 : 1; /* I2C Bus 2 => B5 */
unsigned int8 i2c_scl2 : 1; /* I2C Bus 2 => B6 */
unsigned int8 db_uart_tx : 1; /* TX for Debugging => B7 */
unsigned int8 tsic_1 : 1; /* TSIC716_1 input => B8 */
unsigned int8 tsic_2 : 1; /* TSIC716_2 input => B9 */
unsigned int8 dio_7 : 1; /* Digital in/out => B10 */
unsigned int8 dio_8 : 1; /* Digital in/out => B11 */
unsigned int8 db_uart_rx : 1; /* RX for Debugging B12 */
unsigned int8 dio_9 : 1; /* Digital in/out => B13 */
unsigned int8 i2c_sda4 : 1; /* I2C Bus 4 => B14 */
unsigned int8 i2c_scl4 : 1; /* I2C Bus 4 => B15 */
};
struct port_b_layout port_b;
#byte port_b = 0x674
struct port_b_layout const port_b_for_io = {1,1,0,0,1,0,0,0,1,1,0,0,1,0,0,0};
/**************************
*** PORT C definitions ***
**************************/
struct port_c_layout {
unsigned int8 not_used : 12; /* not used pins => C0-C11 */
unsigned int8 dio_4 : 1; /* Digital in/out => C12 */
unsigned int8 dio_3 : 1; /* Digital in/out => C13 */
unsigned int8 acc_int2 : 1; /* INT2 from Acc.meter => C14 */
unsigned int8 dio_5 : 1; /* Digital in/out => C15 */
};
struct port_c_layout port_c;
#byte port_c = 0x688
struct port_c_layout const port_c_for_io = {0xfff,0,0,1,0};
/**************************
*** PORT D definitions ***
**************************/
struct port_d_layout {
unsigned int8 acc_spi_mosi : 1; /* SPI DO to Acc.meter => D0 */
unsigned int8 nina_rxd : 1; /* TX to Nina module => D1 */
unsigned int8 mem_spi_cs : 1; /* SPI CS for flashmemory=> D2 */
unsigned int8 mem_spi_sclk : 1; /* SPI SCLK for flashmemory => D3 */
unsigned int8 mem_spi_mosi : 1; /* SPI DO to flashmemory => D4 */
unsigned int8 mem_spi_moso : 1; /* SPI DI from flashmemory => D5 */
unsigned int8 nina_txd : 1; /* RX from Nina module => D6 */
unsigned int8 nina_cts : 1; /* CTS to Nina module => D7 */
unsigned int8 acc_spi_cs : 1; /* CS for Acc.meter => D8 */
unsigned int8 sht_i2c_sda : 1; /* I2C bus for SHT31 => D9 */
unsigned int8 sht_i2c_scl : 1; /* I2C bus for SHT31 => D10 */
unsigned int8 acc_spi_sclk : 1; /* SPI SCLK for Acc.meter => D11 */
unsigned int8 not_used : 4; /* not used pins => D12-D15 */
};
struct port_d_layout port_d;
#byte port_d = 0x69C
struct port_d_layout const port_d_for_io = {0,0,0,0,0,1,1,0,0,0,0,0,0xf};
/**************************
*** PORT E definitions ***
**************************/
struct port_e_layout {
unsigned int8 nina_dsr : 1; /* DSR to Nina module => E0 */
unsigned int8 mem_wp : 1; /* WP signal to flashmemory => E1 */
unsigned int8 mem_hold : 1; /* HOLD signal to flashmemory => E2 */
unsigned int8 charge_status : 1; /* Charge_status input => E3 */
unsigned int8 co2_dig_out : 1; /* Dig. OUT from CO2 sensor => E4 */
unsigned int8 dio_0 : 1; /* Digital in/out => E5 */
unsigned int8 i2c_scl : 1; /* Extension I2C Bus => E6 */
unsigned int8 i2c_sda : 1; /* Extension I2C Bus => E7 */
unsigned int8 not_used : 8; /* not used pins => D12-D15 */
};
struct port_e_layout port_e;
#byte port_e = 0x6B0
struct port_e_layout const port_e_for_io = {0,0,0,1,1,0,0,0,0xff};
/**************************
*** PORT F definitions ***
**************************/
struct port_f_layout {
unsigned int8 nina_rts : 1; /* RTS from Nina module => F0 */
unsigned int8 nina_dtr : 1; /* DTR from Nina module => F1 */
unsigned int8 not_used1 : 1; /* not used pin => F2 */
unsigned int8 sensors_power : 1; /* Power for sensors => F3 */
unsigned int8 i2c_sda1 : 1; /* I2C Bus 1 => F4 */
unsigned int8 i2c_scl1 : 1; /* I2C Bus 1 => F5 */
unsigned int8 not_used2 : 1; /* not used pin => F6 */
unsigned int8 Vusb : 1; /* USB power input => F7 */
unsigned int8 not_used3 : 8; /* not used pins => F8-F15 */
};
struct port_f_layout port_f;
#byte port_f = 0x6C4
struct port_f_layout const port_f_for_io = {1,1,1,0,0,0,1,1,0xf};
/**************************
*** PORT G definitions ***
**************************/
struct port_g_layout {
unsigned int8 not_used1 : 2; /* not used pins => G0-G1 */
unsigned int8 usb_dp : 1; /* USB DP input => G2 */
unsigned int8 usb_dm : 1; /* USB DM input => G3 */
unsigned int8 not_used2 : 2; /* not used pins => G4-G5 */
unsigned int8 _5V_enable : 1; /* 5V enable pin => G6 */
unsigned int8 acc_spi_moso : 1; /* SPI DI from Acc.meter => G7 */
unsigned int8 acc_int1 : 1; /* INT1 from Acc.meter => G8 */
unsigned int8 sht_alert : 1; /* Alert signal from SHT31 => G9 */
unsigned int8 not_used3 : 6; /* not used pins => G10-G15 */
};
struct port_g_layout port_g;
#byte port_g = 0x6D8
struct port_g_layout const port_g_for_io = {3,1,1,3,0,1,1,1,0x3f};
int8 current_day[7][10] = {"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
};
rtc_time_t act_time;
#INT_TIMER1
void timer1_isr(void)
{
}
#INT_RTC
void rtc_isr(void)
{
}
void main()
{
setup_timer1(TMR_INTERNAL | TMR_DIV_BY_256, 15625); /* every 1 second */
setup_adc_ports(sAN4, VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL | ADC_TAD_MUL_0);
setup_rtc(RTC_ENABLE | RTC_CLOCK_INTERNAL | RTC_CLK_DIV_BY_256,7836);
setup_rtc_alarm(RTC_ALARM_ENABLE,RTC_ALARM_10_SECONDS, 0xFF);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_RTC);
enable_interrupts(INTR_GLOBAL);
set_tris_b((int16)port_b_for_io);
set_tris_c((int16)port_c_for_io);
set_tris_d((int16)port_d_for_io);
set_tris_e((int16)port_e_for_io);
set_tris_f((int16)port_f_for_io);
set_tris_g((int16)port_g_for_io);
act_time.tm_year=17;
act_time.tm_mon=10;
act_time.tm_mday=27;
act_time.tm_wday=5;
act_time.tm_hour=9;
act_time.tm_min=2;
act_time.tm_sec=0;
rtc_write(&act_time);
fprintf(UART_PORT,"Program is started...\r\n");
while(TRUE) {
restart_wdt();
rtc_read(&act_time);
fprintf(UART_PORT, "%s %02u/%02u/20%02u %02u:%02u:%02u \r\n",current_day[act_time.tm_wday],act_time.tm_mday,act_time.tm_mon,act_time.tm_year,act_time.tm_hour,act_time.tm_min,act_time.tm_sec);
delay_ms(50);
disable_interrupts(INTR_GLOBAL);
enable_interrupts(INT_RTC);
clear_interrupt(INT_RTC);
sleep(SLEEP_FULL);
delay_cycles(1);
fprintf(UART_PORT,"Wakeup from sleep...\r\n");
delay_ms(50);
}
} |
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Fri Oct 27, 2017 8:07 am |
|
|
1st thought.
Have you actually got the RTC enabled? I don't use that PIC, but I'd like to see a small program that displays the RTC time say every second...
main()
{
display rtc time
delay_ms(1000)
}
a simple program, no interrupts, just read and display rtc data.
2nd thought..
get rid of WDT. It shouldn't be enabled until your product is ready to be shipped.
3rd thought..
if running through an ICD, several fuses and registers will NOT be correct.....you need to run in 'release' mode.
Jay |
|
|
JMarysse
Joined: 27 Oct 2017 Posts: 9
|
|
Posted: Fri Oct 27, 2017 12:41 pm |
|
|
Hi temtronic,
Thanks for your answer.
1. if i don't use the sleep function, the RTC is running well.
2. if i disable the WDT, then the PIC does NOT wakeup anymore
3. i use the PicKit3. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19543
|
|
Posted: Fri Oct 27, 2017 2:41 pm |
|
|
That it doesn't wake without the watchdog, tells you this is waking the chip.
You have 1mSec selected as the clock (32 prescaler), and 4096 selected as the divider. So the watchdog timeout is 4.096 seconds. Exactly what you are seeing.....
Obviously you need the watchdog to be set longer than the RTC timeout.
Then start by testing the RTC with the chip awake. Does the alarm trigger?.
I think you will find you have the RTC running much slower than you want. You are using a divider or 7837 * 256 = 2006272. You are meant to select the division to give 2Hz. You are running off 31KHz, so want 15500. So your 10 second alarm will trigger at about 1290 seconds..... |
|
|
JMarysse
Joined: 27 Oct 2017 Posts: 9
|
|
Posted: Sat Oct 28, 2017 1:49 am |
|
|
Hi Ttelmah,
Thank you for this info!
I will check/change this on Monday and keep you informed.
Have a nice weekend. |
|
|
JMarysse
Joined: 27 Oct 2017 Posts: 9
|
|
Posted: Mon Oct 30, 2017 4:01 am |
|
|
Hi Ttelmah,
I did 2 tests:
=> 1 with rtc_int routine
=> 1 with sleep.
The result is that in test 1 the RTC is running perfect, in test 2 it is indeed very slow...and is also it is the WD which is waking the device after 16 seconds.
Can not see why this happens, please help.
This is the code:
main.h
Code: |
#include <24FJ64GB406.h>
#device ADC=12
#device ICSP=1
#use delay(internal=8000000)
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOJTAG //JTAG disabled
/* UART6 */
#use rs232(xmit=PIN_B7, rcv=PIN_B12, baud=19200, stream=UART_PORT)
main.c
#include "main.h"
/**************************
*** PORT B definitions ***
**************************/
struct port_b_layout {
unsigned int8 pged : 1; /* For Debuger => B0 */
unsigned int8 pgec : 1; /* For Debugger => B1 */
unsigned int8 i2c_scl3 : 1; /* I2C Bus 3 => B2 */
unsigned int8 i2c_sda3 : 1; /* I2C Bus 3 => B3 */
unsigned int8 co2_input : 1; /* Analog input from CO2 sensor => B4 */
unsigned int8 i2c_sda2 : 1; /* I2C Bus 2 => B5 */
unsigned int8 i2c_scl2 : 1; /* I2C Bus 2 => B6 */
unsigned int8 db_uart_tx : 1; /* TX for Debugging => B7 */
unsigned int8 tsic_1 : 1; /* TSIC716_1 input => B8 */
unsigned int8 tsic_2 : 1; /* TSIC716_2 input => B9 */
unsigned int8 dio_7 : 1; /* Digital in/out => B10 */
unsigned int8 dio_8 : 1; /* Digital in/out => B11 */
unsigned int8 db_uart_rx : 1; /* RX for Debugging B12 */
unsigned int8 dio_9 : 1; /* Digital in/out => B13 */
unsigned int8 i2c_sda4 : 1; /* I2C Bus 4 => B14 */
unsigned int8 i2c_scl4 : 1; /* I2C Bus 4 => B15 */
};
struct port_b_layout port_b;
#byte port_b = 0x674
struct port_b_layout const port_b_for_io = {1,1,0,0,1,0,0,0,1,1,0,0,1,0,0,0};
/**************************
*** PORT C definitions ***
**************************/
struct port_c_layout {
unsigned int8 not_used : 12; /* not used pins => C0-C11 */
unsigned int8 dio_4 : 1; /* Digital in/out => C12 */
unsigned int8 dio_3 : 1; /* Digital in/out => C13 */
unsigned int8 acc_int2 : 1; /* INT2 from Acc.meter => C14 */
unsigned int8 dio_5 : 1; /* Digital in/out => C15 */
};
struct port_c_layout port_c;
#byte port_c = 0x688
struct port_c_layout const port_c_for_io = {0xfff,0,0,1,0};
/**************************
*** PORT D definitions ***
**************************/
struct port_d_layout {
unsigned int8 acc_spi_mosi : 1; /* SPI DO to Acc.meter => D0 */
unsigned int8 nina_rxd : 1; /* TX to Nina module => D1 */
unsigned int8 mem_spi_cs : 1; /* SPI CS for flashmemory=> D2 */
unsigned int8 mem_spi_sclk : 1; /* SPI SCLK for flashmemory => D3 */
unsigned int8 mem_spi_mosi : 1; /* SPI DO to flashmemory => D4 */
unsigned int8 mem_spi_moso : 1; /* SPI DI from flashmemory => D5 */
unsigned int8 nina_txd : 1; /* RX from Nina module => D6 */
unsigned int8 nina_cts : 1; /* CTS to Nina module => D7 */
unsigned int8 acc_spi_cs : 1; /* CS for Acc.meter => D8 */
unsigned int8 sht_i2c_sda : 1; /* I2C bus for SHT31 => D9 */
unsigned int8 sht_i2c_scl : 1; /* I2C bus for SHT31 => D10 */
unsigned int8 acc_spi_sclk : 1; /* SPI SCLK for Acc.meter => D11 */
unsigned int8 not_used : 4; /* not used pins => D12-D15 */
};
struct port_d_layout port_d;
#byte port_d = 0x69C
struct port_d_layout const port_d_for_io = {0,0,0,0,0,1,1,0,0,0,0,0,0xf};
/**************************
*** PORT E definitions ***
**************************/
struct port_e_layout {
unsigned int8 nina_dsr : 1; /* DSR to Nina module => E0 */
unsigned int8 mem_wp : 1; /* WP signal to flashmemory => E1 */
unsigned int8 mem_hold : 1; /* HOLD signal to flashmemory => E2 */
unsigned int8 charge_status : 1; /* Charge_status input => E3 */
unsigned int8 co2_dig_out : 1; /* Dig. OUT from CO2 sensor => E4 */
unsigned int8 dio_0 : 1; /* Digital in/out => E5 */
unsigned int8 i2c_scl : 1; /* Extension I2C Bus => E6 */
unsigned int8 i2c_sda : 1; /* Extension I2C Bus => E7 */
unsigned int8 not_used : 8; /* not used pins => D12-D15 */
};
struct port_e_layout port_e;
#byte port_e = 0x6B0
struct port_e_layout const port_e_for_io = {0,0,0,1,1,0,0,0,0xff};
/**************************
*** PORT F definitions ***
**************************/
struct port_f_layout {
unsigned int8 nina_rts : 1; /* RTS from Nina module => F0 */
unsigned int8 nina_dtr : 1; /* DTR from Nina module => F1 */
unsigned int8 not_used1 : 1; /* not used pin => F2 */
unsigned int8 sensors_power : 1; /* Power for sensors => F3 */
unsigned int8 i2c_sda1 : 1; /* I2C Bus 1 => F4 */
unsigned int8 i2c_scl1 : 1; /* I2C Bus 1 => F5 */
unsigned int8 not_used2 : 1; /* not used pin => F6 */
unsigned int8 Vusb : 1; /* USB power input => F7 */
unsigned int8 not_used3 : 8; /* not used pins => F8-F15 */
};
struct port_f_layout port_f;
#byte port_f = 0x6C4
struct port_f_layout const port_f_for_io = {1,1,1,0,0,0,1,1,0xf};
/**************************
*** PORT G definitions ***
**************************/
struct port_g_layout {
unsigned int8 not_used1 : 2; /* not used pins => G0-G1 */
unsigned int8 usb_dp : 1; /* USB DP input => G2 */
unsigned int8 usb_dm : 1; /* USB DM input => G3 */
unsigned int8 not_used2 : 2; /* not used pins => G4-G5 */
unsigned int8 _5V_enable : 1; /* 5V enable pin => G6 */
unsigned int8 acc_spi_moso : 1; /* SPI DI from Acc.meter => G7 */
unsigned int8 acc_int1 : 1; /* INT1 from Acc.meter => G8 */
unsigned int8 sht_alert : 1; /* Alert signal from SHT31 => G9 */
unsigned int8 not_used3 : 6; /* not used pins => G10-G15 */
};
struct port_g_layout port_g;
#byte port_g = 0x6D8
struct port_g_layout const port_g_for_io = {3,1,1,3,0,1,1,1,0x3f};
int8 current_day[7][10] = {"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
};
rtc_time_t act_time;
unsigned int8 rtc_int = 0;
#INT_RTC
void rtc_isr(void)
{
rtc_int = 1;
}
void main()
{
setup_rtc(RTC_ENABLE | RTC_CLOCK_INTERNAL | RTC_CLK_DIV_BY_256,7836);
setup_rtc_alarm(RTC_ALARM_ENABLE,RTC_ALARM_10_SECONDS, 0xFF);
setup_wdt(WDT_16S);
enable_interrupts(INT_RTC);
enable_interrupts(INTR_GLOBAL);
set_tris_b((int16)port_b_for_io);
set_tris_c((int16)port_c_for_io);
set_tris_d((int16)port_d_for_io);
set_tris_e((int16)port_e_for_io);
set_tris_f((int16)port_f_for_io);
set_tris_g((int16)port_g_for_io);
act_time.tm_year=17;
act_time.tm_mon=10;
act_time.tm_mday=30;
act_time.tm_wday=1;
act_time.tm_hour=10;
act_time.tm_min=15;
act_time.tm_sec=0;
rtc_write(&act_time);
fprintf(UART_PORT,"Program is started...\r\n");
fprintf(UART_PORT, "%s %02u/%02u/20%02u %02u:%02u:%02u \r\n",current_day[act_time.tm_wday],act_time.tm_mday,act_time.tm_mon,act_time.tm_year,act_time.tm_hour,act_time.tm_min,act_time.tm_sec);
// Test with rtc_int every 10 seconds
/* while(TRUE) {
if (rtc_int) {
restart_wdt();
rtc_int = 0;
rtc_read(&act_time);
fprintf(UART_PORT, "%s %02u/%02u/20%02u %02u:%02u:%02u \r\n",current_day[act_time.tm_wday],act_time.tm_mday,act_time.tm_mon,act_time.tm_year,act_time.tm_hour,act_time.tm_min,act_time.tm_sec);
delay_ms(50);
}
}
}
*/
/*
RESULT WITH RTC_INT :
Program is started...
Monday 30/10/2017 10:15:00
Monday 30/10/2017 10:15:10
Monday 30/10/2017 10:15:20
Monday 30/10/2017 10:15:30
Monday 30/10/2017 10:15:40
Monday 30/10/2017 10:15:50
Monday 30/10/2017 10:16:00
Monday 30/10/2017 10:16:10
Monday 30/10/2017 10:16:20
*/
// Test with rtc_int every 10 seconds, BUT IN SLEEP
while(TRUE) {
restart_wdt();
rtc_read(&act_time);
fprintf(UART_PORT, "%s %02u/%02u/20%02u %02u:%02u:%02u \r\n",current_day[act_time.tm_wday],act_time.tm_mday,act_time.tm_mon,act_time.tm_year,act_time.tm_hour,act_time.tm_min,act_time.tm_sec);
delay_ms(50);
sleep(SLEEP_FULL);
delay_cycles(1);
fprintf(UART_PORT,"Wakeup from sleep...\r\n");
delay_ms(50);
}
}
/*
RESULT WITH RTC_INT from SLEEP :
Program is started...
Monday 30/10/2017 10:15:00
Monday 30/10/2017 10:15:00
Wakeup from sleep...
Monday 30/10/2017 10:15:00
Wakeup from sleep...
Monday 30/10/2017 10:15:00
Wakeup from sleep...
Monday 30/10/2017 10:15:00
Wakeup from sleep...
Monday 30/10/2017 10:15:00
Wakeup from sleep...
Monday 30/10/2017 10:15:00
Wakeup from sleep...
Monday 30/10/2017 10:15:00
Wakeup from sleep...
Monday 30/10/2017 10:15:00
Wakeup from sleep...
Monday 30/10/2017 10:15:00
Wakeup from sleep...
Monday 30/10/2017 10:15:01
Wakeup from sleep...
Monday 30/10/2017 10:15:01
Wakeup from sleep...
Monday 30/10/2017 10:15:01
Wakeup from sleep...
Monday 30/10/2017 10:15:01
Wakeup from sleep...
Monday 30/10/2017 10:15:01
Wakeup from sleep...
Monday 30/10/2017 10:15:01
Wakeup from sleep...
Monday 30/10/2017 10:15:01
Wakeup from sleep...
Monday 30/10/2017 10:15:01
Wakeup from sleep...
Monday 30/10/2017 10:15:02
Wakeup from sleep...
Monday 30/10/2017 10:15:02
*/ |
|
|
|
JMarysse
Joined: 27 Oct 2017 Posts: 9
|
|
Posted: Mon Oct 30, 2017 4:39 am |
|
|
Hi Ttelmah,
The problem is solved.
I did not read your mail very well (monday morning...)
I changed the following line :
Code: |
setup_rtc(RTC_ENABLE | RTC_CLOCK_INTERNAL | RTC_CLK_DIV_BY_256,7836); | with :
Code: | setup_rtc(RTC_ENABLE | RTC_CLOCK_LPRC, 15500); |
The clock is running correct now.
Thanks for your help. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1355
|
|
Posted: Mon Oct 30, 2017 7:59 am |
|
|
The key there is you need an oscillator that can run while the chip sleeps. The traditional internal oscillator does not. The LPRC will (on chips that have it) but usually it is very bad tolerance (Upwards of + or - 15% on some chips). I would normally recommend using an external oscillator tied to an asynchronous timer input. Normally for PIC24's this is timer 1, though I haven't checked your chip's datasheet.
If your LPRC has good enough tolerance then it isn't an issue though. Just make sure you check the datasheet to be sure. |
|
|
JMarysse
Joined: 27 Oct 2017 Posts: 9
|
|
Posted: Tue Oct 31, 2017 3:50 am |
|
|
New question : we need to communicate with a NINA-B112 module trough the UART.
Problem is that the modules uart is default set at 115200.
We use the INTERNAL 8Mhz osc and the compiler does NOT allow 115200 baud.
All comment/help is welcome. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19543
|
|
Posted: Tue Oct 31, 2017 5:21 am |
|
|
You need to be clocking faster.
From 8MHz, there just aren't enough clock cycles available to get reasonably serial accuracy at this rate.
If you look in the data sheet, they give how to calculate the error. In this case:
(remember the UART is clocked off FOSC/2)
U1BRG = ((4000000/115200)/4)-1 = 7
Baud = 4000000/(4*8) = 125000
Error = (125000-115200)/115200 = 0.085
8.5%
The maximum total error on a async link should be kept below perhaps 3%. The compiler will reject any setup that results in such a large error.
Using 16Mhz.
U1BRG = 16
Baud = 117647
Error = 0.0212
2.1%
Still not 'great', but close enough that it has a chance of working.
There is an option 'BRGH1OK', that on older chips allowed the /4 division (shown) to be used, but on PIC24's this is automatically selected, so this won't help (the calculation above is using this). |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Tue Oct 31, 2017 7:32 am |
|
|
The 'other' problem with using an internal clock even IF it is fast enough, has to do with temperature. You need to read the datasheet for your PIC and decide IF the clock will be within 'spec' for the temperature range your product will see. Often it's just OK, on the bench, in a warm building BUT put into an industrial/commercial site where the temperature drops, say due to setback thermostats or it gets really, really hot in the summer and the internal clock may easily go out of the 'OK' range.
Older PICs had a wide 'range' for say '4 MHz', some newer PICs are better and some 'families' are better yet so you MUST read the datasheet !
To get accurate, high speed (115K200) operation from most PICs you need an external clock, xtal and caps or canned xtal.
Jay |
|
|
JMarysse
Joined: 27 Oct 2017 Posts: 9
|
|
Posted: Tue Oct 31, 2017 7:44 am |
|
|
Hello,
Thanks for your replies!
So we will need to add an external xtal.
No way to do it with the 8 MHz internal one, not even if using the PLL? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Tue Oct 31, 2017 7:54 am |
|
|
you need to download the datasheet and read the section on 'clock selection'.
I did a quik read and it may be possible to use the internal FRC with e PLL and get 64MHz operation.
Since I don't have that PIC I can't cut code/compile and test.
Try it...
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19543
|
|
Posted: Tue Oct 31, 2017 7:57 am |
|
|
Key point to understand is that errors 'add up' in the worst case. Yes you can run at 16MHz off the internal oscillator. It'll then work, but the error will be 2.1% from the baud rate calculations, and potentially +/-1% from the oscillator. This may well give you problems. Go up to 32Mhz from the internal oscillator, and the baud error will drop to only a fraction of a percent, and it should work OK, but will be drawing a lot more power. You have been using sleep, which potentially implies low power is required?. If so, then look at an external crystal like 7.3728MHz. This will divide to give 115200bps _exactly_, and your baud accuracy will be limited just by the accuracy of the crystal. |
|
|
JMarysse
Joined: 27 Oct 2017 Posts: 9
|
|
Posted: Tue Oct 31, 2017 8:10 am |
|
|
Hi Ttelmah, temtronic,
I just made it work by indeed setting the fuses FRC_PLL and PLL2, and set the "use delay(clock=32M,internal,restart_wdt).
But you both are correct, we will need to redesign and use an external crystal.
Also "low power" will be needed because the system is to be used as a standalone data logger (4 MLX90614 sensors, 2 TSIC716 sensors, which are already implemented). The power of these sensor is controlled by the pic.
Thanks for your replies! |
|
|
|
|
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
|