STC32G12K128 遇到一个问题关于xdata的问题
typedef struct Key
{
u8 key_code : 4; // key code
u8 state : 1; // 0 released 1 pressd
u8 short_flag : 1; // 短按待处理标志
u8 long_flag : 1;// 长按待处理标志
u8 lock_flag : 1; // 预留
u16 press_time; // 持续按下时间
} Key_t;
#define NUM_KEYS 5
#define KEY1 1
#define KEY2 2
#define KEY3 3
#define KEY4 4
#define KEY5 5
Key_t xdata g_keys;
void keyInit(void)
{
Key_t *key = NULL;
u8 key_i = 0;
#ifdef KEY1
key = &g_keys;
key->key_code = KEY1;// 这里是问题出现的地方,其它没有,永远是0,实际KEY1定义是1,尝试过任何值最终都为0
#endif // KEY1
#ifdef KEY2
key = &g_keys;
key->key_code = KEY2;
#endif // KEY2
#ifdef KEY3
key = &g_keys;
key->key_code = KEY3;
#endif // KEY3
#ifdef KEY4
key = &g_keys;
key->key_code = KEY4;
#endif // KEY4
#ifdef KEY5
key = &g_keys;
key->key_code = KEY5;
#endif // KEY5
#ifdef KEY6
key = &g_keys;
key->key_code = KEY6;
#endif // KEY6
}
但是将xdata删除或修改为idata就能正常初始值
看反汇编很正常啊
都正常 Ayb_ice 发表于 2026-1-4 15:27
都正常
目前我这运行输出来的结果是0,0,0,02,0,0...这样的结果,我上传编译你反编译看下结果
jacksonjim 发表于 2026-1-4 17:29
目前我这运行输出来的结果是0,0,0,02,0,0...这样的结果,我上传编译你反编译看下结果
...
可以 这是编译的,手上没有反编译工具,你帮查看下 上传了一个工程代码,目前发现是不是初始化的原因了,在按键扫描那输出这个结构体的数据,初始化中输出一次,结果是被修改了
#include "key.h"
#include "uart.h"
#ifdef HAS_KEYS
Key_t xdata g_keys = {
#ifdef KEY1
{KEY1},
#endif // KEY1
#ifdef KEY2
{KEY2},
#endif // KEY2
#ifdef KEY3
{KEY3},
#endif // KEY3
#ifdef KEY4
{KEY4},
#endif // KEY4
#ifdef KEY5
{KEY5},
#endif // KEY5
#ifdef KEY6
{KEY6},
#endif // KEY6
};
void keyInit(void)
{
UART_sendBytes(RS485_USE_UART, (u8 *)g_keys, sizeof(Key_t) * NUM_KEYS);
}
bit read_key(const u8 key_code)
{
switch (key_code)
{
#ifdef KEY1
case KEY1:
return !KEY1_PIN;
#endif
#ifdef KEY2
case KEY2:
return !KEY2_PIN;
#endif
#ifdef KEY3
case KEY3:
return !KEY3_PIN;
#endif
#ifdef KEY4
case KEY4:
return !KEY4_PIN;
#endif
#ifdef KEY5
case KEY5:
return !KEY5_PIN;
#endif
#ifdef KEY6
case KEY6:
return !KEY6_PIN;
#endif
default:
return 0; // 无效键码
}
}
void keyScan(void)
{
// 按键消抖计数
static u8 keys_debounce = {0}, test = 0;
bit key_stable_sta, key_sta;
Key_t *key = NULL;
u8 i;
#ifdef SW_KTDY01
WKTCL = 0xFF;
WKTCH = 0x87;
NOP2();
MCU_IDLE();
NOP2();
#endif
#ifdef KEY_ISP
if (!KEY_ISP_PIN)
{
IAP_CONTR = 0x60; // in system programe ISP
NOP2();
}
#endif // KEY_ISP
if (test++ > 20)
{
test = 0;
UART_sendBytes(RS485_USE_UART, (u8 *)g_keys, sizeof(Key_t) * NUM_KEYS);
}
for (i = 0; i < NUM_KEYS; i++)
{
key = &g_keys;
key_sta = read_key(key->key_code);
// 消抖处理 连续3次一致才认为按键有效
if (key_sta)
{
if (keys_debounce < 3)
keys_debounce++;
}
else
{
if (keys_debounce > 0)
keys_debounce--;
}
key_stable_sta = keys_debounce >= 3 ? 1 : 0;
if (key_stable_sta)
{
if (key->state == 0)
{
// 按键按下时,初始化
key->state = 1;
key->press_time = 0;
key->long_flag = 0;
key->short_flag = 0;
key->lock_flag = 0;
}
else
{
// 持续按下时,计时
if (key->press_time < LONG_PRESS_TIME)
key->press_time++;
// 检查是否达到长按阈值且未触发过
if (key->press_time >= LONG_PRESS_TIME && !key->long_flag && !key->lock_flag)
{
key->long_flag = 1; // 标记长按事件待处理
key->lock_flag = 1;
}
}
}
else
{ // 释放按键
if (key->state == 1)
{
if (!key->long_flag && !key->lock_flag && key->press_time >= SHORT_PRESS_TIME && key->press_time < LONG_PRESS_TIME)
{
key->short_flag = 1;
}
// 释放按键时, 重置按键状态
key->state = 0;
key->press_time = 0;
key->lock_flag = 0;
}
}
}
}
void keyService(void)
{
int i;
Key_t *key = NULL;
for (i = 0; i < NUM_KEYS; i++)
{
key = &g_keys;
if (key->short_flag)
{
key->short_flag = 0;
// Key_onClick(key->key_code);
UART_sendBytes(RS485_USE_UART, (u8 *)key, sizeof(Key_t));
}
if (key->long_flag)
{
key->long_flag = 0;
// Key_onLongPress(key->key_code);
}
}
}
#endif // HAS_KEYS
运行时输出结果
收←◆01 00 00 02 00 00 03 00 00 04 00 00 05 00 00 初始化函数输出的结果,下方所有输出是在扫描函数1秒输出一次
收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00 将xdata修改为idata或删除就输出的结果是正常的
收←◆01 00 00 02 00 00 03 00 00 04 00 00 05 00 00
收←◆01 00 00 02 00 00 03 00 00 04 00 00 05 00 00
收←◆01 00 00 02 00 00 03 00 00 04 00 00 05 00 00
收←◆01 00 00 02 00 00 03 00 00 04 00 00 05 00 00
收←◆01 00 00 02 00 00 03 00 00 04 00 00 05 00 00
收←◆01 00 00 02 00 00 03 00 00 04 00 00 05 00 00
收←◆01 00 00 02 00 00 03 00 00 04 00 00 05 00 00
收←◆01 00 00 02 00 00 03 00 00 04 00 00 05 00 00
收←◆01 00 00 02 00 00 03 00 00 04 00 00 05 00 00
jacksonjim 发表于 2026-1-5 09:11
上传了一个工程代码,目前发现是不是初始化的原因了,在按键扫描那输出这个结构体的数据,初始化中输出一次 ...
建议不要使用位域,另外将数据打印成ASCII码,即调用printf或sprintf Ayb_ice 发表于 2026-1-5 10:00
建议不要使用位域,另外将数据打印成ASCII码,即调用printf或sprintf
那个打印只是临时调试使用不是正常使用,目前就是这个原因,改回idata就能正常使用了 jacksonjim 发表于 2026-1-5 10:23
那个打印只是临时调试使用不是正常使用,目前就是这个原因,改回idata就能正常使用了 ...
看反汇编,看看有什么区别
页:
[1]
2