基于STM32与influxDB的电力监控系统-5
一、目标:
在PAGE_DATA界面中显示RTC时间
二、main.c具体修改
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./USMART/usmart.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/ADC/adc.h"
#include "./BSP/KEY/key.h"
#include "./MALLOC/malloc.h"
#include "./BSP/SDMMC/spi_sdcard.h"
#include "./BSP/NORFLASH/norflash.h"
#include "./FATFS/exfuns/exfuns.h"
#include "./BSP/RTC/rtc.h" // 添加RTC头文件
#include <math.h>
#include <stdio.h>#define ADC_DMA_BUF_SIZE 100 * 2 /* ADC DMA采集 BUF大小, 每个通道100次采样 */
uint16_t g_adc_dma_buf[ADC_DMA_BUF_SIZE]; /* ADC DMA BUF */extern uint8_t g_adc_dma_sta; /* DMA传输状态标志, 0,未完成; 1, 已完成 *//* 传感器参数定义 */
#define VREF 3.3f /* ADC参考电压3.3V */
#define ADC_RES 4096.0f /* 12位ADC分辨率 *//* 电流互感器参数 (ZMCT103C) */
#define CURRENT_RATIO 1000.0f /* 变比1000:1 */
#define CURRENT_SENSITIVITY 0.1f /* 灵敏度调节系数,根据实际校准调整 *//* 电压互感器参数 (ZMPT101B) */
#define VOLTAGE_RATIO 1000.0f /* 变比1000:1000 */
#define VOLTAGE_SENSITIVITY 0.01f /* 灵敏度调节系数,根据实际校准调整 *//* 页面定义 */
#define PAGE_DATA 0 /* 数据页面 */
#define PAGE_WAVE 1 /* 波形页面 */
#define PAGE_FATFS 2 /* FATFS页面 *//* 波形显示参数优化 */
#define WAVE_HEIGHT 80 /* 每个波形区域高度 */
#define WAVE_WIDTH 300 /* 波形显示区域宽度 */
#define WAVE_OFFSET_X 10 /* 波形显示区域X偏移 */
#define WAVE_OFFSET_Y 40 /* 波形显示区域Y偏移 */
#define WAVE_POINTS 150 /* 波形显示点数(减少点数提高性能) */
#define WAVE_UPDATE_INTERVAL 3 /* 每3次DMA采集更新一次波形 *//* 全局变量 */
uint8_t g_current_page = PAGE_DATA; /* 当前页面 */
uint16_t g_wave_buffer[2][WAVE_POINTS]; /* 波形数据缓冲区 */
uint16_t g_wave_index = 0; /* 波形数据索引 */
uint8_t g_update_counter = 0; /* 波形更新计数器 */
uint8_t g_fatfs_initialized = 0; /* FATFS初始化标志 */
uint32_t g_last_rtc_update = 0; /* 上次RTC更新时间 *//* 函数声明 */
float calculate_rms(uint16_t *data, uint16_t samples, uint8_t channel);
float adc_to_voltage(uint16_t adc_value);
float calculate_current(float voltage_rms);
float calculate_voltage(float voltage_rms);
void display_data_page(float current_rms, float voltage_rms, float current_value, float voltage_value);
void display_wave_page_optimized(void);
void draw_waveform_optimized(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t *data, uint16_t color);
void update_wave_data_optimized(uint16_t *adc_buf, uint16_t buf_size);
void display_fatfs_page(void);
uint8_t init_fatfs(void);
void display_rtc_time(void); // 新增:显示RTC时间函数int main(void)
{uint16_t i, j;float current_rms, voltage_rms;float current_value, voltage_value;uint8_t key_val;HAL_Init(); /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72); /* 延时初始化 */usart_init(115200); /* 串口初始化为115200 */led_init(); /* 初始化LED */lcd_init(); /* 初始化LCD */key_init(); /* 初始化按键 *//* 初始化RTC */if (rtc_init() != 0){printf("RTC Init Failed!\r\n");}else{printf("RTC Init Success!\r\n");}adc_nch_dma_init((uint32_t)&g_adc_dma_buf); /* 初始化ADC DMA采集 *//* 初始化波形缓冲区 */for (i = 0; i < WAVE_POINTS; i++){g_wave_buffer[0][i] = 2048; /* 电流波形数据初始化为中间值 */g_wave_buffer[1][i] = 2048; /* 电压波形数据初始化为中间值 */}/* 显示初始页面 */lcd_clear(WHITE);lcd_show_string(30, 10, 200, 16, 16, "STM32 SENSOR SYSTEM", RED);lcd_show_string(30, 30, 200, 12, 12, "Current/Voltage Monitor", BLUE);lcd_show_string(50, 220, 200, 16, 16, "KEY1:Switch Page", BLUE);adc_dma_enable(ADC_DMA_BUF_SIZE); /* 启动ADC DMA采集 */while (1){/* 按键扫描 */key_val = key_scan(0);if (key_val == KEY1_PRES) /* KEY1按下 */{g_current_page = ((g_current_page + 1) % 3); /* 循环切换三个页面 */lcd_clear(WHITE);lcd_show_string(30, 10, 200, 16, 16, "STM32 SENSOR SYSTEM", RED);lcd_show_string(30, 30, 200, 12, 12, "Current/Voltage Monitor", BLUE);lcd_show_string(50, 220, 200, 16, 16, "KEY1:Switch Page", BLUE);/* 如果切换到FATFS页面且未初始化,则进行初始化 */if (g_current_page == PAGE_FATFS && !g_fatfs_initialized){if (init_fatfs() == 0){g_fatfs_initialized = 1;}}}if (g_adc_dma_sta == 1){/* 只在数据页面和波形页面处理ADC数据 */if (g_current_page == PAGE_DATA || g_current_page == PAGE_WAVE){/* 处理两个通道的数据 */for(j = 0; j < 2; j++) /* 遍历2个通道 */{/* 计算RMS值 */float rms_value = calculate_rms(g_adc_dma_buf, ADC_DMA_BUF_SIZE / 2, j);if (j == 0) /* 电流传感器通道 */{current_rms = rms_value;current_value = calculate_current(current_rms);}else if (j == 1) /* 电压传感器通道 */{voltage_rms = rms_value;voltage_value = calculate_voltage(voltage_rms);}}/* 优化波形更新:控制更新频率 */g_update_counter++;if (g_update_counter >= WAVE_UPDATE_INTERVAL){update_wave_data_optimized(g_adc_dma_buf, ADC_DMA_BUF_SIZE);g_update_counter = 0;}}/* 根据当前页面显示内容 */if (g_current_page == PAGE_DATA){display_data_page(current_rms, voltage_rms, current_value, voltage_value);}else if (g_current_page == PAGE_WAVE){display_wave_page_optimized(); /* 使用优化后的波形显示 */}else if (g_current_page == PAGE_FATFS){display_fatfs_page(); /* 显示FATFS页面 */}g_adc_dma_sta = 0; /* 清除DMA采集完成状态标志 *//* 只在数据页面和波形页面继续ADC采集 */if (g_current_page == PAGE_DATA || g_current_page == PAGE_WAVE){adc_dma_enable(ADC_DMA_BUF_SIZE); /* 启动下一次ADC DMA采集 */}}/* 在数据页面显示RTC时间(每秒更新一次) */if (g_current_page == PAGE_DATA){static uint32_t last_tick = 0;if (HAL_GetTick() - last_tick >= 1000) // 每秒更新一次{display_rtc_time();last_tick = HAL_GetTick();}}LED0_TOGGLE();delay_ms(10); /* 减少延时,提高响应速度 */}
}/*** @brief 显示RTC时间* @param 无* @retval 无*/
void display_rtc_time(void)
{char time_str[32];char date_str[32];/* 获取当前RTC时间 */rtc_get_time();/* 格式化日期和时间字符串 */sprintf(date_str, "Date: %04d-%02d-%02d", calendar.year, calendar.month, calendar.date);sprintf(time_str, "Time: %02d:%02d:%02d", calendar.hour, calendar.min, calendar.sec);/* 显示日期和时间 */lcd_fill(30, 160, 200, 175, WHITE); /* 清除日期显示区域 */lcd_show_string(30, 160, 200, 12, 12, date_str, BLUE);lcd_fill(30, 175, 200, 190, WHITE); /* 清除时间显示区域 */lcd_show_string(30, 175, 200, 12, 12, time_str, BLUE);
}/*** @brief 初始化FATFS* @param 无* @retval 0:成功 1:失败*/
uint8_t init_fatfs(void)
{uint8_t res = 0;/* 初始化NORFLASH */norflash_init();/* 初始化内存管理 */my_mem_init(SRAMIN);/* 检测SD卡 */if (sd_init()){lcd_show_string(30, 130, 200, 16, 16, "SD Card Error!", RED);return 1;}/* 初始化exfuns */exfuns_init();/* 挂载SD卡 */f_mount(fs[0], "0:", 1);/* 挂载FLASH */res = f_mount(fs[1], "1:", 1);if (res == 0X0D) /* FLASH磁盘,FAT文件系统错误,重新格式化FLASH */{lcd_show_string(30, 130, 200, 16, 16, "Flash Disk Formatting...", RED);res = f_mkfs("1:", 0, 0, FF_MAX_SS); /* 格式化FLASH */if (res == 0){f_setlabel((const TCHAR *)"1:ALIENTEK"); /* 设置Flash磁盘的名字为:ALIENTEK */}else{lcd_show_string(30, 130, 200, 16, 16, "Flash Disk Format Error ", RED);return 1;}}return 0;
}/*** @brief 显示FATFS页面* @param 无* @retval 无*/
void display_fatfs_page(void)
{static uint8_t prev_page = 0xFF; /* 前一个页面 */uint32_t total, free;/* 如果页面发生变化,重新显示静态内容 */if (prev_page != PAGE_FATFS){lcd_fill(0, 50, 239, 200, WHITE);lcd_show_string(30, 60, 200, 16, 16, "FATFS FILE SYSTEM", RED);prev_page = PAGE_FATFS;}/* 获取SD卡容量信息 */if (exfuns_get_free("0", &total, &free) == 0){lcd_show_string(30, 80, 200, 16, 16, "SD Card Status: OK", BLUE);lcd_show_string(30, 100, 200, 16, 16, "SD Total Size: MB", BLUE);lcd_show_string(30, 120, 200, 16, 16, "SD Free Size: MB", BLUE);lcd_show_num(30 + 13 * 8, 100, total >> 10, 5, 16, BLUE); /* 显示SD卡总容量 MB */lcd_show_num(30 + 13 * 8, 120, free >> 10, 5, 16, BLUE); /* 显示SD卡剩余容量 MB */}else{lcd_show_string(30, 80, 200, 16, 16, "SD Card Status: ERROR", RED);}/* 显示页面标识 */lcd_show_string(100, 180, 200, 16, 16, "FATFS PAGE", RED);
}/*** @brief 显示数据页面* @param current_rms: 电流RMS值* @param voltage_rms: 电压RMS值* @param current_value: 电流计算值* @param voltage_value: 电压计算值* @retval 无*/
void display_data_page(float current_rms, float voltage_rms, float current_value, float voltage_value)
{static uint8_t prev_page = 0xFF; /* 前一个页面 *//* 如果页面发生变化,重新显示静态内容 */if (prev_page != PAGE_DATA){/* 清除数据区域 */lcd_fill(0, 50, 239, 200, WHITE);/* 显示电流传感器信息 */lcd_show_string(30, 60, 200, 12, 12, "CURRENT SENSOR:", BLUE);lcd_show_string(30, 75, 200, 12, 12, "ADC_CH0_RMS:", BLUE);lcd_show_string(30, 90, 200, 12, 12, "CURRENT: 0.000A", BLUE);/* 显示电压传感器信息 */lcd_show_string(30, 110, 200, 12, 12, "VOLTAGE SENSOR:", BLUE);lcd_show_string(30, 125, 200, 12, 12, "ADC_CH1_RMS:", BLUE);lcd_show_string(30, 140, 200, 12, 12, "VOLTAGE: 000.0V", BLUE);/* 显示RTC时间标题 */lcd_show_string(30, 160, 200, 12, 12, "RTC TIME:", BLUE);/* 显示页面标识 */lcd_show_string(100, 190, 200, 16, 16, "DATA PAGE", RED);prev_page = PAGE_DATA;}/* 显示ADC RMS值 */lcd_fill(102, 75, 150, 87, WHITE);lcd_show_xnum(102, 75, (uint16_t)current_rms, 4, 12, 0, BLUE);lcd_fill(102, 125, 150, 137, WHITE);lcd_show_xnum(102, 125, (uint16_t)voltage_rms, 4, 12, 0, BLUE);/* 显示电流值 */lcd_fill(78, 90, 150, 102, WHITE);if (current_value < 10.0f) /* 显示格式: X.XXX A */{lcd_show_xnum(78, 90, (uint16_t)current_value, 1, 12, 0, BLUE); /* 整数部分 */float decimal_current = (current_value - (uint16_t)current_value) * 1000; /* 小数部分 */lcd_show_xnum(90, 90, (uint16_t)decimal_current, 3, 12, 0X80, BLUE); /* 小数部分 */lcd_show_string(114, 90, 200, 12, 12, "A", BLUE);}/* 显示电压值 */lcd_fill(78, 140, 150, 152, WHITE);if (voltage_value < 1000.0f) /* 显示格式: XXX.X V */{lcd_show_xnum(78, 140, (uint16_t)voltage_value, 3, 12, 0, BLUE); /* 整数部分 */float decimal_voltage = (voltage_value - (uint16_t)voltage_value) * 10; /* 小数部分 */lcd_show_xnum(102, 140, (uint16_t)decimal_voltage, 1, 12, 0X80, BLUE); /* 小数部分 */lcd_show_string(114, 140, 200, 12, 12, "V", BLUE);}
}// 其他函数保持不变...
// [原有代码继续]
三、显示效果
在PAGE_DATA界面中,RTC时间将显示在传感器数据下方,格式为:
日期:YYYY-MM-DD
时间:HH:MM:SS