找回密码
 立即注册
查看: 292|回复: 14

STC32G12K128 遇到一个问题关于xdata的问题

[复制链接]
  • 打卡等级:常住居民III
  • 打卡总天数:162
  • 最近打卡:2026-03-26 08:17:55

14

主题

53

回帖

778

积分

高级会员

积分
778
发表于 2026-1-4 14:23:09 | 显示全部楼层 |阅读模式
复制代码
  1. typedef struct Key
  2. {
  3.     u8 key_code : 4;   // key code
  4.     u8 state : 1;      // 0 released 1 pressd
  5.     u8 short_flag : 1; // 短按待处理标志
  6.     u8 long_flag : 1;  // 长按待处理标志
  7.     u8 lock_flag : 1;    // 预留
  8.     u16 press_time;    // 持续按下时间
  9. } Key_t;
  10. #define NUM_KEYS 5
  11. #define KEY1 1
  12. #define KEY2 2
  13. #define KEY3 3
  14. #define KEY4 4
  15. #define KEY5 5
  16. Key_t xdata g_keys[NUM_KEYS];
  17. void keyInit(void)
  18. {
  19.     Key_t *key = NULL;
  20.     u8 key_i = 0;
  21. #ifdef KEY1
  22.     key = &g_keys[key_i++];
  23.     key->key_code = KEY1;  // 这里是问题出现的地方,其它没有,永远是0,实际KEY1定义是1,尝试过任何值最终都为0
  24. #endif // KEY1
  25. #ifdef KEY2
  26.     key = &g_keys[key_i++];
  27.     key->key_code = KEY2;
  28. #endif // KEY2
  29. #ifdef KEY3
  30.     key = &g_keys[key_i++];
  31.     key->key_code = KEY3;
  32. #endif // KEY3
  33. #ifdef KEY4
  34.     key = &g_keys[key_i++];
  35.     key->key_code = KEY4;
  36. #endif // KEY4
  37. #ifdef KEY5
  38.     key = &g_keys[key_i++];
  39.     key->key_code = KEY5;
  40. #endif // KEY5
  41. #ifdef KEY6
  42.     key = &g_keys[key_i++];
  43.     key->key_code = KEY6;
  44. #endif // KEY6
  45. }
复制代码

但是将xdata删除或修改为idata就能正常初始值
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:257
  • 最近打卡:2026-04-01 08:14:32
已绑定手机

22

主题

631

回帖

2340

积分

金牌会员

积分
2340
发表于 2026-1-4 15:24:03 | 显示全部楼层
看反汇编很正常啊
截图202601041523562357.jpg
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:257
  • 最近打卡:2026-04-01 08:14:32
已绑定手机

22

主题

631

回帖

2340

积分

金牌会员

积分
2340
发表于 2026-1-4 15:27:10 | 显示全部楼层
都正常
截图202601041526521459.jpg
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:162
  • 最近打卡:2026-03-26 08:17:55

14

主题

53

回帖

778

积分

高级会员

积分
778
发表于 2026-1-4 17:29:04 | 显示全部楼层

目前我这运行输出来的结果是0,0,0,02,0,0...这样的结果,我上传编译你反编译看下结果
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:257
  • 最近打卡:2026-04-01 08:14:32
已绑定手机

22

主题

631

回帖

2340

积分

金牌会员

积分
2340
发表于 2026-1-4 17:30:26 | 显示全部楼层
jacks*** 发表于 2026-1-4 17:29
目前我这运行输出来的结果是0,0,0,02,0,0...这样的结果,我上传编译你反编译看下结果
...

可以
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:162
  • 最近打卡:2026-03-26 08:17:55

14

主题

53

回帖

778

积分

高级会员

积分
778
发表于 2026-1-4 17:32:16 | 显示全部楼层
这是编译的,手上没有反编译工具,你帮查看下

key.__i

169 Bytes, 下载次数: 1

key.crf

100.93 KB, 下载次数: 1

key.obj

13.13 KB, 下载次数: 1

SW_TEST.hex

40.67 KB, 下载次数: 0

回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:162
  • 最近打卡:2026-03-26 08:17:55

14

主题

53

回帖

778

积分

高级会员

积分
778
发表于 2026-1-5 09:11:13 | 显示全部楼层
上传了一个工程代码,目前发现是不是初始化的原因了,在按键扫描那输出这个结构体的数据,初始化中输出一次,结果是被修改了

  1. #include "key.h"
  2. #include "uart.h"
  3. #ifdef HAS_KEYS
  4. Key_t xdata g_keys[NUM_KEYS] = {
  5. #ifdef KEY1
  6.     {KEY1},
  7. #endif // KEY1
  8. #ifdef KEY2
  9.     {KEY2},
  10. #endif // KEY2
  11. #ifdef KEY3
  12.     {KEY3},
  13. #endif // KEY3
  14. #ifdef KEY4
  15.     {KEY4},
  16. #endif // KEY4
  17. #ifdef KEY5
  18.     {KEY5},
  19. #endif // KEY5
  20. #ifdef KEY6
  21.     {KEY6},
  22. #endif // KEY6
  23. };
  24. void keyInit(void)
  25. {
  26.     UART_sendBytes(RS485_USE_UART, (u8 *)g_keys, sizeof(Key_t) * NUM_KEYS);
  27. }
  28. bit read_key(const u8 key_code)
  29. {
  30.     switch (key_code)
  31.     {
  32. #ifdef KEY1
  33.     case KEY1:
  34.         return !KEY1_PIN;
  35. #endif
  36. #ifdef KEY2
  37.     case KEY2:
  38.         return !KEY2_PIN;
  39. #endif
  40. #ifdef KEY3
  41.     case KEY3:
  42.         return !KEY3_PIN;
  43. #endif
  44. #ifdef KEY4
  45.     case KEY4:
  46.         return !KEY4_PIN;
  47. #endif
  48. #ifdef KEY5
  49.     case KEY5:
  50.         return !KEY5_PIN;
  51. #endif
  52. #ifdef KEY6
  53.     case KEY6:
  54.         return !KEY6_PIN;
  55. #endif
  56.     default:
  57.         return 0; // 无效键码
  58.     }
  59. }
  60. void keyScan(void)
  61. {
  62.     // 按键消抖计数
  63.     static u8 keys_debounce[NUM_KEYS] = {0}, test = 0;
  64.     bit key_stable_sta, key_sta;
  65.     Key_t *key = NULL;
  66.     u8 i;
  67. #ifdef SW_KTDY01
  68.     WKTCL = 0xFF;
  69.     WKTCH = 0x87;
  70.     NOP2();
  71.     MCU_IDLE();
  72.     NOP2();
  73. #endif
  74. #ifdef KEY_ISP
  75.     if (!KEY_ISP_PIN)
  76.     {
  77.         IAP_CONTR = 0x60; // in system programe ISP
  78.         NOP2();
  79.     }
  80. #endif // KEY_ISP
  81.     if (test++ > 20)
  82.     {
  83.         test = 0;
  84.         UART_sendBytes(RS485_USE_UART, (u8 *)g_keys, sizeof(Key_t) * NUM_KEYS);
  85.     }
  86.     for (i = 0; i < NUM_KEYS; i++)
  87.     {
  88.         key = &g_keys[i];
  89.         key_sta = read_key(key->key_code);
  90.         // 消抖处理 连续3次一致才认为按键有效
  91.         if (key_sta)
  92.         {
  93.             if (keys_debounce[i] < 3)
  94.                 keys_debounce[i]++;
  95.         }
  96.         else
  97.         {
  98.             if (keys_debounce[i] > 0)
  99.                 keys_debounce[i]--;
  100.         }
  101.         key_stable_sta = keys_debounce[i] >= 3 ? 1 : 0;
  102.         if (key_stable_sta)
  103.         {
  104.             if (key->state == 0)
  105.             {
  106.                 // 按键按下时,初始化
  107.                 key->state = 1;
  108.                 key->press_time = 0;
  109.                 key->long_flag = 0;
  110.                 key->short_flag = 0;
  111.                 key->lock_flag = 0;
  112.             }
  113.             else
  114.             {
  115.                 // 持续按下时,计时
  116.                 if (key->press_time < LONG_PRESS_TIME)
  117.                     key->press_time++;
  118.                 // 检查是否达到长按阈值且未触发过
  119.                 if (key->press_time >= LONG_PRESS_TIME && !key->long_flag && !key->lock_flag)
  120.                 {
  121.                     key->long_flag = 1; // 标记长按事件待处理
  122.                     key->lock_flag = 1;
  123.                 }
  124.             }
  125.         }
  126.         else
  127.         { // 释放按键
  128.             if (key->state == 1)
  129.             {
  130.                 if (!key->long_flag && !key->lock_flag && key->press_time >= SHORT_PRESS_TIME && key->press_time < LONG_PRESS_TIME)
  131.                 {
  132.                     key->short_flag = 1;
  133.                 }
  134.                 // 释放按键时, 重置按键状态
  135.                 key->state = 0;
  136.                 key->press_time = 0;
  137.                 key->lock_flag = 0;
  138.             }
  139.         }
  140.     }
  141. }
  142. void keyService(void)
  143. {
  144.     int i;
  145.     Key_t *key = NULL;
  146.     for (i = 0; i < NUM_KEYS; i++)
  147.     {
  148.         key = &g_keys[i];
  149.         if (key->short_flag)
  150.         {
  151.             key->short_flag = 0;
  152.             // Key_onClick(key->key_code);
  153.             UART_sendBytes(RS485_USE_UART, (u8 *)key, sizeof(Key_t));
  154.         }
  155.         if (key->long_flag)
  156.         {
  157.             key->long_flag = 0;
  158.             // Key_onLongPress(key->key_code);
  159.         }
  160.     }
  161. }
  162. #endif // HAS_KEYS
复制代码


运行时输出结果
  1. [09:02:22.359]收←◆01 00 00 02 00 00 03 00 00 04 00 00 05 00 00 初始化函数输出的结果,下方所有输出是在扫描函数1秒输出一次
  2. [09:02:22.583]收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
  3. [09:02:22.804]收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
  4. [09:02:23.024]收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
  5. [09:02:23.244]收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
  6. [09:02:23.465]收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
  7. [09:02:23.685]收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
  8. [09:02:23.905]收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
  9. [09:02:24.126]收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
  10. [09:02:24.346]收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
  11. [09:02:24.566]收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
  12. [09:02:24.786]收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
  13. [09:02:25.007]收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
  14. [09:02:25.227]收←◆00 00 00 02 00 00 03 00 00 04 00 00 05 00 00
复制代码
将xdata修改为idata或删除就输出的结果是正常的
  1. [09:12:25.479]收←◆01 00 00 02 00 00 03 00 00 04 00 00 05 00 00
  2. [09:12:25.699]收←◆01 00 00 02 00 00 03 00 00 04 00 00 05 00 00
  3. [09:12:25.919]收←◆01 00 00 02 00 00 03 00 00 04 00 00 05 00 00
  4. [09:12:26.139]收←◆01 00 00 02 00 00 03 00 00 04 00 00 05 00 00
  5. [09:12:26.360]收←◆01 00 00 02 00 00 03 00 00 04 00 00 05 00 00
  6. [09:12:26.580]收←◆01 00 00 02 00 00 03 00 00 04 00 00 05 00 00
  7. [09:12:26.800]收←◆01 00 00 02 00 00 03 00 00 04 00 00 05 00 00
  8. [09:12:27.021]收←◆01 00 00 02 00 00 03 00 00 04 00 00 05 00 00
  9. [09:12:27.241]收←◆01 00 00 02 00 00 03 00 00 04 00 00 05 00 00
复制代码


LightingControlSystem.zip

52.35 KB, 下载次数: 3

回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:257
  • 最近打卡:2026-04-01 08:14:32
已绑定手机

22

主题

631

回帖

2340

积分

金牌会员

积分
2340
发表于 2026-1-5 10:00:43 | 显示全部楼层
jacks*** 发表于 2026-1-5 09:11
上传了一个工程代码,目前发现是不是初始化的原因了,在按键扫描那输出这个结构体的数据,初始化中输出一次 ...

建议不要使用位域,另外将数据打印成ASCII码,即调用printf或sprintf
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:162
  • 最近打卡:2026-03-26 08:17:55

14

主题

53

回帖

778

积分

高级会员

积分
778
发表于 2026-1-5 10:23:42 | 显示全部楼层
Ayb_*** 发表于 2026-1-5 10:00
建议不要使用位域,另外将数据打印成ASCII码,即调用printf或sprintf

那个打印只是临时调试使用不是正常使用,目前就是这个原因,改回idata就能正常使用了
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:257
  • 最近打卡:2026-04-01 08:14:32
已绑定手机

22

主题

631

回帖

2340

积分

金牌会员

积分
2340
发表于 2026-1-5 10:26:03 | 显示全部楼层
jacks*** 发表于 2026-1-5 10:23
那个打印只是临时调试使用不是正常使用,目前就是这个原因,改回idata就能正常使用了 ...

看反汇编,看看有什么区别
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-4-2 22:54 , Processed in 0.121778 second(s), 87 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表