From 564de1dab20a920317dfa7f2869cb4d30affbafe Mon Sep 17 00:00:00 2001 From: aixiao Date: Mon, 25 Mar 2024 15:05:38 +0800 Subject: [PATCH] init --- .gitignore | 2 + CMakeLists.txt | 39 +++++++++++++ EC800M.c | 116 +++++++++++++++++++++++++++++++++++++++ EC800M.h | 21 +++++++ README.md | 25 +++++++++ main.c | 85 ++++++++++++++++++++++++++++ main.h | 10 ++++ pico_extras_import.cmake | 62 +++++++++++++++++++++ pico_sdk_import.cmake | 62 +++++++++++++++++++++ 9 files changed, 422 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 EC800M.c create mode 100644 EC800M.h create mode 100644 README.md create mode 100644 main.c create mode 100644 main.h create mode 100644 pico_extras_import.cmake create mode 100644 pico_sdk_import.cmake diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9ef9604 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..9f4253e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 3.25.1) +include(pico_sdk_import.cmake) +include(pico_extras_import.cmake) +project(main CXX C ASM) +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) +pico_sdk_init() + + + +add_executable( + main + EC800M.c + main.c +) + + +pico_enable_stdio_uart(main 1) +pico_enable_stdio_usb(main 1) +pico_add_extra_outputs(main) + +target_include_directories(main PRIVATE + ${CMAKE_CURRENT_LIST_DIR} + ) + +target_link_libraries( + main + pico_stdlib + pico_runtime + pico_multicore + hardware_sleep + hardware_rtc + hardware_i2c + hardware_uart + hardware_pwm + hardware_adc + hardware_pio +) + diff --git a/EC800M.c b/EC800M.c new file mode 100644 index 0000000..54b3296 --- /dev/null +++ b/EC800M.c @@ -0,0 +1,116 @@ +#include "EC800M.h" + +char GPSDATA[GPSDATA_LENGTH]; +int GPSDATA_LEN; + +void uart_send_string(const char *str) +{ + size_t len = strlen(str); + uart_write_blocking(GPS_UART, (const uint8_t *)str, len); +} + +void uart_read_string() +{ + while (uart_is_readable(GPS_UART)) { + char c = uart_getc(GPS_UART); + + if (GPSDATA_LEN < GPSDATA_LENGTH - 1) { + GPSDATA[GPSDATA_LEN++] = c; + GPSDATA[GPSDATA_LEN] = '\0'; + } + + sleep_ms(1); + } +} + +void uart_read_string_until_response(const char *expected_response) +{ + int response_len = strlen(expected_response); + char response_buffer[1024]; // 假设响应不会超过 100 个字符 + + int i = 0; + while (1) { + while (uart_is_readable(GPS_UART)) { + char c = uart_getc(GPS_UART); + GPSDATA[i++] = c; + GPSDATA[i] = '\0'; // 添加字符串结束符 + if (strstr(GPSDATA, expected_response) != NULL) { + return; // 找到了预期的响应,退出循环 + } + } + sleep_ms(1); // 等待一小段时间再继续读取 + } +} + +// 重置数据缓冲区 +void reset_data() +{ + memset(GPSDATA, 0, GPSDATA_LENGTH); + GPSDATA_LEN = 0; +} + +int EC800M_INIT() +{ + uart_init(GPS_UART, 2400); + gpio_set_function(9, GPIO_FUNC_UART); // UART1_TX + gpio_set_function(8, GPIO_FUNC_UART); // UART1_RX + int __unused actual = uart_set_baudrate(GPS_UART, GPS_UART_BAUD_RATE); + uart_set_hw_flow(GPS_UART, false, false); + uart_set_format(GPS_UART, 8, 1, UART_PARITY_NONE); + //uart_set_fifo_enabled(GPS_UART, false); + + uart_send_string("AT+QGPSCFG=\"outport\",\"uartdebug\"\r\n"); + sleep_ms(100); + uart_read_string(); + + uart_send_string("AT+QGPSCFG=\"nmeasrc\",1\r\n"); + sleep_ms(100); + uart_read_string(); + + uart_send_string("AT+QGPSCFG=\"gpsnmeatype\",63\r\n"); + sleep_ms(100); + uart_read_string(); + + uart_send_string("AT+QGPSCFG=\"gnssconfig\",1\r\n"); + sleep_ms(100); + uart_read_string(); + + uart_send_string("AT+QGPSCFG=\"autogps\",0\r\n"); + sleep_ms(100); + uart_read_string(); + + uart_send_string("AT+QGPSCFG=\"apflash\",0\r\n"); + sleep_ms(100); + uart_read_string(); + + uart_send_string("AT+QGPS=1\r\n"); + sleep_ms(100); + uart_read_string(); + + // 打印第一次初始化输出 + printf("%s %d\n", GPSDATA, strlen(GPSDATA)); + + return 0; +} + +char *EC800M() +{ + uart_send_string("AT+QGPSLOC=0\r\n"); + uart_read_string_until_response("OK"); + sleep_ms(100); + //printf("%s %d\n", GPSDATA, strlen(GPSDATA)); + + //printf("\r\n"); + + return GPSDATA; +} + +char *EC800M_GPS_DATA_PARSING(char *GPS_DATA) +{ + char *p = NULL; + p = strstr(GPSDATA, "QGPSLOC:"); + + printf("%s\n", p); + + return 0; +} diff --git a/EC800M.h b/EC800M.h new file mode 100644 index 0000000..ec27759 --- /dev/null +++ b/EC800M.h @@ -0,0 +1,21 @@ +#ifndef EC800M_H +#define EC800M_H + +#include +#include +#include "pico/stdlib.h" +#include "hardware/uart.h" + +#define GPS_UART uart1 +#define GPS_UART_BAUD_RATE 115200 +#define GPSDATA_LENGTH 8192 + +extern char GPSDATA[GPSDATA_LENGTH]; +extern int GPSDATA_LEN; + +extern int EC800M_INIT(); +extern char *EC800M(); +extern char *EC800M_GPS_DATA_PARSING(char *GPS_DATA); +extern void reset_data(); + +#endif diff --git a/README.md b/README.md new file mode 100644 index 0000000..fe81207 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# 基于 Raspberry Pico / Pico W 的GPS模块(EC800M) + * 可以计算时间、经纬度 + +## Build +``` + # 使用WSL Debian GNU/Linux 12 (bookworm) 构建 + # 确保Pico-SDK环境变量 + export PICO_SDK_PATH=/mnt/c/Users/niuyuling/Desktop/raspberry-pico/SDK/pico-sdk + export PICO_EXTRAS_PATH=/mnt/c/Users/niuyuling/Desktop/raspberry-pico/SDK/pico-extras + + apt install cmake gcc-arm-none-eabi gcc g++ + apt install gdb-multiarch automake autoconf build-essential texinfo libtool libftdi-dev libusb-1.0-0-dev + + git clone https://git.aixiao.me/aixiao/EC800M.git + cd EC800M + + mkdir -p build + cd build + cmake .. + #cmake -DPICO_BOARD=pico_w .. + make + + +``` + diff --git a/main.c b/main.c new file mode 100644 index 0000000..010ce59 --- /dev/null +++ b/main.c @@ -0,0 +1,85 @@ +#include "main.h" +#include "EC800M.h" + +typedef struct GPS_ { + char time[10]; + char N[20]; + char E[20]; +} GPS_; + +float convertToDecimal(float coordinate) +{ + int degree = (int)(coordinate / 100); + float minutes = coordinate - degree * 100; + return degree + minutes / 60; +} + +void Data_parsing(char *gps_data, GPS_ * gps_) +{ + char *p = strchr(gps_data, ':'); + char *p1 = strstr(p + 2, "\r\n"); + char GPS_DATA_[p1 - p]; + + memset(GPS_DATA_, 0, p1 - p); + memcpy(GPS_DATA_, p + 2, p1 - p - 2 + 1); + //printf("%s\n", GPS_DATA_); + + char *token = strtok(GPS_DATA_, ","); + int i = 1; + while (token != NULL) { + if (i == 1) { + strcpy(gps_->time, token); + } + if (i == 2) { + strcpy(gps_->N, token); + } + if (i == 3) { + strcpy(gps_->E, token); + } + + token = strtok(NULL, ","); + i++; + } + + gps_->N[strlen(gps_->N) - 1] = '\0'; + gps_->E[strlen(gps_->E) - 1] = '\0'; + //printf("GPS : %.6f, %.6f\n", convertToDecimal(atof(gps_->N)), convertToDecimal(atof(gps_->E))); + + // 095921.00 + char hours[3] = { 0 }; + char minutes[3] = { 0 }; + char seconds[9] = { 0 }; + char *p2 = gps_->time; + memcpy(hours, p2, 2); + memcpy(minutes, p2 + 2, 2); + memcpy(seconds, p2 + 4, 2); + //printf("GPS 修正时间: %d:%s:%s\n", atoi(hours) + 8, minutes, seconds); + + sprintf(gps_->time, "%d:%s:%s", atoi(hours) + 8, minutes, seconds); + sprintf(gps_->N, "%.6f", convertToDecimal(atof(gps_->N))); + sprintf(gps_->E, "%.6f", convertToDecimal(atof(gps_->E))); + +} + +int main(void) +{ + stdio_init_all(); + sleep_ms(1000); + + printf("EC800M\n"); + EC800M_INIT(); + char gps_data[1024] = { 0 }; + + GPS_ gps_; + + while (1) { + strcpy(gps_data, EC800M()); + Data_parsing(gps_data, &gps_); + printf(" T: %s\n N: %s\n E: %s\n", gps_.time, gps_.N, gps_.E); + + printf("\r\n"); + sleep_ms(3000); + } + + return 0; +} diff --git a/main.h b/main.h new file mode 100644 index 0000000..c9ead74 --- /dev/null +++ b/main.h @@ -0,0 +1,10 @@ +#ifndef MAIN_H +#define MAIN_H + +#include +#include +#include +#include "pico/stdlib.h" +#include "hardware/uart.h" + +#endif diff --git a/pico_extras_import.cmake b/pico_extras_import.cmake new file mode 100644 index 0000000..706add0 --- /dev/null +++ b/pico_extras_import.cmake @@ -0,0 +1,62 @@ +# This is a copy of /external/pico_extras_import.cmake + +# This can be dropped into an external project to help locate pico-extras +# It should be include()ed prior to project() + +if (DEFINED ENV{PICO_EXTRAS_PATH} AND (NOT PICO_EXTRAS_PATH)) + set(PICO_EXTRAS_PATH $ENV{PICO_EXTRAS_PATH}) + message("Using PICO_EXTRAS_PATH from environment ('${PICO_EXTRAS_PATH}')") +endif () + +if (DEFINED ENV{PICO_EXTRAS_FETCH_FROM_GIT} AND (NOT PICO_EXTRAS_FETCH_FROM_GIT)) + set(PICO_EXTRAS_FETCH_FROM_GIT $ENV{PICO_EXTRAS_FETCH_FROM_GIT}) + message("Using PICO_EXTRAS_FETCH_FROM_GIT from environment ('${PICO_EXTRAS_FETCH_FROM_GIT}')") +endif () + +if (DEFINED ENV{PICO_EXTRAS_FETCH_FROM_GIT_PATH} AND (NOT PICO_EXTRAS_FETCH_FROM_GIT_PATH)) + set(PICO_EXTRAS_FETCH_FROM_GIT_PATH $ENV{PICO_EXTRAS_FETCH_FROM_GIT_PATH}) + message("Using PICO_EXTRAS_FETCH_FROM_GIT_PATH from environment ('${PICO_EXTRAS_FETCH_FROM_GIT_PATH}')") +endif () + +if (NOT PICO_EXTRAS_PATH) + if (PICO_EXTRAS_FETCH_FROM_GIT) + include(FetchContent) + set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) + if (PICO_EXTRAS_FETCH_FROM_GIT_PATH) + get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_EXTRAS_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") + endif () + FetchContent_Declare( + PICO_EXTRAS + GIT_REPOSITORY https://github.com/raspberrypi/pico-extras + GIT_TAG master + ) + if (NOT PICO_EXTRAS) + message("Downloading PICO EXTRAS") + FetchContent_Populate(PICO_EXTRAS) + set(PICO_EXTRAS_PATH ${PICO_EXTRAS_SOURCE_DIR}) + endif () + set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) + else () + if (PICO_SDK_PATH AND EXISTS "${PICO_SDK_PATH}/../pico-extras") + set(PICO_EXTRAS_PATH ${PICO_SDK_PATH}/../pico-extras) + message("Defaulting PICO_EXTRAS_PATH as sibling of PICO_SDK_PATH: ${PICO_EXTRAS_PATH}") + else() + message(FATAL_ERROR + "PICO EXTRAS location was not specified. Please set PICO_EXTRAS_PATH or set PICO_EXTRAS_FETCH_FROM_GIT to on to fetch from git." + ) + endif() + endif () +endif () + +set(PICO_EXTRAS_PATH "${PICO_EXTRAS_PATH}" CACHE PATH "Path to the PICO EXTRAS") +set(PICO_EXTRAS_FETCH_FROM_GIT "${PICO_EXTRAS_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of PICO EXTRAS from git if not otherwise locatable") +set(PICO_EXTRAS_FETCH_FROM_GIT_PATH "${PICO_EXTRAS_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download EXTRAS") + +get_filename_component(PICO_EXTRAS_PATH "${PICO_EXTRAS_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") +if (NOT EXISTS ${PICO_EXTRAS_PATH}) + message(FATAL_ERROR "Directory '${PICO_EXTRAS_PATH}' not found") +endif () + +set(PICO_EXTRAS_PATH ${PICO_EXTRAS_PATH} CACHE PATH "Path to the PICO EXTRAS" FORCE) + +add_subdirectory(${PICO_EXTRAS_PATH} pico_extras) \ No newline at end of file diff --git a/pico_sdk_import.cmake b/pico_sdk_import.cmake new file mode 100644 index 0000000..e02a33e --- /dev/null +++ b/pico_sdk_import.cmake @@ -0,0 +1,62 @@ +# This is a copy of /external/pico_sdk_import.cmake + +# This can be dropped into an external project to help locate this SDK +# It should be include()ed prior to project() + +if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) + set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) + message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) + set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) + message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) + set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) + message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") +endif () + +set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the PICO SDK") +set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of PICO SDK from git if not otherwise locatable") +set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") + +if (NOT PICO_SDK_PATH) + if (PICO_SDK_FETCH_FROM_GIT) + include(FetchContent) + set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) + if (PICO_SDK_FETCH_FROM_GIT_PATH) + get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") + endif () + FetchContent_Declare( + pico_sdk + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG master + ) + if (NOT pico_sdk) + message("Downloading PICO SDK") + FetchContent_Populate(pico_sdk) + set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) + endif () + set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) + else () + message(FATAL_ERROR + "PICO SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." + ) + endif () +endif () + +get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") +if (NOT EXISTS ${PICO_SDK_PATH}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") +endif () + +set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) +if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the PICO SDK") +endif () + +set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the PICO SDK" FORCE) + +include(${PICO_SDK_INIT_CMAKE_FILE})