AT89C52记脉冲个数(C语言)
我本来计P1.4的脉冲个数,将个数模除12以此来决定输出,不过脉冲计数会溢出,这个长时间工作就会不准确,不知道能不能将记P1.4的个数,然后这个个数以12循环,这样就应该可以实现我的功能。如果可以,这个程序该怎么写?
/*已经实验验证通过*/
#include<reg52.h>
sbit IN3=P1^4;
sbit 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循环,不过参考了网上的下降沿判断大多用计时器对于我的不适用,我想就端口的值判断,不过具体的不知道怎么写,刚学单片机,不是很懂。
你就把输入信号当做按键或开关信号接I/O口,程序不断扫描此I/O口,对高或低电平计数,计满6次令输出端口置高或低电平并清0计数变量,如此循环。
如果可以改电路的话,可以把输入接到外部中断引脚,这样有变化了就产生一个中断,也不容易漏数
谢谢你的建议,下面是我编的程序,编译后不出错,不过有警告,位置是主函数里,调用子函数后,对于flag的判断哪里,显示方向控制.C(29): warning C276: constant in condition expression,然后就无法生成hex文件,麻烦看一下,不好意思,谢谢了。
#include<reg52.h>
sbit IN3=P1^4;
sbit 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<num<=3)
OUT2=1;
else
OUT2=0;
}
}
警告是由于少打了一个=,不过仿真并没有出现预期结果,输出端一直只会输出高电平,不知道程序哪里写错了?
非常感谢你的帮助,我刚刚试着操作并看了一下代码,那输入信号为时钟信号来说,250这个数字的选取确定了判断输入端口的最大频率,由于我外部0,1都持续十几二十几秒所以不会影响我的使用,但外部信号如果变化比较快这个就不适用了,请问我这样理解对不对,真的很谢谢你。
这样理解是可以的,250这个数字是以主循环速度设定的,对于12T单片机也就是大约2ms,大于一般干扰持续时间,如果用1T单片机,这个数字还要扩大10倍,如果主循环任务多就要减小这个数字,如果输入是TTL信号,这一部分代码可以不要。总之由具体需求确定,不是一成不变的。
刚刚调试发现一个问题就是如果一开始就输入的低电平的话,0,1,0,1输出信号就会变,这之后的会变为正常的6循环
把初始sum+=-1就行了,不好意思啊。
错了,是count1=-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<reg52.h>
sbit IN3=P1^4;
sbit 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;
}
}
}
}
我已经想出来,不好意思打扰了。
好帖,必须支持一下!
小编是做项目还是学习?
计算脉冲有专门寄存器,或者用中断引脚也可以。
51单片机计脉冲个数,最好使用外部中断来做。