Jump to content


Photo

Proiect ARM GPS cu STM32F407 si u-blox neo 6m


This topic has been archived. This means that you cannot reply to this topic.
No replies to this topic

#1 OFFLINE   moro

moro

    Membru avansat

  • Membri
  • PipPipPipPip
  • 1,027 posts

Posted 19 December 2014 - 10:22 PM

Va salut, ma gandeam sa postez un mic proiect pe care l-am inceput prin vara, acesta consta intr-un modul gps ublox neo 6m destul de popular in randul dronelor (quadcopters) si un microcontroler din familia cortex m4, respectiv STM32F407VG

 

Codul este in C, eu am folosit iar  ewarm, dar se poate adapta fara prea mari batai de cap.

 

Mai jos sunt src si .h file pt gps, precum si main program.

lcd_cr si lcd_char  sunt doar functii pt display 4x20 caractere,

 

 

Poate ajuta pe cineva care are nevoie :-)

 

main.c

#include <stm32f4xx.h>
#include <stdint.h>
#include "stm32f4xx_it.h"
#include "stm32f4xx_syscfg.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "system_stm32f4xx.c"
#include "lcd.h"
#include <stdint.h>
#include "misc.h"
#include <math.h>
#include "stdlib.h"
#include "stdio.h"
#include "gps_serial.h"


#define LINEMAX 200
 char line_buffer[LINEMAX + 1]; // Holding buffer with space for terminating NUL
volatile int line_valid = 0;

void USART1_IRQHandler(void)            // Serial com1 (USART1) interrupt handler
{
  static char rx_buffer[LINEMAX];   // Local holding buffer to build line
  static int rx_index = 0;
 
  if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) // Received character?
  { char rx = USART_ReceiveData(USART1);
    
    if ((rx == '\r') || (rx == '\n')) // Is this an end-of-line condition, either will suffice?
    {
      if (rx_index != 0) // Line has some content
      {
        memcpy((void *)line_buffer, rx_buffer, rx_index); // Copy to static line buffer from dynamic receive buffer
        line_buffer[rx_index] = 0; // Add terminating NUL
        line_valid = 1; // flag new line valid for processing
        rx_index = 0; // Reset content pointer
           }
    }
    else
    {
      if ((rx == '$') || (rx_index == LINEMAX)) // If resync or overflows pull back to start
        rx_index = 0;
       rx_buffer[rx_index++] = rx; // Copy to buffer and increment
    }
  }
}


int main(void){ 
  
SystemInit();  // initialize system clocks & stuff
lcd_init();  // initialize lcd & specific lcd ports
gps_serial_init(); // initialize serial com 1 module, and specific gpib for serial com + configure the com1 interrupts


while(1){
 if (line_valid)
    {
      ProcessNMEALine(line_buffer);
      line_valid = 0;
    }
}

 

 

gps_serial.c


#include "gps_serial.h"
#include "stm32f4xx_it.h"
#include "string.h"



void Usart_interrupt_enable(void){

  NVIC_InitTypeDef NVIC_InitStruct;  
  USART_ITConfig(UART_PORT, USART_IT_RXNE, ENABLE); // enable the USART1 receive interrupt
  NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;		 // we want to configure the USART1 interrupts
  NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 6;// this sets the priority group of the USART1 interrupts
  NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;		 // this sets the subpriority inside the group
  NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;			 // the USART1 interrupts are globally enabled
  NVIC_Init(&NVIC_InitStruct);							 // the properties are passed to the NVIC_Init function which takes care of the low level stuff 
 
}




void gps_serial_init(void){

USART_InitTypeDef USART_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct;  
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);  // enable the peripheral  GPIOB port  
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // Enable clock for USART1 

GPIO_InitStruct.GPIO_Pin =   GPIO_RS232_TX | GPIO_RS232_RX ;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;

GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1); // Serial TX
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1); // Serial Rx
GPIO_Init(GPIOB, &GPIO_InitStruct); 

USART_InitStruct.USART_BaudRate = baudrate;				// the baudrate is set to the value we passed into this init function
USART_InitStruct.USART_WordLength = USART_WordLength_8b;// we want the data frame size to be 8 bits (standard)
USART_InitStruct.USART_StopBits = USART_StopBits_1;		// we want 1 stop bit (standard)
USART_InitStruct.USART_Parity = USART_Parity_No;		// we don't want a parity bit (standard)
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // we don't want flow control (standard)
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // we want to enable the transmitter and the receiver
USART_Init(UART_PORT, &USART_InitStruct);					// again all the properties are passed to the USART_Init function which takes care of all the bit setting
Usart_interrupt_enable();     
USART_Cmd(UART_PORT, ENABLE); 
 
}



#define FIELD_MAX 20
 
void ProcessNMEALine(char *s)
{ 
  char *field[FIELD_MAX];
  int f;
  int i;
  char c;
  int x;
 
  // Check the line synchronization
 
  if (s[0] != '$')
    return;
   // Verify the line checksum integrity
   c = 0; // checksum
   i = 1; // Xor bytes between $ and *, but not including those bytes
 
  while((s[i] != 0) && (s[i] != '*'))
    c ^= s[i++];
   if (s[i] == 0)
    return;
   sscanf(&s[i + 1],"%x",&x); // Checksum byte - Note sscanf needs this to be an int, rather than a single byte
   if (c != (char)(x & 0xFF)) // Leave if checksum fails
    return;
   // Parse out fields on , and *
   f = 0;
   while(1) { field[f++] = s;
     while((*s != 0) && (*s != ',') && (*s != '*') && (*s != 0x0D) && (*s != 0x0A))
      s++;
    if ((*s == 0) || (*s == '*') || (*s == 0x0D) || (*s == 0x0A) || (f == (FIELD_MAX - 1)))
    { *s = 0;
      field[f] = NULL;
       break; }
     *s++ = 0;
  }
 
  
 if ((strcmp(field[0],"$GPGGA") == 0) && (f > 14))
{ 
  
 double lat, lon, alt, msl;
  int lat_deg, lon_deg;
  double lat_min, lon_min;
  uint32_t fix_time; //double fix_time;
  int fix_hour, fix_minute;
  double fix_second;
  char lat_hemi, lon_hemi;
  uint8_t valid;
  double hdop;
  int sv;
 
  // Field  1 UTC Time HHMMSS.SSS
  // Field  2 Latitude
  // Field  3 Lat Hemi
  // Field  4 Longitude
  // Field  5 Lon Hemi
  // Field  6 Position Fix Indicator - 0=Fix Not available, 1=GPS SPS, 2=GPS SPS DIFF, 3=GPS PPS,
  //              4=RTK, 5=Float RTK, 6=Estimate/Dead Reckoning, 7=Manual, 8=Simulator
  // Field  7 Satellites Used
  // Field  8 HDOP
  // Field  9 MSL Altitude
  // Field 10 Units M
  // Field 11 Geoid Separation
  // Field 12 Units M
  // Field 13 Age of Differential (NULL when not used)
  // Field 14 Differential Reference Station ID
 
  sscanf(field[2],"%lf",&lat);
  
  lat_hemi = field[3][0];
 // lcd_cr(1,5,lat_hemi);
  
  sscanf(field[4],"%lf",&lon);
 
  lon_hemi = field[5][0];

  
  sscanf(field[9],"%lf",&msl);
  sscanf(field[11],"%lf",&alt);
  
  
 // time
 sscanf(field[1],"%d",&fix_time); //  sscanf(field[1],"%lf",&fix_time);
 char kk1[10];
 sprintf(kk1,"%d", fix_time);

 lcd_char(3,1,"GPS TIME");
 lcd_cr(3,10,kk1[0]);
 lcd_cr(3,11,kk1[1]);
 lcd_char(3,12,":");
 lcd_cr(3,13,kk1[2]);
 lcd_cr(3,14,kk1[3]);
 lcd_char(3,15,":");
 lcd_cr(3,16,kk1[4]);
 lcd_cr(3,17,kk1[5]);
 
 
 /// FIX MODE 
sscanf(field[6],"%d",&valid);
 if(valid!=0){
   if(valid=1){  lcd_char(4,1,"GPS Lock"); }
   if(valid==2){ lcd_char(4,1,"DGPS FIX");}
 } else { lcd_char(4,1,"No GPS FIX"); }

 // COUNT SATELITES IN VIEW
  sscanf(field[7],"%d",&sv);    // Satellites used (or in view, depends on receiver)
  char kku[6];
  sprintf(kku,"%d", sv);
  if(sv!=0){
  lcd_char(4,11,kku);
  } else { lcd_char(4,11, "0");}
  
  sscanf(field[8],"%lf",&hdop); // Horizontal Dilution of precision (HDOP)
 
 // if (valid != 0)
 // {
    lat_deg = (int)lat / 100;
    lat_min = lat - (lat_deg * 100);
    lat = (double)lat_deg + (lat_min / 60.0);
    if (lat_hemi == 'S')
    lat = -lat;
    char crlat[10];
    if(valid!=0){
    sprintf(crlat,"%lf",lat);
    lcd_char(1,1,"Lat:");
    lcd_char(1,6,crlat);
    lcd_cr(1,16, lat_hemi);
    } else {
          lcd_char(1,1,"Lat:");
      lcd_char(1,6, "Not Available");
    }
  
    lon_deg = (int)lon / 100;
    lon_min = lon - (lon_deg * 100);
    lon = (double)lon_deg + (lon_min / 60.0);
    if (lon_hemi == 'W')
    lon = -lon;
    char crlon[10];
    sprintf(crlon,"%lf",lon);
    if(valid!=0){    
    lcd_char(2,1,"Lon:");
    lcd_char(2,6,crlon);
    lcd_cr(2,16, lon_hemi);
    }else {
    lcd_char(2,1,"Lon:");
    lcd_char(2,6, "Not Available");
    }
    
    alt += msl; // Convert to height above datum
   


}}

 

 

 

gps_serial.h 

#include "stm32f4xx_it.h"
#define GPIO_RS232_TX             GPIO_Pin_6
#define GPIO_RS232_RX             GPIO_Pin_7
#define baudrate 9600
#define UART_PORT USART1

void Usart_interrupt_enable(void);
void gps_serial_init(void);



Cu_reclama

Cu_reclama
  • Membri