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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
求教:AT89C52记脉冲个数(C语言); D- c1 X$ l# v. j* [' J2 a
5 Z7 P4 y$ e5 B/ u& y

, C2 v5 G* x, V0 x1 Q4 A5 V. |$ [P1.4采集信号,信号0,1,0,1,0,1,时P2.4输出1,下一个0,1,0,1,0,1时P2.4输出0,然后循环往复。+ n7 h7 o# @; Q, W
我本来计P1.4的脉冲个数,将个数模除12以此来决定输出,不过脉冲计数会溢出,这个长时间工作就会不准确,不知道能不能将记P1.4的个数,然后这个个数以12循环,这样就应该可以实现我的功能。如果可以,这个程序该怎么写?
1 a" [/ o7 ?& w! t

该用户从未签到

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:148 w' r. i4 T& S# Y' }: }
6分频,循环计数清0怎么会溢出?

8 ^& @3 M( S+ q1 `3 i6 m% \* M由于外部输入端口0和1持续时间都在十几二十秒左右,所以我现在想记外部输入端口下降沿个数,然后这个个数6循环,不过参考了网上的下降沿判断大多用计时器对于我的不适用,我想就端口的值判断,不过具体的不知道怎么写,刚学单片机,不是很懂。& l0 d; n* v( P( g) S% s2 J( ?5 b% l

点评

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

该用户从未签到

4#
发表于 2019-3-25 11:18 | 只看该作者
码农 发表于 2019-3-25 10:24
0 {4 x3 Z7 p4 a4 o3 {# Q由于外部输入端口0和1持续时间都在十几二十秒左右,所以我现在想记外部输入端口下降沿个数,然后这个个数 ...
+ P& B" b% }% J0 a) j
你就把输入信号当做按键或开关信号接I/O口,程序不断扫描此I/O口,对高或低电平计数,计满6次令输出端口置高或低电平并清0计数变量,如此循环。
" T1 `7 Z% o2 R6 _5 _

点评

谢谢你的建议,下面是我编的程序,编译后不出错,不过有警告,位置是主函数里,调用子函数后,对于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:183 B% d, X% y4 j; P8 i. M
你就把输入信号当做按键或开关信号接I/O口,程序不断扫描此I/O口,对高或低电平计数,计满6次令输出端口 ...
8 H$ x7 {: a( u# C0 j
谢谢你的建议,下面是我编的程序,编译后不出错,不过有警告,位置是主函数里,调用子函数后,对于flag的判断哪里,显示方向控制.C(29): warning C276: constant in condition expression,然后就无法生成hex文件,麻烦看一下,不好意思,谢谢了。8 f0 A1 O; {% G- o, h9 l) R! r* V" e
#include<reg52.h>0 h" n; N9 n- u, y
sbit IN3=P1^4;
; n2 i! U+ A3 x: ~( xsbit OUT2=P2^4;
. W; q$ i8 ?4 {5 M! e& e7 `bit old_bit;' v5 p% H' X, a$ R
unsigned char flag;* i8 ?. F! a0 u$ g2 H) ^& D2 g
void io_rest()
0 O! S. f6 p/ D1 e  }/ \{4 p! G7 u; t. v; I5 g( g* h& P9 P
  if(old_bit!=IN3)( b' @1 u+ X2 N5 ~
  {
% w$ U5 F1 J8 C) b3 }* p    old_bit=IN3;
& ^; W: D' P9 B/ [        if(IN3!=1)
7 F3 q3 i) k0 |3 P, o# Q        {2 f. y0 |3 j1 D3 T
          flag=1;
, }  K2 O- L& Q5 b9 K9 O. z        }
) G+ ?# D4 p6 g% I6 Z, o! @; E8 e        else4 i* o. E* K4 T: g0 E2 e5 |" x
        {
9 w: q- H$ J+ e3 B, E8 j( [% t# A           flag=2;
& Z5 J, a. S" ?: K0 |        }$ m( c- x! R4 d
  }
/ e$ j8 W0 C: j}
# S- t4 g1 R* \6 }7 [void main()
9 x) n9 f% E/ P! K% W  c8 T{5 C/ V) P! E, O& o7 R5 s$ i
  old_bit=IN3;
4 [+ g( R* U" K3 t1 F# `6 Q  while(1)
8 O* x: d- Q  g! t& d- ]" G  {
9 K8 C3 [' A  h  q) d% I% }) K: _' c7 D$ @    int num=0;. Y9 k1 K, S& _/ L' ?
         flag=0;0 {; X, Q, k0 q; r3 Z" W
        io_rest();  B+ B3 F- x/ X: Q
        if(flag=1)( {/ e$ f5 {. e/ b
        num++;! e9 z" u3 U# U. ^
        if(num==6)
# d, X' Z! Y  y' m' p1 [        num=0;
1 Y. u& g1 a# o5 l- ?! i$ a0 r        if(0<num<=3)6 d5 S. n' ^* |$ z% J
     OUT2=1;2 q( D( U& ?+ X; m! k  {7 Z
         else
0 J0 {' e2 y3 x4 m6 m1 D         OUT2=0;) Y8 I4 k  R. M
  }, B& ]" ?. @9 g' H2 P2 p
}" L( M. X' G" \8 b1 {

' F) g, o1 f9 ~7 \2 _: u) i% Z+ R$ i

9 ~5 u8 p( W5 ]6 D8 C* ?警告是由于少打了一个=,不过仿真并没有出现预期结果,输出端一直只会输出高电平,不知道程序哪里写错了?5 q7 M; a5 p! [0 m6 C9 N

该用户从未签到

6#
发表于 2019-3-25 13:22 | 只看该作者
/*已经实验验证通过*/
3 L. }$ m* d! }: t8 z# C7 h4 J#include<reg52.h>
; @9 {! v; p& ~5 e/ c* T8 hsbit IN3=P1^4;5 m' P* R" B( z; T- _! |2 K
sbit OUT2=P2^4;% G/ l$ _5 u" p# R% t5 m
bit flag=0;                                                //自锁标志
; T0 R: E& X- W/ N8 uunsigned char count=0,count1=0;//计数变量" Y1 A/ r  s1 C0 _) s" [
& k1 k' S/ }- p$ g$ \$ g
void io_rest()1 F) f2 W: ?0 Y% s8 C
{
9 i/ U- _* v9 }! T% f5 s9 \+ O+ T        if(IN3==0)                                        //IN3低电平有效) I' @- e0 K! X; b
        {        $ ~2 J* J$ j9 G8 z& i
                count++;                                        //消抖、消扰* b5 y5 H$ Q$ V8 u9 d7 y3 K
                if(count>=250)                        //根据环境干扰强度10到250: J3 X% [/ \5 W" F* F
                {
, m1 a0 T- s3 ^- \* t5 V; d- _                        count=250;                        //防止溢出
2 [0 T0 z! o$ @8 w, ]+ O                        if(flag==0)                        //如果自锁标志为0
0 Y/ q) [, N, e1 f& M( j; ~# {1 P                        {
. [2 t6 `9 X5 _) t) m9 N                                flag=1;                        //自锁标志置1、不会在持续低电平期间重复计数
" ~. e/ _0 I# X0 I. @' a3 D4 ?: Y                                count1++;                //脉冲计数变量
) D: W2 P5 h+ i; z. M, [                                if(count1>=3)        //脉冲计数变量>=3
- D: P" j4 U# ?; T- u+ I                                {8 K4 |. o9 j! S4 ?  z& N
                                        count1=0;        //脉冲计数变量清0  [. u% u/ P+ V% H; x9 u! c$ c/ d
                                        OUT2=~OUT2;        //输出电平取反; |% C" P+ r$ n. m
                                }% y* ?/ u6 Z5 r. v. T
                        }2 B+ w6 Q( j+ a0 o" b- q* n# H
                }1 Q& k: P( b1 m% m
        }' Q4 u' Q2 u5 P( ?* W- M: s" P( t
        else                                                        //IN3高电平
, @; R& j3 a" `" h' ^* N- w1 X& k        {
" \! i5 c" Z. `! L                flag=0;                                        //自锁标志清0$ Z4 x5 b; G' ~
                count=0;                                        //消抖、消扰计数变量清0
9 k  I, V: v5 b        }. O3 D% `7 l6 }# W+ j1 p
}
2 y7 y: g- g# M+ t( A8 v! Lvoid main()
3 q3 I" D& U$ ]+ V& K$ Y{+ x0 m0 U% j6 A! H
        while(1)
1 B9 ?% I. O: _: V) x: X8 ?- j. M8 `        {1 w0 \# M6 b9 T( \+ b2 n% V0 h
                io_rest();
6 k& T! I9 |) L. _        }) m& L5 {. \2 Z$ j7 o8 w. A
}

该用户从未签到

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:40- l% x, o: T: N0 M2 b, N
我刚刚试着操作并看了一下代码,那输入信号为时钟信号来说,250这个数字的选取确定了判断输入端口的最大频 ...

$ _/ ?+ m; p1 B$ {6 W  R这样理解是可以的,250这个数字是以主循环速度设定的,对于12T单片机也就是大约2ms,大于一般干扰持续时间,如果用1T单片机,这个数字还要扩大10倍,如果主循环任务多就要减小这个数字,如果输入是TTL信号,这一部分代码可以不要。总之由具体需求确定,不是一成不变的。
& q: r5 y* g( F' ^

点评

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

该用户从未签到

9#
 楼主| 发表于 2019-3-25 14:17 | 只看该作者
gaoxings 发表于 2019-3-25 14:07
- e9 U& x: T8 i) o1 A1 q( y这样理解是可以的,250这个数字是以主循环速度设定的,对于12T单片机也就是大约2ms,大于一般干扰持续时 ...
; ^0 l5 Z6 R+ S6 N+ a
刚刚调试发现一个问题就是如果一开始就输入的低电平的话,0,1,0,1输出信号就会变,这之后的会变为正常的6循环
. n7 ?" k* @6 ?% P0 [% ^8 p

点评

这样改一下就可以解决初始计数问题 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:177 ^+ H2 E& a2 r- t& T* Y, F& J
刚刚调试发现一个问题就是如果一开始就输入的低电平的话,0,1,0,1输出信号就会变,这之后的会变为正常 ...
: @: S+ n; s& T- s( Q. H6 |/ X
这样改一下就可以解决初始计数问题; p7 n, [) C. ^) Q( l4 e; m, q
void io_rest()
6 c/ h2 g& p- |. U9 A# ~{1 t2 g  w, h% l' X
        if(IN3==0)        
% h0 W/ j  H  _5 E. _        {        * c; L7 @; Z3 p
                count++;        
% d0 ]3 v5 S. S7 W9 T, G                if(count>=250)        
& d; }% I' y5 U, r% n                {
& q7 f7 Q$ u, q8 L2 b0 B7 A( A                        count=250;! t% e! N1 q5 D/ `& m4 H
                        if(flag==0)                + G9 ~2 U4 S( @* d8 @3 e
                        {
4 [' C; x2 h8 t3 y% l; G                                flag=1;        # d6 r7 L! n) Y! L4 X
                                count1++;                3 Y/ a( G- R( Q% _6 f
                                if(count1>=4)        
5 m" r7 ~- E" A1 D$ W7 e                                {$ ^- k/ R6 P) a2 h# S; t! Y
                                        count1=1;        
  k( |8 U. `: }& Q                                        OUT2=~OUT2;        " t$ H  a, g$ w1 Q
                                }& Z: }4 ?* X. w4 L1 h& v3 a1 Q' k
                        }
5 R( n9 i+ O: ?# F3 h/ W                }# C0 ]" U  Z5 ?+ K" M/ @; i+ I
        }
( M7 P5 |0 l& g) n' s" z( V+ s        else                                                + Q: @. u3 F& m- t3 e+ z8 F
        {) o" X5 ~* F4 l. ^! }& i1 j7 J
                flag=0;                                4 ^5 }# T" c" l1 `2 _
                count=0;                                1 X& q% ?2 q" @( Z7 f2 C* K; X8 `
        }
$ _/ J) s2 ^& d6 H0 U: G0 o' _}
5 z6 a& `  T* u$ u9 x- p- y  V

点评

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

该用户从未签到

11#
 楼主| 发表于 2019-3-25 14:40 | 只看该作者
gaoxings 发表于 2019-3-25 14:34
  H0 {+ z' m& M, T这样改一下就可以解决初始计数问题8 |+ S2 o, N  O8 ]
void io_rest()
+ W' f  [" ~* y  o{

  p9 {. G4 W3 P8 n4 m( q谢谢大神,太感谢了, N3 x2 P2 `- c1 @, [5 F

该用户从未签到

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

“来自电巢APP”

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-6-23 16:57 , Processed in 0.093750 second(s), 33 queries , Gzip On.

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

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

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