ly1350
发表于 2024-2-28 08:12:35
电子DIY小家 发表于 2024-2-28 08:01
晚点我给你发一个好的按键检测函数
好的,谢谢。但是,我还想知道,我这种处理,除了浪费系统资源,按道理不应该死机啊{:titter:}
ly1350
发表于 2024-2-28 08:13:05
zhudean11 发表于 2024-2-28 05:31
代码能全发出来么?不全不好找问题啊
以下是完整的代码。但是,一按按键就停止计数了。要去掉第255行的 Delay10ms();
就运行正常。
ly1350
发表于 2024-2-28 08:14:42
zhudean11 发表于 2024-2-28 05:31
代码能全发出来么?不全不好找问题啊
#include<STC8H.H>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar dis={0,0,':',0,0};
uchar count=0,s=0,m=0,h=0;
void Led_Init()
{
P2M0 |= 0x7f; P2M1 &= ~0x7f; //设置P2.0-P2.6为推挽输出
P3M0 = (P3M0 & ~0x78) | 0x80; P3M1 &= ~0xf8; //设置P3.3-P3.6为高阻输入;p37为推挽输出
P33=1; //DG1
P34=1; //DG2
P35=1; //DG3
P36=1; //DG4
P37=0; //Pd
P20=0; //段A
P21=0; //段B
P22=0; //段C
P23=0; //段D
P24=0; //段E
P25=0; //段F
P26=0; //段G
}
void Delay1ms(void) //@24.000MHz
{
unsigned char data i, j;
_nop_();
i = 32;
j = 40;
do
{
while (--j);
} while (--i);
}
void Delay10ms(void) //@24.000MHz
{
unsigned char data i, j;
i = 234;
j = 115;
do
{
while (--j);
} while (--i);
}
void Display(unsigned char val)
{
unsigned char i=0;
for(i=0;i<5;i++)
{
switch(val)
{
case 0 :
P20=1;
P21=1;
P22=1;
P23=1;
P24=1;
P25=1;
break;
case 1 :
P21=1;
P22=1;
break;
case 2 :
P20=1; //段A
P21=1; //段B
P22=0; //段C
P23=1; //段D
P24=1; //段E
P25=0; //段F
P26=1; //段G
break;
case 3 :
P20=1; //段A
P21=1; //段B
P22=1; //段C
P23=1; //段D
P24=0; //段E
P25=0; //段F
P26=1; //段G
break;
case4 :
P20=0; //段A
P21=1; //段B
P22=1; //段C
P23=0; //段D
P24=0; //段E
P25=1; //段F
P26=1; //段G
break;
case5 :
P20=1; //段A
P21=0; //段B
P22=1; //段C
P23=1; //段D
P24=0; //段E
P25=1; //段F
P26=1; //段G
break;
case6 :
P20=1; //段A
P21=0; //段B
P22=1; //段C
P23=1; //段D
P24=1; //段E
P25=1; //段F
P26=1; //段G
break;
case7 :
P20=1; //段A
P21=1; //段B
P22=1; //段C
P23=0; //段D
P24=0; //段E
P25=0; //段F
P26=0; //段G
break;
case8 :
P20=1; //段A
P21=1; //段B
P22=1; //段C
P23=1; //段D
P24=1; //段E
P25=1; //段F
P26=1; //段G
break;
case 9 :
P20=1; //段A
P21=1; //段B
P22=1; //段C
P23=1; //段D
P24=0; //段E
P25=1; //段F
P26=1; //段G
break;
case 'a' :
P20=1; //段A
P21=1; //段B
P22=1; //段C
P23=0; //段D
P24=1; //段E
P25=1; //段F
P26=1; //段G
break;
case 'b' :
P20=0; //段A
P21=0; //段B
P22=1; //段C
P23=1; //段D
P24=1; //段E
P25=1; //段F
P26=1; //段G
break;
case 'c' :
P20=1; //段A
P21=0; //段B
P22=0; //段C
P23=1; //段D
P24=1; //段E
P25=1; //段F
P26=0; //段G
break;
case 'd' :
P20=0; //段A
P21=1; //段B
P22=1; //段C
P23=1; //段D
P24=1; //段E
P25=0; //段F
P26=1; //段G
break;
case 'e' :
P20=1; //段A
P21=0; //段B
P22=0; //段C
P23=1; //段D
P24=1; //段E
P25=1; //段F
P26=1; //段G
break;
case 'f' :
P20=1; //段A
P21=0; //段B
P22=0; //段C
P23=0; //段D
P24=1; //段E
P25=1; //段F
P26=1; //段G
break;
case ':' : P37=1;break;
default : P26=1; //段G
}
switch(i)
{
case 0 : P33=0;break;
case 1 : P34=0;break;
case 2 : P34=0;break;
case 3 : P35=0;break;
case 4: P36=0;break;
}
Delay1ms();
Led_Init();
}
}
void Timer1_Init(void) //1毫秒@24.000MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x40; //设置定时初始值
TH1 = 0xA2; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1=1;
EA=1;
}
void main()
{
uchar i=0,f=0;
P3M0 &= ~0x04; P3M1 &= ~0x04; //设置P32为标准io口
EX0=0;
P32=1;
Timer1_Init();
while(1)
{
if(P32==0)
{
Delay10ms();
if(P32==0)
{
f++;
while(!P32);
}
}
if(f>=3) f=0;
if(count>=100)
{
count=0 ;
s+=1;
}
if(s>=60)
{
s=0;
m++;
}
if(m>=60)
{
m=0;
h++;
}
if(h>=24)h=0 ;
switch(f)
{
case 0 :
dis=s/10;
dis=s%10;
dis=count/10;
dis=count%10;
break;
case 1 :
dis=h/10;
dis=h%10;
dis=m/10;
dis=m%10;
break;
case 2 :
dis=m/10;
dis=m%10;
dis=s/10;
dis=s%10;
break;
default : break;
}
}
}
void Timer1_Isr() interrupt 3
{
Display(dis);
count++;
}
ly1350
发表于 2024-2-28 08:28:07
我这个菜鸟写的程序,有点不好意思往上发{:shy:}
ly1350
发表于 2024-2-28 09:31:21
目前我自己的解决方法是:
设置一个变量temp,记录两次按键端口检测为低之间的时间,如果大于20ms,就认定不是抖动。经测试,去抖问题解决了。
但是,我的疑问还在,为什么用软件延时,程序就死机呢?还是没搞明白{:dizzy:}
ly1350
发表于 2024-2-28 09:33:32
本帖最后由 ly1350 于 2024-2-28 09:37 编辑
我的解决办法:(修改部分)void main()
{
uchar i=0,f=0,temp=0;
P3M0 &= ~0x04; P3M1 &= ~0x04; //设置P32为标准io口
P32=1;
Timer1_Init();
while(1)
{
if((P32==0)&&(temp==0))
temp=count;
else if((P32==0)&&(count-temp)>20)
{
f++;
while(!P32);
}
xxxevery
发表于 2024-3-12 12:04:37
Delay10ms这个函数你用的是STCISP软件生成的,STC8H单片机应该用Y6指令集,你用的是Y5指令集了
ly1350
发表于 2024-3-12 16:01:21
xxxevery 发表于 2024-3-12 12:04
Delay10ms这个函数你用的是STCISP软件生成的,STC8H单片机应该用Y6指令集,你用的是Y5指令集了 ...
我这个思路不对。用定时器搞
zhaoliang3399
发表于 2024-3-12 16:09:59
本帖最后由 zhaoliang3399 于 2024-3-12 16:15 编辑
你的定时器太忙了,1ms中断里调用的Display(dis)子程序大于1ms,你觉的你的主程序里10MS的延时还有时间进行吗,1ms的中断里加一个1ms的软延时你想想吧,你后用改的是用定时器计数,所以就可以了
ly1350
发表于 2024-3-12 20:20:42
zhaoliang3399 发表于 2024-3-12 16:09
你的定时器太忙了,1ms中断里调用的Display(dis)子程序大于1ms,你觉的你的主程序里10MS的延时还有时间进行 ...
我写的是标准的菜鸟程序{:4_167:}