commit 564de1dab20a920317dfa7f2869cb4d30affbafe Author: aixiao Date: Mon Mar 25 15:05:38 2024 +0800 init 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})