|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
完整的单片机霍尔测速程序2 K1 C! {- B0 f' H
& n* ?, j, [8 v$ v) r9 d3 M# { D
: {( N, |* a# T7 O L) j/************霍尔测速仪******************/ r$ O7 R, {* ?6 c
/****************************************/9 }% Z2 H) E A
/****************************************/0 A) }; [4 j9 T/ ~: A
/**编写人:刘梦宇**/
( E& G0 b; U$ m$ e) C/**主控芯片:STC89C52RC**/
: D3 e; C D; Q/**晶振12MHZ**/- a5 V, d) ^1 c4 A! b
#include<reg52.h>
! `& \+ y4 g. H3 P1 c#include<intrins.h>4 W2 U( ?1 G2 Y; C; w
#define uint8 unsigned char6 t, X( ^+ ?) D- z" T: U: h/ V' L
#define uint16 unsigned int* Z# x! z; R; K4 z: }3 l
#define CMD 0x00' e- S" X) j7 b9 E6 i. f
#define DAT 0x01) `# c$ j! f8 w: j$ p" l. K$ @
#define DataPort P0//LCD数据口
0 f& L2 _2 j8 i/ Q/ q: s) z; `sbit RW=P2^6;; Q$ T) a P; N& [0 h
sbit RS=P2^5;& s" V8 C8 N1 E0 ^9 s
sbit E=P2^7;
1 G6 l" ^' b1 ouint16 N=0;
0 q5 I }* w* C! w% W' [+ a Nuint8 C_50ms;" i5 F) |1 m9 r0 O2 Q2 H3 H
uint8 Z=0;1 C) U! X. r* T$ g1 S7 G
uint8 count=0;
. e) \; M2 v+ a5 Xbit flag_1s=0;9 R- H5 [: ?5 a x' a9 H
/**ms级延时子程序**/+ ~* k3 Z7 H1 S5 C" l. [0 ?8 ]
void delay(uint16 t)0 H* c, u. P1 j$ ]4 `1 K+ `
{
* M, y1 y/ F& j2 K* I uint16 a;
3 h8 p; W+ U f! C8 e) b1 H( y for(;t>0;t--)
$ N2 ?2 u8 |& F0 O& } for(a=123;a>0;a--);0 @. `+ A. o: g
}% w1 ]" c) | z2 \0 a4 Q i' J0 Y
/**LCD时序**/
' t* F+ U" Q$ ~0 n/ f8 u: A9 Z v( ]void write_LCD(uint8 dat,bit rs)
1 }9 z% J6 F5 Q! s: b$ y. l o{# G4 H( |2 |/ c
E=0;8 M4 }1 r9 V9 D4 c( n- q% m
RW=0;
9 v( d4 V v8 r+ f1 t RS=rs;//选择指令or数据 g" n/ Z) U& ]2 H1 v( O
_nop_();. M, T" r s; S7 b
_nop_();3 s K3 W- O0 O
_nop_();$ ~& s: F, T5 i. F) |, D% e
E=1;
6 w, I1 B* ~$ p8 H! A0 ]1 B3 ?9 A _nop_();//delay(1);
# Q0 @6 A1 b6 e4 b _nop_();9 ~6 g# I+ r% T* Y
_nop_();, M- {: A% p9 N# S
DataPort=dat;//将数据送到LCD数据口+ X! p1 A! {6 j& Z: N* C
_nop_();3 I u- s* s0 f2 r" O$ T& Q% B" F( c8 D
_nop_();
7 L% D- Q. j1 A- Y _nop_();# _3 E/ W- @ d9 L# ?$ V, \9 M; X0 K% ]
E=0;
N, Z$ b) _& X! A- G delay(1);% K$ P- [ d! ~6 C
}
, W& R8 H/ H4 u6 J& S& q/**LCD选择显示位置子函数**/
6 b6 z' e) g5 L/ P! E l* n: Hvoid SetXY(uint8 x,uint8 y)
" O8 \" b2 b* R0 {2 b{
& n6 W8 y. b7 ]+ m @% J& x x=x&0x0f;//防止X、Y 超过量程
& D2 ?- ^9 ]/ Z! C9 w y=y&0x01;" D$ [2 _3 H6 s# a! [8 f
if(y)
" |3 Y6 g2 |1 b1 c {
* V& A. T3 S! b6 {7 ^: G8 m write_LCD(0x80+x,CMD);
& T; P! e- ]7 B: |+ `+ R& \0 a8 W } C- e$ A, h; V/ t( G
else
9 d1 f( {& C" d: I2 H+ X {
; h* o/ j6 l7 o5 w8 Z; c% N% J write_LCD(0xc0+x,CMD);, l. a7 n; b; [- R' L
}" h: c7 ^3 }3 i, ]6 k
} A: M @. }0 s0 k9 A4 {8 j
/**转速数值转换子函数**/3 p8 I: e% A2 \: F0 C
void disload(uint16 a)
6 \& o7 ]8 _) D. b. D( g" x{$ D! W: X& ~3 X, M0 M \
SetXY(4,0);
5 Z0 o- f- i7 T+ p c write_LCD(a/1000+'0',DAT);9 S: q: L) K1 p& f* O h8 l. I0 d
write_LCD(a%1000/100+'0',DAT);
4 o! g3 b8 s1 q1 e8 N8 U; I* { write_LCD(a%100/10+'0',DAT);
! f/ _1 I3 B1 U$ q F1 H! c write_LCD(a%10+'0',DAT);
# ]/ q) U- K, K, |' K- W( u write_LCD('r',DAT);6 A1 h$ ~+ R: m; U
write_LCD('/',DAT);
5 S; ~1 l% B9 u x) T; w, c0 [- ]2 { write_LCD('m',DAT);/ U* J. b( @+ k0 G, _" v
write_LCD('i',DAT);. b0 B3 U+ n" a" M
write_LCD('n',DAT);
$ U, X, O9 J5 g* I3 J- d3 a}
; e$ h2 q$ A, i+ R! w) g0 H( Q" Y/**LCD字符指针函数**/9 \/ ]/ K, _3 o+ i
void LCD_wrstr(uint8*str)
^! N" x( m* p) L. V5 R. V{
9 o% ~' F2 E4 b0 x, I while(*str!='\0')
2 H/ t. I5 ?- Y( D {) q% u6 n) H: e& _7 ^* x5 D& s% Z+ b
write_LCD(*str,DAT);
1 ~" o. P" l' W# b, X5 O str++;0 L3 Y$ ?" T7 |7 ]2 m
}
, t8 T) @3 n, Q# k: j}6 X: B5 o2 a$ Q1 k. F Q u1 I
/**初始化子程序**/- G# O. S2 `' y8 Z& q
void All_init()2 w% w! z7 P1 z( C# v5 A% |2 C
{
- v/ y; [1 S# x' ?! o/ j delay(500);
5 t& i2 Y+ {% L# a3 I4 S4 }( L/ V write_LCD(0x38,CMD);2 E. g' r* j/ k* l- Z' e. s" u" P
write_LCD(0x38,CMD);1 Y1 a2 c5 L8 X) r7 {1 A
write_LCD(0x0c,CMD);* X8 i* X. j( L0 d' R
write_LCD(0x01,CMD);& X" u$ j+ O, V2 z3 h# m
delay(10);+ w0 I4 g1 ^! V, t5 ?
0 s! Y( Q7 W: n# N* s7 E5 r SetXY(0,1);//设置标题显示位置4 T3 }5 g. a6 G0 a9 y* \' c$ }
LCD_wrstr("Tachometer:");, N' j' M- [& l) t
" A# D8 j9 C6 v. ^- C* u
TMOD=0x01;//设置T0位工作方式1——作为16位定时器
! d) g1 k. A7 Y/ x* G, J+ d6 _ ET0=1;//打开定时器0的中断8 u4 i2 R' G% L
TR0=1;//打开定时器0
2 u8 s1 x% w8 a5 y8 a: Q* C TH0=(65536-50000)/256;//装入初值
: q: ^$ s; D% x" m- r TL0=(65536-50000)%256; a' G, ?+ \) I1 N I3 l
IT0=1;//外部中断0为下降沿中断3 N* S- a N" R1 s3 }9 b! |
EX0=1;//打开外部中断
" }8 Y9 m* [7 _4 j* o- } EA=1;//打开总中断
; p; H3 T& c3 X4 D+ c* e. r" Q% L}
/ L7 Z+ U! ~1 S: w8 v9 E- R" Cvoid main()
+ D2 G% R; N$ q0 R' c{/ E" `. }1 m$ t6 G* d& M: ~
All_init();//先进行初始化3 ]' |9 ]- ]3 v* F" P; K5 n. o$ h
while(1)
( g& ?+ b( [* d3 f/ t7 Z, H1 s {
* X: e# F$ b0 b$ c- p1 L( { if(flag_1s==1)
( S: e+ g7 b: p {
! u8 ~- H2 A) a1 K$ } flag_1s=0;//1s标志位清零$ w' p) B9 ], v" L9 _5 ~
disload(N);
9 C. _& R" P# N" z+ t# e9 U. T }
& j9 p& O7 r$ _. h* Y, q }
5 }! h Q* @4 u5 e# j$ l. o+ ~4 T3 X6 x% g, O* l6 n8 u
}8 } k) z0 H9 c
/**定时器0中断服务子程序**/
! i0 h/ \: G3 n4 ?void timer0() interrupt 1
6 Z8 t4 E1 X- }% N1 i{
5 b! e$ R) m$ E6 |: e6 j+ L TH0=(65536-50000)/256;' o# r; ?) R/ @$ F$ C6 w
TL0=(65536-50000)%256;
$ t! }9 Y3 I. w1 h- `* D( ?: L5 r if(++C_50ms>19)4 C: z4 U- y" `4 _5 L/ ~- D
{- q6 f- ]' J4 [/ V1 L# T3 P/ d T4 Q
EX0=0;//关闭外部中断0$ p% i& \# w: {# f, }
C_50ms=0;//定时1s之后C_50ms清零4 y2 A0 q [7 s8 @
N=60*Z;//计算转速
. H. R+ I- a" W3 K* @7 C Z=0;//初始化圈数% x( r& Q7 p8 h* A
flag_1s=1;//1s标志位置1
4 V, O# M2 N O3 V3 h TH0=0x3c;//重新赋值
# W' V# t( S6 J/ t9 `! C9 M" v7 H TL0=0xb0;; M6 q) ~( d' Y
EX0=1;//打开外部中断0,开始计数。8 k/ T7 Z: _6 e
}5 r+ O3 k, y) P! F+ x
}
) R' E; k8 o" C) }. v& Uvoid wai0() interrupt 0
2 \8 k/ U b* a5 S* s{
4 W0 a5 Q% D+ x" \ M& n count++;6 m" H, q( s: G4 D7 k
if(count==2) //两次外部脉冲,电机转一圈。
$ C+ A' F' ?' Q- e& D {3 y" |: I; F& H
Z++;//转圈+1
* y; q. r# N" Z* l* @ count=0;//初始计数值
) `! [. q* B' } Y+ M) z! |* } }
' c) l8 d7 g% H4 S' \5 c( W% e3 l* M* j3 Q( }$ z/ |0 g1 w
}' c9 Z+ s! g- n+ l Y+ C( r8 _/ C4 _6 a
2 ^3 z# K: N3 z8 i7 k
|
|