Sari la conținut
ELFORUM - Forumul electronistilor

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


moro

Postări Recomandate

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 NULvolatile 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 & stufflcd_init();  // initialize lcd & specific lcd portsgps_serial_init(); // initialize serial com 1 module, and specific gpib for serial com + configure the com1 interruptswhile(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 TXGPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1); // Serial RxGPIO_Init(GPIOB, &GPIO_InitStruct); USART_InitStruct.USART_BaudRate = baudrate;				// the baudrate is set to the value we passed into this init functionUSART_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 receiverUSART_Init(UART_PORT, &USART_InitStruct);					// again all the properties are passed to the USART_Init function which takes care of all the bit settingUsart_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 USART1void Usart_interrupt_enable(void);void gps_serial_init(void);
Link spre comentariu

Alătură-te conversației

Poți posta acum și să te înregistrezi mai târziu. Dacă ai un cont, autentifică-te acum pentru a posta cu contul tău.
Notă: Postarea ta va necesita aprobare moderator înainte de a fi vizibilă.

Vizitator
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Răspunde la acest subiect...

×   Alipit ca text avansat.   Restituie formatare

  Doar 75 emoji sunt permise.

×   Linkul tău a fost încorporat automat.   Afișează ca link în schimb

×   Conținutul tău precedent a fost resetat.   Curăță editor

×   Nu poți lipi imagini direct. Încarcă sau inserează imagini din URL.




×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări