|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
单片机数字频率计仿真设计0~9000hz 数码管显示 带源码/ V+ N, t+ G- R& n. Y8 Y
& J4 c6 @4 X& f1 O5 U
: }# D' n) Z0 `7 y5 V/ U今天给论坛的朋友们分享一个51单片机做的数字频率计,用数码管显示,有详细的程序代码.4 u3 g2 C6 R) S3 a Y
仿真原理图如下:1 f% }0 n& ?# p
; D* t2 R% {8 e7 a/ c
?+ r( g. v; d" s7 k- ?+ N; o+ L5 i M3 q
部分单片机源码预览:2 G& ]; _# o% j( O/ E M+ r, n. G
freCountMain.c文件:
# t3 K$ t8 c' A# g2 r' B/*************************************************************************6 W( x9 J! y. p" g1 n4 O5 W; W7 V
*实例名称:频率计 s9 Q, \% \. a4 D2 j; R
*实例说明:实现0~9000hz频率计的统计. J- D8 ?3 X) C) {
*作者:yd# R8 a4 `7 v8 E' w8 a! F" H
*时间:09.06.200 \- @( G# @, I$ ^ G/ V$ \
*************************************************************************/* Z4 V/ u& s! L" L( |" w$ ?' F( l8 ]
#include "target.h"3 ^% W/ L- g' c) G, n0 Z
#include "led.h"
5 ?0 z; k6 @6 j! muchar displayBuff[4]={'0','0','0','0'}; //数码管显示缓冲区,千,百,十,个
& H' p+ I# L9 \5 [: g: b) H) e; X" uconst uchar displayMode=0x00; //后四位分别对应缓冲区中每位的数据类型,1为任意字符显示,0为数字显示
& q0 N7 `8 I% Svoid main(): B9 i6 ~7 y( W. U" o
{
6 e ?6 X+ o( X8 U uint get_fre;
) [6 V5 H' d$ w% V target_init();
/ s @0 P% X9 e5 v0 L init_led();
9 Q) Q+ f9 ~8 F, U- o2 z sei();5 t# b7 U( J) g4 F# x7 m
while(1)
2 ~; x; {! B1 @! ]& A. n5 N% P {
z, d2 K1 S* p$ U$ y) C' } get_fre=get_fre_number();1 [8 Q4 K, E6 U% A9 y( i f6 ]
if(get_fre/1000<0x0A)( N d# `' j5 K' C p: M+ c" @$ B
{
, `$ F+ @2 [; f% m& [3 d displayBuff[0]=get_fre/1000+'0'; //计算频率千位,放在缓冲区第0位
6 S% W( y/ `. v- d" T }
! U. D, n' n; F displayBuff[1]=(get_fre/100)%10+'0'; //计算频率百位,放在缓冲区第1位
8 J$ \5 p, M+ U- s9 c5 b displayBuff[2]=(get_fre%100)/10+'0'; //计算频率十位,放在缓冲区第2位- B/ Z% z7 w3 i7 u
displayBuff[3]=get_fre%10+'0'; //计算频率个位,放在缓冲区第3位1 L+ r; f5 }" w
ledSweepDisplay(displayBuff,displayMode,0x04);//循环显示数码管缓冲区中数据
$ K( s9 x" x' i. K2 w6 G$ {0 [ }
, t# }; H4 q, n5 y# y3 P: Q) s& ?, x& i$ E f: p
}7 H7 b* [& J' Q5 }9 Z: z
& w9 L( _3 n6 q, e2 `: @
led.c文件:& y) ?9 H% i7 V: g
#define LED_GLOBAL 1& J* q, I( x4 Y8 Q6 I$ R
#include "led.h"
/ u. G' w6 s2 b% n/*******************************************************************************************
: M/ } J) [1 E' H, L' u: ^*函数名称:delay_us(uint us)5 r3 a r/ j4 @# `; F( C* j
*函数功能:实现微秒级的延时
( `+ Q j! S5 F* T; y: G*函数入口:us,延时函数循环后期数8 p0 y9 ^4 _) ~
*函数出口:无
3 V; ^' h5 T! {- H5 \5 }2 v' H*******************************************************************************************/, G, ~0 R7 R( z9 T$ u2 P5 A& P
void delay_us(uint us); Q: t9 P5 |+ G, b3 ?& U' V
{; a+ \/ i" T' g! v+ F
uint i;! t* O2 w9 M W
while(us--) S; u% u" p+ ]! u8 W2 _' m( R
{$ J+ q' {7 `+ P$ y8 ?/ D$ Y
for(i=0;i<100;i++);
% p3 v0 P7 r5 V; }. H* S* D5 ~3 B }
- r. y2 J2 l9 O8 E5 d; W: Y}
0 m* J! h4 ^+ f1 B& k/ B" }/*******************************************************************************************, A0 i7 T1 j# c+ |% m
*函数名称:led_init(void) a& j7 Z4 S3 \+ {/ o# y
*函数功能:四位七段数码管显示初始化
- L5 V6 C# A3 e*函数入口:无+ L7 b; H t! {/ O
*函数出口:无
9 v6 Y! z8 Y: Q: c' o, ?% [*******************************************************************************************// }" b, [' r, c* @) b4 T- D/ u- A
void init_led(void)
* l; s- l; @ M! n6 r{+ z$ X, f! D0 d7 H9 [
LED=segLedCode[0];
" x) m! g Z1 J, I' j( _1 f9 F LED_CS1=0;
: h$ R% C( b2 j; ^6 K/ m4 C LED_CS2=0;
" V7 g& ~3 M; c5 u$ M LED_CS3=0;
7 }. L$ Q1 f# D& @# j LED_CS4=0;
l, O1 k) {- T* r+ f}' J& [9 M. c6 C2 H3 ~2 L
/*******************************************************************************************
3 ]$ O" G- z' k* n5 h! e*函数名称:ledWrite(uchar c,uchar n,uchar mod)
t- i9 {/ a4 }6 B, u2 g6 D*函数功能:对一组数码管的某一位进行短暂显示
) w* m' M& a6 F( J9 D8 S*函数入口:c,要显示的数据;n,显示一组数码管中的第n位;mod,c的数据形式
, G8 Z* z* p1 b% i w$ \/ Q- J*函数出口:无
) c [" B8 U0 B. }: S3 ]; ~*说明:当mod==DIGITAL时,c为数字0~9的ANCII码形式,此时在n位数码管上显示想用数字
- {; T4 ?9 i0 w0 R5 V5 L2 ~3 | 当mod==CHARACTER,直接将c输出数据口5 P! m+ @) Z- U
*******************************************************************************************/
8 t0 J- c. {" o% ^! y5 Rvoid ledWrite(uchar c,uchar n,uchar mod)# j y9 p4 q* y8 n
{
' n9 d- N( E6 s- \ if(CHARACTER==mod)
; d+ x- L' t: E/ ], c( e9 p {. k2 ^/ ~1 n, Z. }- t- o. R- n7 M& x
LED=c; " F8 s% r1 m( x
}
* x" m/ C, ]' o: F' V, _ else if(DIGITAL==mod)
! B P! G, g1 Z7 o( Z {4 @+ |0 r8 B5 J5 B
if((c-'0')<0x0a)# h2 o) W$ y4 Z \( {) o+ T3 T- Q
{
4 ?- m% G( p1 d6 p6 Q LED=segLedCode[c-'0'];
4 f+ \* v2 o. [7 p } & T: n8 z* Q4 ?. Z% T( v
else
; n+ b( D* n* G* G+ h$ X2 l' y { 4 v% S2 f5 s: v4 p& q
LED=segLedCode[0];
2 y4 A1 e5 S+ C. a }" ~# m, a! k( |8 V
}
8 X8 e6 R, T: t switch(n)" M) ^, D" H9 {( I
{" M B& d Y$ \' e& A$ L. [/ e
case 0x01:9 u' w/ j0 V0 _' x- Z
{
1 {$ T: G6 V9 c8 S# D LED_CS1=0;
5 N% p/ B& B5 A$ y$ k' y" F delay_us(10);' x h: W8 D1 f+ c) }! {. n3 v
LED_CS1=1;; @: h* z$ f; \4 t
break;& }2 l. c) ~: D
}
0 f4 ?! n; R$ h) l5 X case 0x02:% V. ] m" K6 a D7 C0 b
{+ Q. e. |0 ]+ x+ d( L
LED_CS2=0;5 Q; h! s1 q. P+ D; Y
delay_us(10);; b' M; V* a0 @+ F( z+ \
LED_CS2=1;
7 f' p& [5 L% g9 Y- u3 x break;7 |4 ~* W. y. g, X0 m' D- w* N
}+ L- s& G, c f$ @. w9 ^+ E4 V% _8 U
case 0x03:
7 p* H( T* a0 ? {
4 `) _) k. k P# w; ` LED_CS3=0;
Z$ N- l% a( o! c5 N3 E delay_us(10);
/ x& k2 @" U5 z/ N [ LED_CS3=1;3 m4 }& T0 @8 m+ W' `
break;3 J" N+ v8 N5 R5 l p3 s
}
1 Q p/ L! x* E) l2 L; [& X7 S+ d case 0x04:, W+ J/ F. L5 b9 \% }, k
{
, V9 U+ D0 n& Q: w- ^% @4 f LED_CS4=0;
' T7 R# t% u" W g; ]' i delay_us(10);
1 W6 y3 O8 W; @: y8 r LED_CS4=1;
2 N4 K! ~0 D0 Q/ n1 N/ s% [- v1 A* F break;
! v) l% t. [% ] }$ `: \. w' o: z6 b1 Z
default:
) J5 |. I, I/ k- e) {2 ? break;
; w! ]& E, ^3 B f' q) _% f/ x
T _5 t7 n6 f. A; { }
0 b% i4 p, s8 l; B+ H0 f- m7 @
}
" z/ ]4 ]0 A& M# N8 b/*******************************************************************************************' J& W* c- m) g" x; | { T. E
*函数名称:ledSweepDisplay(uchar *segCode,uchar segCodeMod,uchar segNumber)' G9 d$ m% y* |# f2 ~9 z( z
*函数功能:循环在数码管上显示缓冲区中的数据: L# h# J5 l! } Q
*函数入口:segCode,指向显示缓冲区中的指针;segCodeMod,0~7位为1或0标示1~8位数码管显示的数据的类型(DIGITAL或者CHARACTER);segNumber,代表要显示数码管的位数
8 M, G) ?# `( A' U*函数出口:无5 r, A. M, X5 C, M* |# z
*说明:本函数主要实现将显示缓冲区中的数据在数码管上显示出来; `! g3 F! ~ J) X9 }; `
*******************************************************************************************/ + m1 o, ]0 b/ m' D6 F
void ledSweepDisplay(uchar *segCode,uchar segCodeMod,uchar segNumber)/ Y) q4 O' j) S+ i5 [
{4 E5 k, T$ g l2 u, a* Y1 x
uchar segCount;# b' x9 ^7 g, ^. q
for(segCount=0;segCount<segNumber;segCount++)
s+ i. E! ^" B3 \ {2 F" V8 F: S0 h4 L- O8 p4 B
if(segCodeMod&0x01) /*1代表此处显示任意字符 */
! M5 a6 x* J3 |: Q% {- a {, p H/ ]9 w% B N3 E E
ledWrite(segCode[segCount],segCount+1,CHARACTER);
) Z4 t/ d" b' W4 j0 t* j7 ] }
7 d2 K- u# F: t3 t" g else
# S- O4 A% J1 F" E! D8 ]' G {' A$ ^( |! S7 ]/ F: {& d M. x
ledWrite(segCode[segCount],segCount+1,DIGITAL);
+ K' w% R: z7 ?- F( K. n. G }
$ A( B$ L+ O- O& U( g* E# j4 B0 P segCodeMod=segCodeMod>>1;
- F$ V6 w% s+ n }
9 b( ]# p4 H G}+ F2 v6 j3 C/ l" _. o ]% z
$ Y3 e M4 E8 s$ e- {
3 X+ T9 {$ `8 f8 I全部资料下载(含仿真工程文件和完整代码):5 S3 Q9 P$ x7 {3 C, f V
1 M7 Z4 ~9 `' ]' b4 Y* z$ J$ `
( Q* F( o' ` C
0 r- v7 g, [: | |
|