完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
P1.4采集信号,信号0,1,0,1,0,1,时P2.4输出1,下一个0,1,0,1,0,1时P2.4输出0,然后循环往复。
我本来计P1.4的脉冲个数,将个数模除12以此来决定输出,不过脉冲计数会溢出,这个长时间工作就会不准确,不知道能不能将记P1.4的个数,然后这个个数以12循环,这样就应该可以实现我的功能。如果可以,这个程序该怎么写? |
|
相关推荐
18个回答
|
|
本帖最后由 wulinwl 于 2017-4-23 14:44 编辑
zxn1314520 发表于 2017-4-23 09:19 /*已经实验验证通过*/ #include ***it IN3=P1^4; ***it OUT2=P2^4; bit flag=0; //自锁标志 unsigned char count=0,count1=0;//计数变量 void io_rest() { if(IN3==0) //IN3低电平有效 { count++; //消抖、消扰 if(count>=250) //根据环境干扰强度10到250 { count=250; //防止溢出 if(flag==0) //如果自锁标志为0 { flag=1; //自锁标志置1、不会在持续低电平期间重复计数 count1++; //脉冲计数变量 if(count1>=3) //脉冲计数变量>=3 { count1=0; //脉冲计数变量清0 OUT2=~OUT2; //输出电平取反 } } } } else //IN3高电平 { flag=0; //自锁标志清0 count=0; //消抖、消扰计数变量清0 } } void main() { while(1) { io_rest(); } }
最佳答案
|
|
|
|
6分频,循环计数清0这么会溢出?
|
|
|
|
谢谢你的帮助,由于外部输入端口0和1持续时间都在十几二十秒左右,所以我现在想记外部输入端口下降沿个数,然后这个个数6循环,不过参考了网上的下降沿判断大多用计时器对于我的不适用,我想就端口的值判断,不过具体的不知道怎么写,刚学单片机,不是很懂。 |
|
|
|
zxn1314520 发表于 2017-4-22 20:19 你就把输入信号当做按键或开关信号接I/O口,程序不断扫描此I/O口,对高或低电平计数,计满6次令输出端口置高或低电平并清0计数变量,如此循环。 |
|
|
|
如果可以改电路的话,可以把输入接到外部中断引脚,这样有变化了就产生一个中断,也不容易漏数
|
|
|
|
谢谢你的建议,下面是我编的程序,编译后不出错,不过有警告,位置是主函数里,调用子函数后,对于flag的判断哪里,显示方向控制.C(29): warning C276: constant in condition expression,然后就无法生成hex文件,麻烦看一下,不好意思,谢谢了。 #include ***it IN3=P1^4; ***it OUT2=P2^4; bit old_bit; unsigned char flag; void io_rest() { if(old_bit!=IN3) { old_bit=IN3; if(IN3!=1) { flag=1; } else { flag=2; } } } void main() { old_bit=IN3; while(1) { int num=0; flag=0; io_rest(); if(flag=1) num++; if(num==6) num=0; if(0 else OUT2=0; } } |
|
|
|
zxn1314520 发表于 2017-4-23 09:19 警告是由于少打了一个=,不过仿真并没有出现预期结果,输出端一直只会输出高电平,不知道程序哪里写错了? |
|
|
|
非常感谢你的帮助,我刚刚试着操作并看了一下代码,那输入信号为时钟信号来说,250这个数字的选取确定了判断输入端口的最大频率,由于我外部0,1都持续十几二十几秒所以不会影响我的使用,但外部信号如果变化比较快这个就不适用了,请问我这样理解对不对,真的很谢谢你。 |
|
|
|
本帖最后由 wulinwl 于 2017-4-23 17:01 编辑
zxn1314520 发表于 2017-4-23 15:51 这样理解是可以的,250这个数字是以主循环速度设定的,对于12T单片机也就是大约2ms,大于一般干扰持续时间,如果用1T单片机,这个数字还要扩大10倍,如果主循环任务多就要减小这个数字,如果输入是TTL信号,这一部分代码可以不要。总之由具体需求确定,不是一成不变的。 |
|
|
|
wulinwl 发表于 2017-4-23 16:57 刚刚调试发现一个问题就是如果一开始就输入的低电平的话,0,1,0,1输出信号就会变,这之后的会变为正常的6循环 |
|
|
|
把初始sum+=-1就行了,不好意思啊。 |
|
|
|
|
|
|
|
这样改一下就可以解决初始计数问题 void io_rest() { if(IN3==0) { count++; if(count>=250) { count=250; if(flag==0) { flag=1; count1++; if(count1>=4) { count1=1; OUT2=~OUT2; } } } } else { flag=0; count=0; } } |
|
|
|
谢谢,不好意思麻烦你了,我现在在这个基础上再加一个功能,就是p2.3端口输出,p2.3一直输出脉冲,当p1.4口为低电平时,延时20s,然后继续输出脉冲,单个的我会写,就是一直输出脉冲,判断p1.4的值,如果为0,延时程序使用,不过在两个叠加后发现往往只能实现一个功能 这是单个p2.3端口程序 #include ***it IN3=P1^4; ***it OUT1=P2^3; void delay_ms(unsigned int ms) { unsigned int a,b; for(a=ms;a>0;a--) for(b=124;b>0;b--); } void delayms(void) { unsigned char a,b; for(b=71;b>0;b--) for(a=2;a>0;a--); } void io_mc() { while(1) { OUT1=1; delayms(); OUT1=0; delayms(); if(IN3==0) delay_ms(20000); } } void main() { io_mc(); } 这是我尝试两个共同作用的程序 void main { while(1) { OUT1=1; delayms(); OUT1=0; delayms(); if(IN3==0) { count++; if(count>=250) { count=250; if(flag==0) { flag=1; count1++; if(count1>=3) { count1=0; OUT2=~OUT2; } } } delay_ms(20000); } else { flag=0; count=0; } } } } |
|
|
|
zxn1314520 发表于 2017-4-23 22:23 我已经想出来,不好意思打扰了。 |
|
|
|
|
|
|
|
|
|
|
|
51单片机计脉冲个数,最好使用外部中断来做。
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
【每周推荐】采用11代Intel CPU,基于youyeetoo X1开发板搭建少儿AI智能STEAM积木平台
776 浏览 0 评论
2265 浏览 2 评论
【youyeetoo X1 windows 开发板体验】+ 影音处理和AI模型移植
2124 浏览 5 评论
I.MX6ULL-飞凌 ElfBoard ELF1板卡- 移植zbar的方法
1682 浏览 0 评论
2786 浏览 3 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
5518 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-4-19 15:52 , Processed in 0.546040 second(s), Total 55, Slave 50 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号