我入职刚一个月,在做一个小项目开发时遇到了如下的问题,今天贴出来,与大家分享,同时也是对我的鞭策。希望大家能够不惜笔墨,畅所欲言。电路图在下面贴着。
发现问题:
前几天在做一个风扇的小项目,我在仿真器上边写边测……,两天后,我感觉全部功能已经都实现了,而且效果也比较好,于是烧了芯片准备测试,这一烧片测试,问题来了:除了能用power键开机完,其他按键功能全部没用(按其他键根本没反应)。
分析问题:
1.由于是新手(7月份刚毕业,没有完整的产品开发经验),当发现这个问题后,我的想法是:在仿真器上运行良好,烧到芯片里不正常,可能是芯片质量太差了,于是连烧了好几个,但都不行。
请教了前辈后,他们告诉我这种问题一般还是程序的问题,跟芯片没关系。
2.然后,我的第一反应是修改 code option(sonix 8 bit mcu编程软件里的东西) 里的一些相关选项,改了后再烧片子测试问题还是没解决,连续改了好几次code option 烧出来的片子还是同样的问题.
3.反正还找不出问题,于是我拿着有问题的样机在那试。(开机后有个定时关机的动作,我为了测试方便把2 hour关机改成了20 s)发现开机后20s 就自动关机了。这给我了一个提示:其他程序模块运行正常。结合 按键没反应的现象,我把问题的重点集中在按键扫描模块了(其实根据除了power键其他键根本没反应,我早都应该检测按键程序了,但是因为在仿真器上运行正常,就忽略了)
经过仔细的检测按键程序,我终于找到了按键程序中的一个错误(@20 处):@20 处少了等待。在扫描按键前要把端口设为输入上拉模式,然后等待一段时间(20us左右)待数据稳定后 再读取端口信息,由于在读p2口时少了这个等待时间p2口的信息没有正确读取 于是导致后面程序判断错误,没能把按键信息存入event fifo 。
解决问题:
当加上@20 处的等待时间后 ,再烧片子测试,功能恢复正常!
经过此次问题后,我的自我检讨:
1.写程序一定要仔细,不能马虎。我在@10 处都有等待,但在@20 处却少了这个等待,说明我知道这个等待的重要性,只是太慌张了给忘了。
2.端口在输入模式下读取按键信息时一定要经过等待 等端口状态稳定后在读取,这个问题一定要牢记。特别是在I/O口复用时。
3.前事不忘,后事之师。其实在前面写暖风机的时候,我已经发现在I/O口复用时,扫描按键如果等待时间处理不好,就会出现很多问题。这次也是 I/O口复用 我却没在按键扫描那里多做检查。下次应该不会忘了。
4.仿真成功并不能代表程序没有问题,烧出来片子测试成功才代表程序没有问题。
HH-32300 按键扫描程序
key_scan:
mov a,#00001110b
mov p2ur,a ;上拉
mov a,#00110000b
or p2,a;mov
mov a,#11110001b
mov p2m,a ;输入模式
b0mov r,#30 ;@10
decms r
jmp $-1
mov a,p2
and a,#00001110b
mov new_key,a
mov a,#00110000b
mov p2ur,a ;上拉
mov a,#11001111b;0001
mov p2m,a ;输入模式
mov a,#11110001b
and p2,a
b0mov r,#30 ;@20问题所在
decms r
jmp $-1
mov a,p2
and a,#00110000b
or new_key,a
bts0 f_key_rel
jmp key_scan10 ;检测放键
jmp key_scan20 ;检测按键
key_scan10:
mov a,new_key
cmprs a,#00111110b
jmp key_scan30
incms key_cnt
mov a,key_cnt
cmprs a,#5 ;20ms放键检测
jmp key_scan90
bclr f_key_rel
jmp key_scan30
key_scan20:
mov a,new_key
cmprs a,old_key
jmp key_scan21
incms key_cnt
mov a,key_cnt
cmprs a,#8 ;32ms消抖
jmp key_scan90
clr key_cnt
jmp key_scan40
key_scan21:
mov_ old_key,new_key
key_scan30:
clr key_cnt
jmp key_scan90
key_scan40:
mov a,new_key ;cleaner键3s长按
cmprs a,#00011110b
jmp key_scan40_0
incms key_cnt0
mov a,key_cnt0
cmprs a,#80
jmp key_scan90
clr key_cnt0
jmp key_scan44
key_scan40_0: ;replace键3s长按
clr key_cnt0
mov a,new_key
cmprs a,#00111010b
jmp key_scan40_1
incms key_cnt1
mov a,key_cnt1
cmprs a,#80
jmp key_scan90
clr key_cnt1
jmp key_scan45
key_scan40_1:
clr key_cnt1
mov a,new_key
cje a,#00111110b,key_scan90 ;无键按下不作处理
cje a,#00111100b,key_scan41
cje a,#00101110b,key_scan42
cje a,#00110110b,key_scan43
;cje a,#00011110b,key_scan44
;cje a,#00111010b,key_scan45
;cje a,#00100110b,key_scan46
jmp key_scan90
key_scan41:
mov_ event_buf,#1 ;POWER键键值1
jmp key_scan80
key_scan42:
mov_ event_buf,#2 ;speed键键值2
jmp key_scan80
key_scan43:
mov_ event_buf,#3 ;timer键键值3
jmp key_scan80
key_scan44:
mov_ event_buf,#4 ;cleaner键值4
jmp key_scan80
key_scan45:
mov_ event_buf,#5 ;replace键键值5
jmp key_scan80
;key_scan46:
; mov_ event_buf,#6 ;speed+timer键键值6
; jmp key_scan80
key_scan80:
bset f_key_rel
call wrt_FIFO ;将键值写入event_FIFO
key_scan90:
ret |