找回密码
 注册
关于网站域名变更的通知
查看: 901|回复: 12
打印 上一主题 下一主题

求教:AT89C52记脉冲个数(C语言)

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-3-25 09:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
求教:AT89C52记脉冲个数(C语言)
: l' q8 r! F* i0 k  @/ u  t5 j8 P, l; x# d1 l# B/ N
) g( L. g: Z/ O: ?
P1.4采集信号,信号0,1,0,1,0,1,时P2.4输出1,下一个0,1,0,1,0,1时P2.4输出0,然后循环往复。
" u7 I" |" O9 p我本来计P1.4的脉冲个数,将个数模除12以此来决定输出,不过脉冲计数会溢出,这个长时间工作就会不准确,不知道能不能将记P1.4的个数,然后这个个数以12循环,这样就应该可以实现我的功能。如果可以,这个程序该怎么写?
0 T! }& E6 Z6 G0 p; }2 I  ]. N% P; p

该用户从未签到

2#
发表于 2019-3-25 10:14 | 只看该作者
6分频,循环计数清0怎么会溢出?

点评

由于外部输入端口0和1持续时间都在十几二十秒左右,所以我现在想记外部输入端口下降沿个数,然后这个个数6循环,不过参考了网上的下降沿判断大多用计时器对于我的不适用,我想就端口的值判断,不过具体的不知道怎么  详情 回复 发表于 2019-3-25 10:24

该用户从未签到

3#
 楼主| 发表于 2019-3-25 10:24 | 只看该作者
gaoxings 发表于 2019-3-25 10:14" j" M' S6 \8 l+ J. n2 Q# l
6分频,循环计数清0怎么会溢出?

) @+ [2 X8 C" Y! W% K$ l" w) I) O& {/ v由于外部输入端口0和1持续时间都在十几二十秒左右,所以我现在想记外部输入端口下降沿个数,然后这个个数6循环,不过参考了网上的下降沿判断大多用计时器对于我的不适用,我想就端口的值判断,不过具体的不知道怎么写,刚学单片机,不是很懂。; u" M+ P- I$ U6 i/ F% k

点评

你就把输入信号当做按键或开关信号接I/O口,程序不断扫描此I/O口,对高或低电平计数,计满6次令输出端口置高或低电平并清0计数变量,如此循环。  详情 回复 发表于 2019-3-25 11:18

该用户从未签到

4#
发表于 2019-3-25 11:18 | 只看该作者
码农 发表于 2019-3-25 10:24
, Z1 s! o) H7 x- {6 g! ]由于外部输入端口0和1持续时间都在十几二十秒左右,所以我现在想记外部输入端口下降沿个数,然后这个个数 ...

$ U) B1 k9 r- l你就把输入信号当做按键或开关信号接I/O口,程序不断扫描此I/O口,对高或低电平计数,计满6次令输出端口置高或低电平并清0计数变量,如此循环。, U( x, p0 v; O3 F$ x& K

点评

谢谢你的建议,下面是我编的程序,编译后不出错,不过有警告,位置是主函数里,调用子函数后,对于flag的判断哪里,显示方向控制.C(29): warning C276: constant in condition expression,然后就无法生成hex文件,  详情 回复 发表于 2019-3-25 11:28

该用户从未签到

5#
 楼主| 发表于 2019-3-25 11:28 | 只看该作者
gaoxings 发表于 2019-3-25 11:18
, g) y; A8 y+ L0 o你就把输入信号当做按键或开关信号接I/O口,程序不断扫描此I/O口,对高或低电平计数,计满6次令输出端口 ...

' R9 W/ \" I/ `3 t- I( P谢谢你的建议,下面是我编的程序,编译后不出错,不过有警告,位置是主函数里,调用子函数后,对于flag的判断哪里,显示方向控制.C(29): warning C276: constant in condition expression,然后就无法生成hex文件,麻烦看一下,不好意思,谢谢了。7 D: Y: g+ L8 J+ ^  i
#include<reg52.h>
! I, p# A9 {$ A7 \) u' Y3 msbit IN3=P1^4;/ v! }3 S+ ~" S: h+ z3 P, y' C
sbit OUT2=P2^4;+ p9 r# Q5 n# H6 ~2 N
bit old_bit;0 e5 k* [# Q4 c0 o  a" F% i" \4 v% c
unsigned char flag;
/ \0 x) ~! g' J( ivoid io_rest()$ c" D7 s( r, [2 A: m
{
6 R' r' ^- C8 w- _- L* }  if(old_bit!=IN3)& J' L* s+ R8 w" Z
  {
9 Y9 f" J! U# E/ E    old_bit=IN3;
; O$ E/ B1 K6 M        if(IN3!=1)
  a! P% i9 y; A* }& K        {
# W5 \5 @1 N5 ~& {' M9 Q( Z5 k0 N          flag=1;/ Y6 m" a& ?3 V' m- F9 M
        }+ A% r: H, n- b" i7 L" E
        else
4 z- ?* H8 s6 {# s, Q5 A$ j1 J        {
- d& o$ b+ h5 n% ^' D6 @- C: @8 c           flag=2;0 Y9 d0 Q* W# i4 G# `
        }! [" a! |* |6 k0 b/ b, q
  }
1 Q; S) y5 L) W& ^) U}: f* \% _$ u" }1 ]1 Z1 _& M$ N
void main()9 X1 ]& o; K& _  }% v
{' n$ b' U% m" J4 D7 c
  old_bit=IN3;
+ z* u) b0 e. S  while(1)2 g. z* E2 Y+ C
  {0 F" ^( J, X6 n, r3 H
    int num=0;# y. v* S4 c/ W/ @; ^, ]
         flag=0;0 O% F) j( n" P# W
        io_rest();
/ ^9 `9 C2 L, @        if(flag=1)8 G/ j$ Q. U" H+ `& r' m  K( C
        num++;; U' a2 a$ c2 J, f9 D$ \) e
        if(num==6)
4 E) U( `/ G# g        num=0;4 Q  \) _+ V& A/ L. y+ ~! H. Q
        if(0<num<=3)2 }  }) G- K5 S% Y
     OUT2=1;
' h3 y' P# x7 V: F5 d6 \& r         else
4 W3 q/ O/ y2 k$ ?         OUT2=0;
. v, P7 @4 G( Y2 n9 i# ^2 o  }" O5 d9 G/ h. |# [6 [& L: g1 i7 C* G
}" ?$ A: J/ I( c: K4 M
$ I1 @, _9 q6 F: R* U+ r

2 V0 Y6 @( V5 T3 S1 l, i; j警告是由于少打了一个=,不过仿真并没有出现预期结果,输出端一直只会输出高电平,不知道程序哪里写错了?3 X# [1 k* `# u- l5 @! U

该用户从未签到

6#
发表于 2019-3-25 13:22 | 只看该作者
/*已经实验验证通过*/
% c2 C# g! z" @7 j#include<reg52.h>  W1 w6 F( ^3 _2 I6 H
sbit IN3=P1^4;
, i! q, N1 T& ?# k5 ~6 `& ]0 Msbit OUT2=P2^4;
7 _! d& G+ ?  G9 n3 xbit flag=0;                                                //自锁标志
8 A$ G6 N9 X1 j! eunsigned char count=0,count1=0;//计数变量
% E9 D- `/ j1 M1 x: B
# T* @* e3 r7 S# V5 f1 Lvoid io_rest()
. K9 U1 m6 r6 m0 z4 y, ]{
  y4 @0 v5 w- ^        if(IN3==0)                                        //IN3低电平有效
$ j# E' q9 \# s1 b1 D5 o5 d. Z        {        
, S6 U# Y5 Z1 i                count++;                                        //消抖、消扰2 M6 f; h# \( l4 q8 B" v
                if(count>=250)                        //根据环境干扰强度10到250
+ v. A8 N. ?  R3 ^9 `- x; ~                {+ N3 n" d$ _+ ?$ A0 J$ h. u
                        count=250;                        //防止溢出
+ x) ]4 z( U; w                        if(flag==0)                        //如果自锁标志为0
5 h2 d' S. D, f, f                        {; \3 q; P* c7 i  L" Z9 P7 |% Y
                                flag=1;                        //自锁标志置1、不会在持续低电平期间重复计数
0 U4 Q% U$ L  K" A. v2 `5 J* o                                count1++;                //脉冲计数变量
; N  g8 N7 l6 m/ s8 I+ C6 I                                if(count1>=3)        //脉冲计数变量>=3
0 t' |7 m+ j$ X3 ?3 u; W! ]                                {" T$ O1 A7 f1 E+ f. A
                                        count1=0;        //脉冲计数变量清05 `+ X: u3 c" b" V9 F4 s" |
                                        OUT2=~OUT2;        //输出电平取反
2 \  w! A, D9 S4 a8 z) p                                }
) o1 L8 w* N/ f1 p                        }
, l' y! A; {4 `; C5 M% o& c* k                }; K* A9 T. j: p: o7 X
        }
8 H$ c! |& c4 V' g1 }# A/ g        else                                                        //IN3高电平& L% `. [3 `, d5 y1 L' m; c
        {5 M! ]/ F, B+ U- L
                flag=0;                                        //自锁标志清0
0 y) P2 h5 U! C0 o1 c/ c, e# P: z                count=0;                                        //消抖、消扰计数变量清08 p4 w$ C. ?3 \+ y1 R
        }; H! F7 |1 d9 C
}
  k! g5 |0 p- m1 ]. \2 }  u9 T" kvoid main()) b* S) H7 W2 ]: u
{/ Z( Q& m% ~& s5 p; V8 W
        while(1)/ {+ Y( x' T- g1 N  Q* `. [
        {) l4 t( G$ G8 U7 h6 E" b
                io_rest();
+ ~' z8 L& f0 C        }; g# u, [" Q$ Q* V) F( L
}

该用户从未签到

7#
 楼主| 发表于 2019-3-25 13:40 | 只看该作者
我刚刚试着操作并看了一下代码,那输入信号为时钟信号来说,250这个数字的选取确定了判断输入端口的最大频率,由于我外部0,1都持续十几二十几秒所以不会影响我的使用,但外部信号如果变化比较快这个就不适用了,请问我这样理解对不对?

点评

这样理解是可以的,250这个数字是以主循环速度设定的,对于12T单片机也就是大约2ms,大于一般干扰持续时间,如果用1T单片机,这个数字还要扩大10倍,如果主循环任务多就要减小这个数字,如果输入是TTL信号,这一部分  详情 回复 发表于 2019-3-25 14:07

该用户从未签到

8#
发表于 2019-3-25 14:07 | 只看该作者
码农 发表于 2019-3-25 13:402 C2 a4 V/ O) N4 l' e
我刚刚试着操作并看了一下代码,那输入信号为时钟信号来说,250这个数字的选取确定了判断输入端口的最大频 ...

$ R; Y) |/ s- V这样理解是可以的,250这个数字是以主循环速度设定的,对于12T单片机也就是大约2ms,大于一般干扰持续时间,如果用1T单片机,这个数字还要扩大10倍,如果主循环任务多就要减小这个数字,如果输入是TTL信号,这一部分代码可以不要。总之由具体需求确定,不是一成不变的。0 ?9 j/ ~9 ^# A& I

点评

刚刚调试发现一个问题就是如果一开始就输入的低电平的话,0,1,0,1输出信号就会变,这之后的会变为正常的6循环  详情 回复 发表于 2019-3-25 14:17

该用户从未签到

9#
 楼主| 发表于 2019-3-25 14:17 | 只看该作者
gaoxings 发表于 2019-3-25 14:07
" W4 n- [) g+ B& b% N# Y# H这样理解是可以的,250这个数字是以主循环速度设定的,对于12T单片机也就是大约2ms,大于一般干扰持续时 ...

7 w# h. z# D. H0 e9 ~5 c刚刚调试发现一个问题就是如果一开始就输入的低电平的话,0,1,0,1输出信号就会变,这之后的会变为正常的6循环
# c, x% L1 F+ P2 f6 A$ F0 n/ d$ I

点评

这样改一下就可以解决初始计数问题 void io_rest() { if(IN3==0) { count++; if(count>=250) {  详情 回复 发表于 2019-3-25 14:34

该用户从未签到

10#
发表于 2019-3-25 14:34 | 只看该作者
码农 发表于 2019-3-25 14:174 D7 e# z5 ^7 Y- O
刚刚调试发现一个问题就是如果一开始就输入的低电平的话,0,1,0,1输出信号就会变,这之后的会变为正常 ...

7 X" k: k( j- L7 M1 N4 H这样改一下就可以解决初始计数问题
( C" I+ v- Y! q4 lvoid io_rest()' k: B8 N; L4 O% {5 Q5 `' B
{! J! |1 N9 [0 ~$ _6 h$ Z* W! N8 B
        if(IN3==0)        4 v) I) y' p7 Y0 j, b5 f$ u
        {        
- g( x0 |6 w  N) e                count++;        ) d2 w5 }3 n) g, l
                if(count>=250)        
! r) P$ N9 T2 w2 i( I                {
0 y% }) D; u0 t% V3 t5 [- U4 H6 N                        count=250;, L! D! c" R0 f% c0 c
                        if(flag==0)               
+ ?7 I  e  Q7 u* F# n/ }# F8 f                        {/ R8 x# |. f0 h. ]4 _2 v
                                flag=1;        
) G& y. d# J2 e                                count1++;               
5 o. J* s+ @+ v, O; x                                if(count1>=4)        $ U- Q! t! G4 ?- `- ^) m
                                {
% R6 S" F) x" R/ V# t9 j4 D                                        count1=1;        6 o# y8 e( V* }6 A
                                        OUT2=~OUT2;        
" z2 Z, c! s/ E6 B  f6 Q- I: u) f                                }
/ M. k: k* [  w( P2 ~  Y                        }  P+ q, I+ h+ }/ z: l4 N
                }  S' I$ y# \5 j9 m' ?
        }
6 `) c0 s5 V* _3 i0 L        else                                                0 @+ e: @0 b1 M% `. q# O: A' g
        {
& a  j$ i- N, ?- S( i                flag=0;                                
6 w" X' d' [. |# U3 j7 V  h# l                count=0;                                
5 ?. s$ o9 ^+ }        }& x& s1 V& t( Z% W( |
}# y! F: J$ ?' U; x) Y2 O* c1 |/ U* ~

点评

谢谢大神,太感谢了  详情 回复 发表于 2019-3-25 14:40

该用户从未签到

11#
 楼主| 发表于 2019-3-25 14:40 | 只看该作者
gaoxings 发表于 2019-3-25 14:34
& M4 ^+ O6 k7 N7 p- q. K1 n这样改一下就可以解决初始计数问题( v; |% K1 W- F7 c3 a
void io_rest()
' q  {( O1 @7 r3 f9 ]" V9 x  T{
/ @; h2 }' v4 p# o" u) w
谢谢大神,太感谢了
/ `& q1 H/ Z, J, j

该用户从未签到

12#
发表于 2019-3-25 15:20 | 只看该作者
好帖子啊

“来自电巢APP”

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

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-7-24 01:30 , Processed in 0.156250 second(s), 33 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

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