diff --git a/.vscode/settings.json b/.vscode/settings.json index 71ce963..d4fbee6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,6 +5,10 @@ "ina226.h": "c", "oled12864_drv.h": "c", "delay.h": "c", - "timer.h": "c" + "timer.h": "c", + "keyscan.h": "c", + "uart.h": "c", + "sensor_json.h": "c", + "stdint.h": "c" } } \ No newline at end of file diff --git a/Driver/timer.c b/Driver/timer.c index 46bed1e..2e2239f 100644 --- a/Driver/timer.c +++ b/Driver/timer.c @@ -25,8 +25,7 @@ Timer3_Init (void) // 10毫秒@30.000MHz void Timer3_Isr (void) interrupt 19 { - time3_cnt++; - if (time3_cnt >= 100) + if (++time3_cnt >= 100) { uptime++; time3_cnt = 0; @@ -38,6 +37,12 @@ GetUpTime (void) { return uptime; } +// 获取系统时间(单位:毫秒) +uint32_t +GetUpTime_10Ms (void) +{ + return uptime*100+time3_cnt; +} // 定时器4 u8 Timer4_OF = 0; // 定时器4溢出标志 diff --git a/Driver/timer.h b/Driver/timer.h index ab42b1f..aa63c13 100644 --- a/Driver/timer.h +++ b/Driver/timer.h @@ -13,6 +13,7 @@ void Timer_Init (void); // Timer3 用于记录系统运行时间 void Timer3_Init (void); uint32_t GetUpTime (void); +uint32_t GetUpTime_10Ms (void); // Timer4 用于短时间延时 void Timer4_Init (void); diff --git a/Lib/KeyScan.c b/Lib/KeyScan.c index aebe4a0..419aa36 100644 --- a/Lib/KeyScan.c +++ b/Lib/KeyScan.c @@ -1,22 +1,55 @@ +/* KeyScan.c - 按键扫描模块 */ #include "KeyScan.h" -void main() { - Key_Init(); // 初始化按键模块 - Timer0_Init(); // 配置1ms定时器 - - while(1) { - // 在定时器中断服务例程中调用Key_Scan() - if(Get_KeyEvents()) { - // 执行按键处理逻辑 - uint8_t keys = Get_KeyEvents(); - if(keys & 0x08) { /* KEY1处理 */ } - if(keys & 0x04) { /* KEY2处理 */ } - // ...其他按键处理 - } - } +// 按键状态机结构体 +typedef struct +{ + uint8_t prev_state; // 前次状态 + uint8_t edge_trigger; // 边沿触发标志 + uint8_t scan_counter; // 扫描计数器 +} KeyStateMachine; + +static KeyStateMachine key_state = { 0xFF, 0x00, 0 }; + +/******************************************* + * 初始化函数 + *******************************************/ +void +Key_Init (void) +{ + // 配置P2.4-P2.1为准双向口 + P2M0 &= 0xE1; + P2M1 &= 0xE1; + + // 初始化按键状态 + key_state.prev_state = (KEY1 * 0x08) | (KEY2 * 0x04) | (KEY3 * 0x02) | KEY4; } -// // Timer0中断服务函数 -// void Timer0_ISR() interrupt 1 { -// Key_Scan(); // 定时扫描按键 -// } +/******************************************* + * 按键扫描函数 + * 需在主循环中周期性调用 + *******************************************/ +void +Key_Scan (void) +{ + const uint8_t current = (KEY1 * 0x08) | (KEY2 * 0x04) | (KEY3 * 0x02) | KEY4; + + // 边沿检测 + const uint8_t falling_edge + = (key_state.prev_state ^ current) & key_state.prev_state; + key_state.edge_trigger |= falling_edge; // 累积触发事件 + + key_state.prev_state = current; // 更新历史状态 +} + +/******************************************* + * 按键事件获取接口(供外部模块调用) + * 返回:4位掩码,对应KEY4-KEY1的触发状态 + *******************************************/ +uint8_t +Get_KeyEvents (void) +{ + const uint8_t events = key_state.edge_trigger; + key_state.edge_trigger = 0; // 读取后清除标志 + return events; +} \ No newline at end of file diff --git a/Lib/KeyScan.h b/Lib/KeyScan.h index d2f411e..ee0b06f 100644 --- a/Lib/KeyScan.h +++ b/Lib/KeyScan.h @@ -2,15 +2,19 @@ #ifndef __KEY_SCAN_H__ #define __KEY_SCAN_H__ +#include "STC15.H" + +#include "config.h" + // 按键引脚定义(与硬件布局一致) -sbit KEY1 = P3^0; -sbit KEY2 = P3^1; -sbit KEY3 = P3^2; -sbit KEY4 = P3^3; +#define KEY1 P21 +#define KEY2 P22 +#define KEY3 P23 +#define KEY4 P24 // 函数声明 -void Key_Init(void); -void Key_Scan(void); -uint8_t Get_KeyEvents(void); +void Key_Init (void); +void Key_Scan (void); +uint8_t Get_KeyEvents (void); #endif \ No newline at end of file diff --git a/Lib/sensor_json.h b/Lib/sensor_json.h new file mode 100644 index 0000000..43811fd --- /dev/null +++ b/Lib/sensor_json.h @@ -0,0 +1,101 @@ +/********************************************** + * 文件名:sensor_json.h + * 功能:将5个uint16参数封装为紧凑JSON格式 + * 特性:HEX传输、静态内存、无库依赖 + * 设计依据:C51硬件架构优化 + ​**********************************************/ + +#ifndef __SENSOR_JSON_H__ +#define __SENSOR_JSON_H__ + +#include + +/* 硬件相关定义 */ +#define JSON_BUF_SIZE 57 // 内存预分配避免动态申请 +#define HEX_DIGITS "0123456789ABCDEF" + +/* 静态缓冲区声明 */ +static char json_buf[JSON_BUF_SIZE] + = "{\"vol\":----,\"cur\":----,\"pwr\":----,\"tmp\":----,\"hum\":----}"; + +/********************************************** + * 函数名:hex4_encode + * 功能:快速HEX转换(无分支优化) + * 输入:16位数值、4字节输出缓冲区 + * 注:避免浮点运算提升执行效率 + ​**********************************************/ +static void +hex4_encode (uint16_t num, char *out) +{ + out[0] = HEX_DIGITS[(num >> 12) & 0x0F]; + out[1] = HEX_DIGITS[(num >> 8) & 0x0F]; + out[2] = HEX_DIGITS[(num >> 4) & 0x0F]; + out[3] = HEX_DIGITS[num & 0x0F]; +} + +/********************************************** + * 主函数:make_sensor_json + * 参数顺序:电压、电流、功率、温度、湿度 + * 返回值:静态缓冲区指针(注意不可重入) + * 内存布局优化:固定位置替换减少计算量 + ​**********************************************/ +char * +make_sensor_json (uint16_t v, uint16_t c, uint16_t p, uint16_t t, uint16_t h) +{ + char tmp[4]; + + /* 定点内存操作(避免字符串拼接) */ + hex4_encode (v, tmp); + json_buf[7] = tmp[0]; + json_buf[8] = tmp[1]; // vol + json_buf[9] = tmp[2]; + json_buf[10] = tmp[3]; + + hex4_encode (c, tmp); + json_buf[18] = tmp[0]; + json_buf[19] = tmp[1]; // cur + json_buf[20] = tmp[2]; + json_buf[21] = tmp[3]; + + hex4_encode (p, tmp); + json_buf[29] = tmp[0]; + json_buf[30] = tmp[1]; // pwr + json_buf[31] = tmp[2]; + json_buf[32] = tmp[3]; + + hex4_encode (t, tmp); + json_buf[40] = tmp[0]; + json_buf[41] = tmp[1]; // tmp + json_buf[42] = tmp[2]; + json_buf[43] = tmp[3]; + + hex4_encode (h, tmp); + json_buf[51] = tmp[0]; + json_buf[52] = tmp[1]; // hum + json_buf[53] = tmp[2]; + json_buf[54] = tmp[3]; + + return json_buf; +} + +#endif /* __SENSOR_JSON_H__ */ + +/********************************************** + * 使用示例: + * #include "sensor_json.h" + * + * void main() { + * char* data = make_sensor_json( + * 0x0D0C, // 电压 + * 0x047E, // 电流 + * 0x1284, // 功率 + * 0x0CA2, // 温度 + * 0x0BF6 // 湿度 + * ); + * // 通过P1口输出(需按 配置端口模式) + * for(uint8_t i=0; data[i]; i++) { + * P1 = data[i]; // 假设P1接发送模块 + * delay_ms(1); + * } + * } + ​**********************************************/ \ No newline at end of file diff --git a/Src/config.h b/Src/config.h index c5c1c60..d709740 100644 --- a/Src/config.h +++ b/Src/config.h @@ -19,6 +19,8 @@ typedef uint8_t u8; #define True 1 #define False 0 +//#define NULL 0 + sbit SDA = P2 ^ 7; sbit SCL = P2 ^ 6; diff --git a/Src/main.c b/Src/main.c index 5947529..e1bdde9 100644 --- a/Src/main.c +++ b/Src/main.c @@ -2,15 +2,18 @@ #include #include #include -// Driver -#include "iic.h" -#include "uart.h" // Config #include "config.h" +// Driver +#include "iic.h" +#include "timer.h" +#include "uart.h" // Lib #include "delay.h" #include "ina226.h" +#include "keyscan.h" #include "oled12864_drv.h" +// #include "sensor_json.h" void SystemClock_Init (void) @@ -22,9 +25,14 @@ SystemClock_Init (void) void main () { + uint32_t last_round_time = 0; + uint32_t this_round_time = 0; + u16 ina226_voltage = 0; u16 ina226_current = 0; u16 ina226_power = 0; + + // char *p_json_str = NULL; SystemClock_Init (); // 时钟配置 Timer_Init (); // 初始化定时器 @@ -37,6 +45,7 @@ main () IIC_Init (); OLED_Init (); INA226_Init (0.005f, 2.0f); + Key_Init (); DelayMs (100); // 初始化延时 @@ -47,27 +56,41 @@ main () P2M0 |= 0x01; P20 = 1; // P20为推挽输出 - while (1) { - OLED_ShowNum (4, 1, GetUpTime (), 10, OLED_FONT_EIGHT, OLED_LEFT_ROLL, + OLED_ShowNum (0, 1, GetUpTime (), 10, OLED_FONT_EIGHT, OLED_LEFT_ROLL, OLED_SHOW); ina226_voltage = (int16_t)(INA226_ReadBusVoltage () * 1000); - - OLED_ShowNum (4, 2, ina226_voltage, 10, OLED_FONT_SIXTEEN, - OLED_LEFT_ROLL, OLED_SHOW); + OLED_ShowNum (0, 2, ina226_voltage, 5, OLED_FONT_SIXTEEN, OLED_LEFT_ROLL, + OLED_SHOW); ina226_current = (int16_t)(INA226_ReadCurrent () * 1000); - OLED_ShowNum (4, 4, ina226_current, 10, OLED_FONT_SIXTEEN, + OLED_ShowNum (48, 2, ina226_current, 5, OLED_FONT_SIXTEEN, OLED_LEFT_ROLL, OLED_SHOW); ina226_power = (int16_t)(INA226_ReadPower () * 1000); - OLED_ShowNum (4, 6, ina226_power, 10, OLED_FONT_SIXTEEN, OLED_LEFT_ROLL, + OLED_ShowNum (0, 4, ina226_power, 5, OLED_FONT_SIXTEEN, OLED_LEFT_ROLL, OLED_SHOW); - DelayMs (500); + // DelayMs (100); // 初始化延时 + last_round_time = this_round_time; + this_round_time = GetUpTime_10Ms (); + OLED_ShowNum (4, 7, this_round_time - last_round_time, 3, + OLED_FONT_EIGHT, OLED_LEFT_ROLL, OLED_SHOW); + + // p_json_str = make_sensor_json (ina226_voltage, // 电压 + // ina226_current, // 电流 + // ina226_power, // 功率 + // 0x0CA2, // 温度 + // 0x0BF6 // 湿度 + // ); + // printf ("data:%s",p_json_str); // 打印数据 + // OLED_ShowPrintf (0, 6, p_json_str, OLED_FONT_EIGHT, OLED_LEFT_ROLL, + // OLED_SHOW); + + Key_Scan (); } }