From c53e96711bc9f50f615590c16f50af9c9f22d73a Mon Sep 17 00:00:00 2001 From: aixiao Date: Mon, 11 Mar 2024 15:53:08 +0800 Subject: [PATCH] IM1253B --- .gitignore | 2 + CMakeLists.txt | 41 +++++++++ main.c | 180 +++++++++++++++++++++++++++++++++++++++ main.h | 40 +++++++++ pico_extras_import.cmake | 62 ++++++++++++++ pico_sdk_import.cmake | 62 ++++++++++++++ 6 files changed, 387 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt 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..7338750 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,41 @@ +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 + 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/main.c b/main.c new file mode 100644 index 0000000..c5f3898 --- /dev/null +++ b/main.c @@ -0,0 +1,180 @@ +#include "main.h" + +unsigned int calccrc(unsigned char crcbuf, unsigned int crc) +{ + unsigned char i; + unsigned char chk; + crc = crc ^ crcbuf; + for (i = 0; i < 8; i++) { + chk = (unsigned char)(crc & 1); + crc = crc >> 1; + crc = crc & 0x7fff; + if (chk == 1) + crc = crc ^ 0xa001; + crc = crc & 0xffff; + } + return crc; +} + +unsigned int chkcrc(unsigned char *buf, unsigned char len) +{ + unsigned char hi, lo; + unsigned int i; + unsigned int crc; + crc = 0xFFFF; + for (i = 0; i < len; i++) { + crc = calccrc(*buf, crc); + buf++; + } + hi = (unsigned char)(crc % 256); + lo = (unsigned char)(crc / 256); + crc = (((unsigned int)(hi)) << 8) | lo; + return crc; +} + +void read_data(void) +{ + static int i = 0; + union crcdata { + unsigned int word16; + unsigned char byte[2]; + } crcnow; + + if (read_enable == 1) // 到时间抄读模块,抄读间隔 1 秒钟(或其他) + { + read_enable = 0; + Tx_Buffer[0] = Read_ID; //模块的 ID 号,默认 ID 为 0x01 + Tx_Buffer[1] = 0x03; + Tx_Buffer[2] = 0x00; + Tx_Buffer[3] = 0x48; + Tx_Buffer[4] = 0x00; + Tx_Buffer[5] = 0x08; + crcnow.word16 = chkcrc(Tx_Buffer, 6); + Tx_Buffer[6] = crcnow.byte[1]; //CRC 效验低字节在前 + Tx_Buffer[7] = crcnow.byte[0]; + + // 发送数据 + uart_write_blocking(UART0, Tx_Buffer, 8); + + // 接收数据 + uint8_t _DATA[37] = { 0 }; + uart_read_blocking(UART0, _DATA, 37); + for (i = 0; i <= 37 - 1; i++) { + //printf("0x%X ", _DATA[i]); + Rx_Buffer[i] = _DATA[i]; + } + sleep_ms(10); + } +} + +void Analysis_data(void) +{ + unsigned char i; + + union crcdata { + unsigned int word16; + unsigned char byte[2]; + } crcnow; + + if (receive_finished == 1) //接收完成 + { + receive_finished = 0; + + if (Rx_Buffer[0] == Read_ID) //确认 ID 正确 + { + crcnow.word16 = chkcrc(Rx_Buffer, reveive_number - 2); //reveive_number 是接收数据总长度 + if ((crcnow.byte[0] == Rx_Buffer[reveive_number - 1]) && (crcnow.byte[1] == Rx_Buffer[reveive_number - 2])) //确认 CRC 校验正确 + { + Voltage_data = (((unsigned long)(Rx_Buffer[3])) << 24) | (((unsigned long)(Rx_Buffer[4])) << 16) | (((unsigned long)(Rx_Buffer[5])) << 8) | Rx_Buffer[6]; + Current_data = (((unsigned long)(Rx_Buffer[7])) << 24) | (((unsigned long)(Rx_Buffer[8])) << 16) | (((unsigned long)(Rx_Buffer[9])) << 8) | Rx_Buffer[10]; + Power_data = (((unsigned long)(Rx_Buffer[11])) << 24) | (((unsigned long)(Rx_Buffer[12])) << 16) | (((unsigned long)(Rx_Buffer[13])) << 8) | Rx_Buffer[14]; + Energy_data = (((unsigned long)(Rx_Buffer[15])) << 24) | (((unsigned long)(Rx_Buffer[16])) << 16) | (((unsigned long)(Rx_Buffer[17])) << 8) | Rx_Buffer[18]; + Pf_data = (((unsigned long)(Rx_Buffer[19])) << 24) | (((unsigned long)(Rx_Buffer[20])) << 16) | (((unsigned long)(Rx_Buffer[21])) << 8) | Rx_Buffer[22]; + CO2_data = (((unsigned long)(Rx_Buffer[23])) << 24) | (((unsigned long)(Rx_Buffer[24])) << 16) | (((unsigned long)(Rx_Buffer[25])) << 8) | Rx_Buffer[26]; + } + } + } +} + +void Print_data(void) +{ + float voltage_value = (float)Voltage_data / 10000.0; + printf("电压: %.2f V\n", voltage_value); + + float current_data = (float)Current_data / 10000.0; + printf("电流: %.2f A\n", current_data); + + float power_data = (float)Power_data / 10000.0; + printf("功率: %.2f W\n", power_data); + + float energy_data = (float)Energy_data / 10000.0; + printf("电能: %.2f KWH\n", energy_data); + + float pf_data = (float)Pf_data / 10000.0; + printf("功率因数: %.2f \n", pf_data); + + float cO2_data = (float)CO2_data / 10000.0; + printf("二氧化碳: %.2f KG\n", cO2_data); + + return ; +} + +static uint16_t IM1253B(void) +{ + // 初始化UART + uart_init(UART0, BAUD_RATE); + gpio_set_function(UART0_TX_PIN, GPIO_FUNC_UART); + gpio_set_function(UART0_RX_PIN, GPIO_FUNC_UART); + uart_set_hw_flow(UART0, false, false); + uart_set_format(UART0, DATA_BITS, STOP_BITS, PARITY); + sleep_ms(10); + + // 发送 + read_enable = 1; + read_data(); + sleep_ms(10); + + // 发送完成后接收数据并处理 + reveive_number = 37; + receive_finished = 1; + Analysis_data(); + + // 打印原始十六进制数据 + for (int i = 0; i <= 37 - 1; i++) { + printf("0x%X ", Rx_Buffer[i]); + } + printf("\n"); + + // 打印处理后的数据 + Print_data(); + + return 0; +} + +int main(void) +{ + stdio_init_all(); + sleep_ms(1000); + set_sys_clock_khz(250000, true); + + // 启动看门狗, 程序如果有阻塞或者程序逻辑错误重启 + if (watchdog_caused_reboot()) { // 判断是否从看门狗启动或者正常启动 + printf("Rebooted by Watchdog!\n"); + } else { + printf("Clean boot\n"); + } + watchdog_enable(8300, 1); // 8秒检测是否重新加载看门狗计数器. (不更新计数器则重启硬件, 最高8秒(8秒后不喂狗硬件重启)) + watchdog_start_tick(12); + + + while (1) { + watchdog_update(); // 喂狗 + + IM1253B(); + printf("\n"); + + sleep_ms(2000); + } + + return 0; +} diff --git a/main.h b/main.h new file mode 100644 index 0000000..9a15d28 --- /dev/null +++ b/main.h @@ -0,0 +1,40 @@ +#ifndef MAIN_H +#define MAIN_H + +#include +#include "pico/stdlib.h" +#include "hardware/gpio.h" + +#include "hardware/clocks.h" +#include "hardware/watchdog.h" +#include "pico/multicore.h" +#include "hardware/i2c.h" +#include "pico/binary_info.h" +#include "hardware/uart.h" +#include "hardware/pwm.h" +#include "hardware/adc.h" + +#define UART0 uart0 +#define BAUD_RATE 4800 +#define DATA_BITS 8 +#define STOP_BITS 1 +#define PARITY UART_PARITY_NONE + +#define UART0_TX_PIN 1 +#define UART0_RX_PIN 0 + +int Read_ID = 0x01; +unsigned char Tx_Buffer[8]; +unsigned char Rx_Buffer[40]; +unsigned char read_enable, receive_finished, reveive_number; +unsigned long Voltage_data, Current_data, Power_data, Energy_data, Pf_data, CO2_data; + +unsigned int calccrc(unsigned char crcbuf, unsigned int crc); +unsigned int chkcrc(unsigned char *buf, unsigned char len); +void read_data(void); +void Analysis_data(void); +void Print_data(void); +static uint16_t IM1253B(void); + + +#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})