mirror of
https://github.com/eddyem/stm32samples.git
synced 2025-12-06 10:45:11 +03:00
Add GPS time synchronisation
This commit is contained in:
parent
5932bfe614
commit
589d00fd4e
BIN
GPS/GPS.bin
BIN
GPS/GPS.bin
Binary file not shown.
@ -163,7 +163,6 @@ uint8_t *nextpos(uint8_t **buf, int pos){
|
|||||||
*/
|
*/
|
||||||
void GPS_parse_answer(uint8_t *buf){
|
void GPS_parse_answer(uint8_t *buf){
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
DBG(buf);
|
|
||||||
if(strncmp(buf+3, U("RMC"), 3)){ // not RMC message
|
if(strncmp(buf+3, U("RMC"), 3)){ // not RMC message
|
||||||
GPS_send_start_seq();
|
GPS_send_start_seq();
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -68,7 +68,7 @@ void GPIO_init(){
|
|||||||
*/
|
*/
|
||||||
void SysTick_init(){
|
void SysTick_init(){
|
||||||
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); // Systyck: 72/8=9MHz
|
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); // Systyck: 72/8=9MHz
|
||||||
STK_RVR = 8999; // 9000 pulses: 1kHz
|
STK_RVR = STK_RVR_DEFAULT_VAL; // 9000 pulses: 1kHz
|
||||||
systick_interrupt_enable();
|
systick_interrupt_enable();
|
||||||
systick_counter_enable();
|
systick_counter_enable();
|
||||||
}
|
}
|
||||||
|
|||||||
60
GPS/main.c
60
GPS/main.c
@ -31,6 +31,13 @@ volatile uint32_t systick_val = 0;
|
|||||||
volatile uint32_t timer_val = 0;
|
volatile uint32_t timer_val = 0;
|
||||||
volatile int clear_ST_on_connect = 1;
|
volatile int clear_ST_on_connect = 1;
|
||||||
|
|
||||||
|
volatile int need_sync = 1;
|
||||||
|
|
||||||
|
volatile uint32_t last_corr_time = 0; // time of last PPS correction (seconds from midnight)
|
||||||
|
|
||||||
|
// STK_CVR values for all milliseconds (RVR0) and last millisecond (RVR1)
|
||||||
|
volatile uint32_t RVR0 = STK_RVR_DEFAULT_VAL, RVR1 = STK_RVR_DEFAULT_VAL;
|
||||||
|
|
||||||
curtime current_time = {25,61,61};
|
curtime current_time = {25,61,61};
|
||||||
|
|
||||||
void time_increment(){
|
void time_increment(){
|
||||||
@ -76,6 +83,7 @@ int main(){
|
|||||||
usbdatalen = parce_incoming_buf(usbdatabuf, usbdatalen);
|
usbdatalen = parce_incoming_buf(usbdatabuf, usbdatalen);
|
||||||
}
|
}
|
||||||
if((string = check_UART2())){
|
if((string = check_UART2())){
|
||||||
|
P(string);
|
||||||
GPS_parse_answer(string);
|
GPS_parse_answer(string);
|
||||||
}
|
}
|
||||||
if(systick_val){
|
if(systick_val){
|
||||||
@ -84,6 +92,10 @@ int main(){
|
|||||||
systick_val = 0;
|
systick_val = 0;
|
||||||
P(", timer value: ");
|
P(", timer value: ");
|
||||||
print_int(timer_val);
|
print_int(timer_val);
|
||||||
|
P(", RVR0 = ");
|
||||||
|
print_int(RVR0);
|
||||||
|
P(", RVR1 = ");
|
||||||
|
print_int(RVR1);
|
||||||
P("\n");
|
P("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,7 +106,11 @@ int main(){
|
|||||||
* SysTick interrupt: increment global time & send data buffer through USB
|
* SysTick interrupt: increment global time & send data buffer through USB
|
||||||
*/
|
*/
|
||||||
void sys_tick_handler(){
|
void sys_tick_handler(){
|
||||||
if(++Timer == 1000){
|
++Timer;
|
||||||
|
if(Timer == 999){
|
||||||
|
STK_RVR = RVR1;
|
||||||
|
}else if(Timer == 1000){
|
||||||
|
STK_RVR = RVR0;
|
||||||
time_increment();
|
time_increment();
|
||||||
}
|
}
|
||||||
usb_send_buffer();
|
usb_send_buffer();
|
||||||
@ -102,17 +118,50 @@ void sys_tick_handler(){
|
|||||||
// STK_CVR - current systick val
|
// STK_CVR - current systick val
|
||||||
// STK_RVR - ticks till interrupt - 1
|
// STK_RVR - ticks till interrupt - 1
|
||||||
|
|
||||||
// PA4 interrupt
|
// PA4 interrupt - PPS signal
|
||||||
void exti4_isr(){
|
void exti4_isr(){
|
||||||
|
uint32_t t = 0, ticks;
|
||||||
|
static uint32_t ticksavr = 0, N = 0;
|
||||||
if(EXTI_PR & EXTI4){
|
if(EXTI_PR & EXTI4){
|
||||||
// correct
|
// correct
|
||||||
systick_val = STK_CVR;
|
systick_val = STK_CVR;
|
||||||
|
STK_CVR = RVR0;
|
||||||
|
systick_val = RVR0 + 1 - systick_val; // Systick counts down!
|
||||||
timer_val = Timer;
|
timer_val = Timer;
|
||||||
|
Timer = 0;
|
||||||
|
if(timer_val < 10) timer_val += 1000; // our closks go faster than real
|
||||||
|
else if(timer_val < 990){ // something wrong
|
||||||
|
RVR0 = RVR1 = STK_RVR_DEFAULT_VAL;
|
||||||
|
STK_RVR = RVR0;
|
||||||
|
need_sync = 1;
|
||||||
|
goto theend;
|
||||||
|
}else
|
||||||
|
time_increment(); // ms counter less than 1000 - we need to increment time
|
||||||
|
t = current_time.H * 3600 + current_time.M * 60 + current_time.S;
|
||||||
if(clear_ST_on_connect){
|
if(clear_ST_on_connect){
|
||||||
STK_CVR = 0;
|
|
||||||
clear_ST_on_connect = 0;
|
clear_ST_on_connect = 0;
|
||||||
time_increment();
|
}else{
|
||||||
|
// || (last_corr_time == 86399 && t == 0)
|
||||||
|
if(t - last_corr_time == 1){ // PPS interval == 1s
|
||||||
|
ticks = systick_val + timer_val*(RVR0 + 1);
|
||||||
|
++N;
|
||||||
|
ticksavr += ticks;
|
||||||
|
if(N > 20){
|
||||||
|
ticks = ticksavr / N;
|
||||||
|
RVR0 = ticks / 1000 - 1; // main RVR value
|
||||||
|
STK_RVR = RVR0;
|
||||||
|
RVR1 = RVR0 + ticks % 1000 - 1; // last millisecond RVR value (with fine correction)
|
||||||
|
N = 0;
|
||||||
|
ticksavr = 0;
|
||||||
|
need_sync = 0;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
N = 0;
|
||||||
|
ticksavr = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
theend:
|
||||||
|
last_corr_time = t;
|
||||||
EXTI_PR = EXTI4;
|
EXTI_PR = EXTI4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,7 +180,7 @@ void set_time(uint8_t *buf){
|
|||||||
inline uint8_t atou(uint8_t *b){
|
inline uint8_t atou(uint8_t *b){
|
||||||
return (b[0]-'0')*10 + b[1]-'0';
|
return (b[0]-'0')*10 + b[1]-'0';
|
||||||
}
|
}
|
||||||
uint8_t H = atou(buf) + 3;
|
uint8_t H = atou(buf) + TIMEZONE_GMT_PLUS;
|
||||||
if(H > 23) H -= 24;
|
if(H > 23) H -= 24;
|
||||||
current_time.H = H;
|
current_time.H = H;
|
||||||
current_time.M = atou(&buf[2]);
|
current_time.M = atou(&buf[2]);
|
||||||
@ -156,6 +205,7 @@ void print_curtime(){
|
|||||||
if(T < 10) usb_send('0');
|
if(T < 10) usb_send('0');
|
||||||
print_int(T);
|
print_int(T);
|
||||||
if(GPS_status == GPS_NOT_VALID) P(" (not valid)");
|
if(GPS_status == GPS_NOT_VALID) P(" (not valid)");
|
||||||
|
if(need_sync) P(" need synchronisation");
|
||||||
newline();
|
newline();
|
||||||
}else
|
}else
|
||||||
P("Waiting for satellites\n");
|
P("Waiting for satellites\n");
|
||||||
|
|||||||
@ -49,6 +49,9 @@ extern void *memcpy(void *dest, const void *src, int n);
|
|||||||
#define U16(x) ((uint16_t) x)
|
#define U16(x) ((uint16_t) x)
|
||||||
#define U32(x) ((uint32_t) x)
|
#define U32(x) ((uint32_t) x)
|
||||||
|
|
||||||
|
#define STK_RVR_DEFAULT_VAL (8999)
|
||||||
|
#define TIMEZONE_GMT_PLUS (3)
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
uint8_t H;
|
uint8_t H;
|
||||||
uint8_t M;
|
uint8_t M;
|
||||||
@ -59,6 +62,8 @@ extern curtime current_time;
|
|||||||
extern volatile uint32_t Timer; // global timer (milliseconds)
|
extern volatile uint32_t Timer; // global timer (milliseconds)
|
||||||
extern volatile int clear_ST_on_connect; // flag for clearing Systick counter on next PPS
|
extern volatile int clear_ST_on_connect; // flag for clearing Systick counter on next PPS
|
||||||
|
|
||||||
|
extern volatile int need_sync;
|
||||||
|
|
||||||
void Delay(uint16_t time);
|
void Delay(uint16_t time);
|
||||||
void set_time(uint8_t *buf);
|
void set_time(uint8_t *buf);
|
||||||
|
|
||||||
|
|||||||
@ -258,6 +258,7 @@ void fill_uart_RXbuff(uint32_t UART, uint8_t byte){
|
|||||||
}
|
}
|
||||||
curbuff = &RX_buffer[bufidx];
|
curbuff = &RX_buffer[bufidx];
|
||||||
if(curbuff->end == UART_BUF_DATA_SIZE){ // end of buffer - forget about data
|
if(curbuff->end == UART_BUF_DATA_SIZE){ // end of buffer - forget about data
|
||||||
|
curbuff->end = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
curbuff->buf[curbuff->end++] = byte; // put byte into buffer
|
curbuff->buf[curbuff->end++] = byte; // put byte into buffer
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user