找回密码
 立即注册
楼主: dongfang

关于STC8H8K 64U按键的迷惑

[复制链接]

48

主题

87

回帖

907

积分

高级会员

积分
907
 楼主| 发表于 2026-9-24 10:59:29 | 显示全部楼层
jrc*** 发表于 2026-9-24 10:14
另外,Key_Tick()里的那些变量尽量要显示初始化,如果IDATAt和XDATA没有统一清0,上电后有可能是随机值的 ...

另外,Key_Tick()里的那些变量尽量要显示初始化,如果IDATAt和XDATA没有统一清0,上电后有可能是随机值的,然后if(S==x)那里可能就没有命中的
如果没有命中,应该按键不起作用,不会是长按、短按、双击都会执行,
回复

使用道具 举报 送花

48

主题

87

回帖

907

积分

高级会员

积分
907
 楼主| 发表于 2026-9-24 11:03:24 | 显示全部楼层
jrc*** 发表于 2026-9-24 09:30
"P33准双向口",初始化为1了吗

后面补充:忽略我这段话。上电P3默认是1。

P33初始化置一了,而且万用表量过了就是高电平
回复

使用道具 举报 送花

已绑定手机

872

主题

1万

回帖

2万

积分

管理员

积分
25428
发表于 2026-9-24 23:20:11 | 显示全部楼层
截图202609242320067631.jpg
回复

使用道具 举报 送花

已绑定手机

872

主题

1万

回帖

2万

积分

管理员

积分
25428
发表于 2026-9-24 23:20:28 | 显示全部楼层

这个帖子讨论的是 STC8H8K64U 上移植江协科技按键状态机程序失败的问题。我先把问题本质梳理清楚。

问题分析

这个帖子楼主遇到的现象是:同一个江协科技状态机按键程序,在 STC32G12K128 上运行正常,移植到 STC8H8K64U 上后,无论长按、短按、双击都会触发按键动作(判断命中)。

结合帖子中各位的回复,可能的原因有以下几个方面:

1. 变量未显式初始化(重点关注)

论坛用户 jrc 的回复很关键:"Key_Tick() 里的那些变量尽量要显示初始化,如果 IDATA 和 XDATA 没有统一清 0,上电后有可能是随机值的"。

  • Keil C51 中,对于 DATA/IDATA 段,C 启动代码 STARTUP.A51 默认是会把变量清 0 的;但对于 XDATA 段,是否清 0 取决于工程设置。
  • 江协的代码中若用了 static uint16_t Time[x] 这类静态数组未赋初值,而该数组恰被分配到 XDATA 且启动代码未清零,则上电后初值是随机数。
  • 这会导致状态机的索引/计时判断 if(S[i] == x) 出现非预期的"命中",表现为"随便怎么按都执行按键动作"。

建议:将这些静态数组显式初始化,例如 static unsigned int Time[4] = {0};。

注意:楼主 dong 反驳说"如果不命中应该按键不起作用,而不是长短按都执行"——这个反驳也有道理,所以变量初始化可能不是唯一原因,需要结合下面几点一起排查。

2. 端口模式设置

  • STC8H 系列与 STC32G 系列在 I/O 口上电默认模式上是一致的(准双向口),但代码中若显式配置了 P3 模式,需要确认配置正确。
  • 楼主已确认 P3.3 初始化为准双向口并置 1,万用表实测为高电平,所以硬件端口状态本身没问题。

3. 时钟频率不同导致的时间基准差异

这是我认为最可能的根因之一:

  • 江协的状态机按键依赖 Key_Tick 的调用周期来做消抖和长短按判定。
  • 楼主在 STC32G 上运行良好,是因为 STC32G 与 STC8H 的实际运行主频/定时器时基可能不同。
  • 移植后如果 定时器 1ms 中断的实际周期发生了变化(例如系统时钟从 24MHz 变成 11.0592MHz,或 ISP 下载时选择的时钟频率不同),那么 Key_Tick 的实际调用间隔就不再是设计值,消抖阈值全部失效,从而造成"短按当长按""单击被判双击"等乱象。

建议:用示波器或翻转 I/O 实测定时器中断的真实周期,确认 Key_Tick 是否严格每 1ms 被调用一次;同时确认 STC8H 的 系统时钟频率(在 ISP 下载软件中查看"时钟频率"设置,默认常用 24MHz 或 11.0592MHz)。

4. 状态机对"释放沿"的依赖

江协按键程序采用状态机 + 计次方式,依赖对按键按下沿和释放沿的准确采样。如果采样周期远大于抖动时间或远小于抖动时间,都会误判。楼主提到"改为 20ms 读一次就有单击遗漏",正说明采样周期必须匹配消抖时间窗(通常 10~20ms 消抖,但状态机内部计数器也要相应匹配)。

结论与建议

综合这个帖子,我给您的排查建议顺序是:

排查项 具体做法
① 变量初始化 把 Key_Tick 内所有 static 数组/变量显式赋初值 = {0} 或 = 0
② 实际时钟频率 用 ISP 软件确认 STC8H 下载时选择的系统时钟;确认定时器计算是否按该频率
③ 中断真实周期 用 I/O 翻转 + 示波器实测 Key_Tick 是否严格 1ms 调用一次
④ 采样周期匹配 消抖采样周期需与状态机内部计数器阈值匹配,不能随意改 20ms
⑤ 参考最小实现 论坛用户 wul 已给出一个最简长/短按参考程序,可先用它验证硬件与时基

关于您提到的"把布丁橘长按键程序去掉 10ms 延时、改为定时器每 10ms 读取":思路是对的,把阻塞式延时改成时隙轮询是正确方向,但要注意——Key_Tick 的内部计数阈值是按原来调用周期设计的,改成 10ms 调用一次,阈值也应同步折算,否则长短按判定会整体偏移。

如果您能提供:① Keil 工程里 XDATA 是否清 0 的设置、② STC8H 下载时的实际系统时钟频率、③ Key_Tick 定时器的配置代码,我可以帮您进一步精准定位。是否需要我基于手册给您一份不依赖复杂状态机、稳定可靠的长短按按键例程(放在 1ms 定时器中断里扫描,主循环只读键值)?


🔍 搜索 "STC 单片机 论坛 帖子"

⏱️ 查找用时 2.1s | 总回答用时 8.6s

回复

使用道具 举报 送花

39

主题

178

回帖

1245

积分

金牌会员

积分
1245
发表于 2026-9-25 22:21:45 | 显示全部楼层
wul*** 发表于 2026-9-24 08:42
给你一个最基本的长、短按键程序参考

这个程序能用吗?I=601的时候 怎么能回到I = 0?如果按键时间大于300小于600.那不就是无效按键?BUG太多
回复

使用道具 举报 送花

已绑定手机

11

主题

484

回帖

1362

积分

金牌会员

积分
1362
发表于 2026-9-25 22:54:34 | 显示全部楼层
zhang*** 发表于 2026-9-25 22:21
这个程序能用吗?I=601的时候 怎么能回到I = 0?如果按键时间大于300小于600.那不就是无效按键?BUG太多
...

此代码是从一个时钟按键代码缩写以示意。原代码短按加/减,长按连加/减。长按超过600计数i等于300,使长按超过600后每隔300重复计次。按键松手计数i归0,由于缩写代码不严谨,留下BUG。谢谢指正。
回复

使用道具 举报 送花

48

主题

87

回帖

907

积分

高级会员

积分
907
 楼主| 发表于 2026-10-1 10:59:56 | 显示全部楼层
神*** 发表于 2026-9-24 23:20
这个帖子讨论的是 STC8H8K64U 上移植江协科技按键状态机程序失败的问题。我先把问题本质梳理清楚。
问题分 ...

非常感谢你详细而深入的分析解答,根据你的分析第一条可能最大,我试一试,再给你汇报,
第二条,我明确确认过,不会有什么问题,弱弱的问一句,你说的P3模式是什么模式
第三条,我也确认过,系统时钟使用40M,定时器1ms配置也确认过,也不会出问题
第四条,调成20ms,会出现漏击,是布丁橘长的,你说的“阈值也应同步折算”,我没有明白什么意思,理论上,在定时器里更为准确,原来10ms延时存在不确定性,(依靠while循环没有延时)因此会造成双击与长按出现偏移,一般对单击不会造成什么影响,回头我再看看布丁橘长对单击最短时间有严格的要求吗
最后对你的解答再次表示衷心的感谢,祝您国庆快乐,阖家欢乐
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2026-11-7 12:20 , Processed in 0.088829 second(s), 75 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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